Skip to main content

Items and Attributes

Items in Mod-Engine are objects with named attributes that describe their properties. These attributes are used by modifiers to determine when and how to apply changes.

Attribute Types

Enum Attributes

Fixed sets of possible values, perfect for categories like rarity or type:

{
key: "Rarity",
kind: "enum",
values: ["Common", "Rare", "Epic", "Legendary"] as const,
}

Usage in conditions:

// Exact match
.when({ op: "eq", attr: "Rarity", value: "Epic" })

// Multiple values
.when({ op: "includes", attr: "Rarity", value: ["Epic", "Legendary"] })

Boolean Attributes

Simple true/false values:

{
key: "Enchanted",
kind: "boolean",
}

Usage:

.when({ op: "eq", attr: "Enchanted", value: true })

Number Attributes

Numeric values with optional constraints:

{
key: "Level",
kind: "number",
min: 1,
max: 100,
}

Usage with comparisons:

// Greater than or equal
.when({ op: "gte", attr: "Level", value: 50 })

// Range checks
.when({ op: "gt", attr: "Level", value: 10 })
.when({ op: "lt", attr: "Level", value: 90 })

String Attributes

Text values with optional validation:

{
key: "Name",
kind: "string",
pattern: "^[A-Za-z ]+$", // Letters and spaces only
}

Setting Attributes

Use the builder to set item attributes:

const item = engine
.builder("Magic Sword")
.set("Rarity", "Epic")
.set("Level", 50)
.set("Enchanted", true)
.set("Name", "Excalibur")
.build();

Attribute Validation

Mod-Engine validates attributes at build time:

// ❌ This will throw an error
.set("Rarity", "Invalid") // Not in enum values

// ❌ This will throw an error
.set("Level", 150) // Exceeds max value

// ✅ This is valid
.set("Rarity", "Legendary")
.set("Level", 75)

Dynamic Attributes

Attributes can be calculated based on other attributes:

// Set base level
.set("Level", 50)
// Enchanted items get +10 levels
.when({ op: "eq", attr: "Enchanted", value: true })
.set("EffectiveLevel", (ctx) => ctx.attributes.Level + 10)

Multi-Value Attributes

Some attributes can hold multiple values:

{
key: "Tags",
kind: "enum",
values: ["Weapon", "Armor", "Accessory", "Consumable"] as const,
cardinality: { min: 1, max: 3 }, // 1-3 tags allowed
}

Usage:

.set("Tags", ["Weapon", "Accessory"])
.when({ op: "includes", attr: "Tags", value: "Weapon" })
.increase("Damage").by(10)

Conditional Attribute Setting

Set attributes conditionally:

const item = engine
.builder("Conditional Item")
.set("BaseRarity", "Common")
// Upgrade rarity if certain conditions are met
.when({ op: "gte", attr: "Level", value: 50 })
.set("Rarity", "Epic")
.otherwise()
.set("Rarity", (ctx) => ctx.attributes.BaseRarity)
.build();

Best Practices

1. Use Descriptive Names

// ❌ Unclear
{ key: "T", kind: "enum", values: ["A", "B"] }

// ✅ Clear
{ key: "ItemType", kind: "enum", values: ["Weapon", "Armor"] }

2. Set Reasonable Constraints

// Level bounds
{ key: "Level", kind: "number", min: 1, max: 100 }

// Quality percentage
{ key: "Quality", kind: "number", min: 0, max: 100 }
// Combat-related
{ key: "AttackSpeed", kind: "number", min: 0.1, max: 5.0 }
{ key: "CriticalChance", kind: "number", min: 0, max: 100 }

// Durability-related
{ key: "MaxDurability", kind: "number", min: 1, max: 1000 }
{ key: "CurrentDurability", kind: "number", min: 0, max: 1000 }

Common Patterns

Rarity System

{
key: "Rarity",
kind: "enum",
values: ["Common", "Uncommon", "Rare", "Epic", "Legendary"] as const
}

Quality System

{
key: "Quality",
kind: "number",
min: 1,
max: 100,
default: 50
}

Equipment Slots

{
key: "Slot",
kind: "enum",
values: ["Head", "Chest", "Legs", "Feet", "Hands", "Ring", "Necklace"] as const
}