properties.txt is the composition layer between item-mod codes (the prop1, mod1code, Code, mod 1 columns scattered across the other item tables) and the engine's stat dictionary in itemstatcost. When a unique item ships prop1 = "ac", the engine looks up ac here, sees it composes the armorclass stat via function 1 (random between min and max), and applies the resulting value to the item. Every modifier on every spawned item — every +1 to Skills, every Faster Cast Rate, every Adds 5–10 Fire Damage — passes through one row in this file.
285 rows × 38 columns. Each row is one property code, and codes are unique (no duplicates). A property can compose up to 7 stats through its func1/stat1/set1/val1 … func7/stat7/set7/val7 slot blocks, though in practice the deeper slots are rarely used: 285 rows fill slot 1, 15 fill slot 2, 10 slot 3, 6 slot 4, 2 each in slots 5–6, and 1 in slot 7.
How a property resolves
When an item-generation routine looks up a property code, it iterates the row's slot blocks 1 through 7 in order. For each filled slot:
- Read
funcN— the function ID, a small integer enum (0–25 in shipped data, plus 36) that selects how the slot's values are interpreted. - Read
statN— the stat key fromitemstatcostthat this slot writes to (some functions don't need a stat; locbones marks those slots blank). - Read
setN— a boolean controlling whether the slot sets the stat value (replacing any current value) or adds to it.1= set,0/blank = add. - Read
valN— an integer parameter consumed by certain functions (most commonly for stat-ID offset arithmetic).
The function ID is the load-bearing piece. Function 1 (the default for "random value between min and max") covers 123 of the 285 properties; everything else uses a more specialized function — chance-to-cast skill encoding, day-night time scaling, per-character-level scaling, charged skills, etc. The full function reference is below.
When a property uses multiple slots, the slots compose: res-all writes to all four resistance stats by chaining four slots (the second–fourth reusing the first's rolled value via function 3). dmg-elem writes seven stats (fire min/max, lightning min/max, cold min/max/duration) by chaining all seven slots. Multi-slot properties are how the engine bundles "one displayed line" into multiple underlying stats.
Columns
Identity
| Column | Meaning |
|---|---|
code | Unique property identifier. Referenced by prop1–prop12 in uniqueitems and setitems, PCode2a/FCode1 etc. in sets, T1Code1–T1Code7 in runes (runeword stats), mod1code–mod3code in magicprefix and magicsuffix, mod 1–mod 5 in cubemain recipe outputs, and modcode slots in automagic. |
Stat-composition slots (slot blocks 1 through 7)
Each slot block is four columns. Slot 1 is required (every property fills it); slots 2–7 are optional and used only when the property needs to write to multiple stats.
| Column pattern | Meaning |
|---|---|
funcN | Function ID from the table below. Controls how min/max/param/val are read and what the slot does. |
statN | Stat key from itemstatcost. The slot writes its computed value to this stat. Some functions (5/6/7 for damage, 14 for sockets, 20 for indestructible, 23 for ethereal) don't take a stat and leave this blank. |
setN | 1 = set the stat to the computed value (replacing); 0 or blank = add to the stat's current value. |
valN | Integer parameter consumed by functions that need it (most commonly function 21 / 22 / 36, where val acts as a stat-ID offset). |
UI
| Column | Meaning |
|---|---|
uiRangeType | Controls how the property's range is displayed in tooltips. Used by 46 of 285 rows (37 with value 1, others scattered). All 37 uiRangeType = 1 rows are character-level-scaling mods (/lvl suffix in their code) — Defense Per Character Level, Life Per Character Level, etc. |
Annotation (asterisk-prefixed — reference only)
| Column | Meaning |
|---|---|
*Id | Numeric row index. Stable across patches if the row order doesn't change. |
*Enabled | 1 if the property is live; 0 if disabled. (All 285 rows are enabled in the shipped data.) |
*Tooltip | The localized display string template for the property's mod line (e.g. +# Defense, Adds #-# Fire Damage, +# to [Skill] ([Class] only)). The # and […] placeholders are filled by the engine at display time using the stat values and the statN keys. |
*Parameter | Author note describing what the valN or stat parameter columns mean for this property (e.g. for randclassskill, *Notes reads val1 = # of Skill levels). |
*Min, *Max | Author notes describing how the stat-block's min / max values are interpreted for this property. Often literally Min # / Max #. |
*Notes | Free-form author commentary. |
*eol | End-of-row marker, always 0. Common to most .txt tables. |
Function ID reference
Every property's slot specifies a function ID. The function controls how the slot's min, max, param, val values are interpreted and written into the stat.
| ID | Name | Reads | Behavior |
|---|---|---|---|
| 0 | (null) | — | Unused. |
| 1 | ItemModsSetValueRegular | stat, set | The default. Roll a random value between the stat's min and max. On High Quality (Superior) items, use the stat's max. Used by 123 of 285 properties — every standard "+X to stat" mod. |
| 2 | ItemModsSetValueBaseToMax | stat, set | Always set the stat to its max value (no roll). |
| 3 | ItemModsSetValueRegular2 | stat, set | Same as function 1, but consecutive calls reuse the previous slot's rolled value. This is how res-all keeps all four resistances at the same value. |
| 4 | ItemModsSetValueBaseToMax2 | stat, set | Same as function 2, with the consecutive-reuse behavior. |
| 5 | ItemModsSetMinDamage | set | Set the item's minimum damage value. |
| 6 | ItemModsSetMaxDamage | set | Set the item's maximum damage value (dependent on its minimum). |
| 7 | ItemModsSetDamagePct | set | Set the damage percent (%ED) based on the stat's min/max range. |
| 8 | ItemModsSetSpeed | stat, set | Roll a random value between min and max for a speed mod (FCR, FHR, FRW, IAS). Used by 15 properties — all the +X% Faster … lines. |
| 9 | ItemModsSetSingleSkill | stat, set | Used for single-skill +N mods. Stat's parameter carries the skill ID; min/max are the skill-level range. |
| 10 | ItemModsSetTabSkills | stat, set | Skill-tab +N mods (e.g. +1 to Fire Spells). Stat's parameter is the tab ID: 0–2 Amazon, 3–5 Sorceress, 6–8 Necromancer, 9–11 Paladin, 12–14 Barbarian, 15–17 Druid, 18–20 Assassin. |
| 11 | ItemModsSetSkillOnAttack | stat, set | Chance-to-cast skill on an event (hit-skill, gethit-skill, death-skill). Stat's parameter is the skill ID; min is the percent chance (default 5 if 0); max is the skill level. |
| 12 | ItemModsSetRandomParam | stat, set | Random selection of the stat's parameter value using min/max as a range. |
| 13 | ItemModsSetMaxDurability | stat, set | Roll min/max for a durability mod; on Superior items set to max; current durability snaps to maximum after calculation. |
| 14 | ItemModsSetSockets | — | Roll the number of sockets on an item. min/max define the random socket count; capped by item's grid size and the hard cap of 6. |
| 15 | ItemModsSetMin | stat, set | Always use the stat's min value (no roll). For physical-minimum-damage stats, this becomes the item's min damage. |
| 16 | ItemModsSetMax | stat, set | Always use the stat's max value (no roll). Symmetric counterpart to function 15 for max damage. |
| 17 | ItemModsSetParam | stat, set | Read the stat's parameter value, falling back to a random min/max value, then 0. The standard pattern for per-character-level scaling mods (all 37 /lvl properties use this). |
| 18 | ItemModsSetByTime | stat | Day/night-cycle-scaled stat. The stat's parameter value names a time period (0 = Day, 1 = Dusk, 2 = Night, 3 = Dawn). The stat's effective value depends on how close the in-game time is to the named period, scaled between min and max. Used by 36 properties — the entire day-night cycle mod family. |
| 19 | ItemModsSetChargedSkill | stat | Skill-charge mods (the +N charges of Skill X family). Stat's parameter is the skill ID; stat's min calculates MaxCharges (using ilvl-scaled arithmetic when negative); max is skill level; spawned charges are randomized within a bounded range. Capped at 255 charges total. |
| 20 | ItemModsSetIndestructible | — | Add the Indestructible stat to the item. |
| 21 | ItemModsSetValueRegPropValParam | stat, set, val | Like function 1, but the property's val value offsets the stat ID. Used to write to one of a family of similarly-structured stats based on val. |
| 22 | ItemModsSetValueRegParam | stat, set | Like function 1, but the stat's parameter value offsets the stat ID. The aura, skill, oskill properties use this pattern — the skill ID lives in the stat's parameter, the level in min/max. |
| 23 | ItemModsSetEthereal | — | Add the Ethereal stat. Only applies to items that have Durability. |
| 24 | ItemModsSetParamAndValue | stat, set | Roll the value (min/max) and offset the stat ID by the stat's parameter. Consecutive calls reuse the rolled value. |
| 25 | (engine-extended) | — | Used by one shipped property (affix-rand, tooltip Add random affix from property). The slot has no stat set; the engine interprets this code as a directive to overlay a random named affix from the property's referenced pool. |
| 26–35 | (null) | — | Unused. |
| 36 | ItemModsSetValueRegPropValParamSwapped | stat, set, val | Variant of function 21 where the roles of the stat's value and the property's val are switched. Used by randclassskill (Hellfire Torch's +1–3 random class skills mod). |
Worked example: dmg-elem chains all 7 slots to write 7 stats
The mixed-element damage mod (Adds #-# Fire/Lightning/Cold Damage) is the only shipped property that fills every slot. Reading its row left to right:
| Slot | funcN | statN | Behavior |
|---|---|---|---|
| 1 | 15 (SetMin) | firemindam | Use the property's min as the item's fire min damage. |
| 2 | 16 (SetMax) | firemaxdam | Use the property's max as the item's fire max damage. |
| 3 | 15 (SetMin) | lightmindam | Use min again, this time for lightning min damage. |
| 4 | 16 (SetMax) | lightmaxdam | Use max again for lightning max. |
| 5 | 15 (SetMin) | coldmindam | Min → cold min damage. |
| 6 | 16 (SetMax) | coldmaxdam | Max → cold max damage. |
| 7 | 17 (SetParam) | coldlength | Use the property's parameter value as the cold-damage duration in frames. |
One property roll with one min/max pair writes to seven stats, and the seventh stat reads the parameter value instead of the rolled min/max. That's why dmg-elem items show three element damage ranges that are identical (same min, same max) with a cold-damage duration on top — the underlying mechanic is one rolled pair fanned out.
For a simpler chain pattern, res-all does the same thing for resistances using function 3 (consecutive-reuse) instead of repeated min/max reads:
| Slot | funcN | statN | Behavior |
|---|---|---|---|
| 1 | 1 (regular) | fireresist | Roll between min and max. |
| 2 | 3 (regular-reuse) | lightresist | Reuse the slot-1 rolled value. |
| 3 | 3 (regular-reuse) | coldresist | Same. |
| 4 | 3 (regular-reuse) | poisonresist | Same. |
One rolled value, applied identically to all four resistance stats — that's why +25 All Resistances literally means +25 Fire / +25 Lightning / +25 Cold / +25 Poison rather than four independent rolls.
Cross-references
uniqueitems,setitems—prop1–prop12columns name property codes from this file.sets—PCode2a–PCode5aandFCode1–FCode8columns name property codes (partial-set and full-set bonuses).runes— runeword stat columns (T1Code1–T1Code7) name property codes.magicprefix,magicsuffix—mod1code/mod2code/mod3codecolumns name property codes.cubemain—mod 1–mod 5columns on recipe outputs name property codes.automagic— auto-mod codes for class-restricted base items name property codes.itemstatcost— everystatNslot in this file resolves to a stat row here.skills— referenced indirectly through statparametervalues that carry skill IDs for the skill-mod functions (9, 11, 19, 22).