Skip to content

Item Power

Kit Oliynyk edited this page Nov 2, 2026 · 2 revisions

TL;DR: Every source of item stats prices them on one scale called M (one measure). A roll is +1 damroll, +1 hitroll, +10 hp and +10 mana, and a tier decides how many M an item may carry. The numbers live in JSON files in dreamland_world/fight. A new source of gear picks a tier and reuses a generator. It never adds a flat bonus. Use when: you add loot, a craft, a quest reward, an enchant or a spell-made item, price a spell on an item, or retune item power. Source of truth: dreamland_world/fight/item_value.json, item_affixes.json, weapon_tiers.json, weapon_damroll_tiers.json, spell_value.json, plug-ins/fight_core/itemmodel.cpp, itemvalue.cpp, armorgenerator.cpp, weapongenerator.cpp, magicitemgenerator.cpp, weapontier.cpp. Verified: 2026-11-02 against dreamland_code 88da8302, dreamland_world 43880467, dreamland_fenia_public c28874b

The ruler

  • One roll is +1 damroll, +1 hitroll, +10 hp and +10 mana (measure.roll).
  • Rolls of an item = item level / slot factor, at least 1 (item_rolls). The factor is 14 by default, 11 for body and shield, 13 for head, and 13 for jeweler-made finger, ears, neck, wrist and face pieces (measure.slot_factor, measure.jeweler_factor).
  • One M is the value of one roll set times the rolls, in gear-score points (item_one_m): rolls * (damroll weight + hitroll weight + 10 * hp weight + 10 * mana weight). The weights come from the profile columns of item_value.json.
  • Profile (archetype). Professions with the caster flag use the caster column. Everything else, including melee, agile, hybrid and NPCs, uses the melee column.
  • Points are the unit of the gear score. The generators buy affixes at points / one M, and the gear advisor scores the same points. A generated item stores its budget in the measure_m property, in centi-M (100 = one M), so the advisor's base score of a generated item equals that number.

Fenia has no floats, so budgets inside scripts are centi-M integers.

Files and who reads them

File Holds Read by
fight/item_value.json point weights per stat for melee and caster, flag values, resist values, detects, extras, materials, measure (roll, slot factors, tier budgets, craft budgets, level curve, cost) C++ item_value() for the advisor and the generators, Fenia .config("fight/item_value")
fight/item_affixes.json the single affix pool: armor stats, affect packs, resists, senses, procs, worn buffs, weapon flags, penalties. Prices, level windows, slot weights, names in three languages ItemAffixRoller in armorgenerator.cpp, WeaponAffixRoller in weapongenerator.cpp, craft scripts
fight/weapon_tiers.json the five tiers: M window, affix counts, negatives allowed, tier roll chance, item lifetime, colour both generators, drops
fight/weapon_damroll_tiers.json base hitroll and damroll of a weapon per tier and level, outside the M budget (like the base AC of armor) WeaponCalculator for random and crafted weapons
fight/weapon_classes.json, weapon_names.json weapon classes and generated names weapongenerator.cpp
fight/armor_profiles.json, armor_names.json armor material profiles and names armorgenerator.cpp
fight/magic_items.json pools and tiers for pills, potions, scrolls, wands and staves, built from the spell price table magicitemgenerator.cpp
fight/spell_value.json what each spell and skill is worth in M: worn, charge, grant magic item generator, advisor, Fenia
fight/spell_combat_value.json expected damage per round of a combat proc, for scoring items that cast in combat advisor
fight/pc_baseline.json a reference player per level band: damage per hit, hp, round length the combat-effect part of the model
fight/material.json materials: hardness, burn ease, price per kg, immunity bit item generators, protectMaterial, repair and cost
fight/item_weight.json the item weight model item_weight() and Fenia .itemWeight

Every file is read by the loader named in Data-Configs. A missing key falls back to the compiled default in C++. A Fenia script that reads a missing key throws, and the throw is swallowed with no message. Reload the configs before posting a script that reads a new key.

Tiers

Windows are in M. The file stores them in centi-M (min_m, max_m).

Tier Name M window Affixes (min to max) Negatives allowed Lifetime of a generated item
1 legendary 4 to 5 5 to 8 2 7 days
2 epic 2.2 to 2.8 4 to 6 2 10 days
3 rare 1.3 to 1.7 2 to 5 2 17 days
4 uncommon 0.85 to 1.15 2 to 3 1 35 days
5 common 0.3 to 0.65 1 1 none
  • A tier lifetime is the item's timer in real days. The timer counts one-minute ticks, so a day is 1440 ticks. This is not a game day, which is 24 ticks.
  • The tier roll starts at the best tier the source allows and walks down. At each tier the roll passes with that tier's chance percent (0, 2, 10, 25, 100). The worst allowed tier always passes. A source may add a per-mille jackpot that jumps to legendary regardless of its window (random_weapon_tier_range).
  • measure.tier_budget (common .5, uncommon 1, rare 1.5, epic 2.5, legendary 4.5 at reference level 60) is the budget used by scripts that do not roll a window, scaled by measure.level_curve (a multiplier by item level, interpolated: 1.5 at levels 1 to 20, 1.2 at 40, 1 at 60, 0.9 at 90).
  • Crafted armor uses its own budgets in centi-M: craft_piece_budget_cm for a piece made by a craft profession, craft_budget_cm for other generated armor, enchant_budget_cm for enchanting, plus mastery_cm_per_level per mastery level. The item level cuts those budgets where the loot pool cannot support them (levelCut).
  • A magic item has its own windows by tier in magic_items.json. A consumable is worth the sum of its spell charge prices, a wand or staff is charge times the number of charges.

Sources

Source Where it is built Rule
Random armor ArmorGenerator, from the script call that randomizes armor tier window by source, archetype of the killer, base items by slot, affixes bought from the pool within the window. The item stores measure_m and its affixes
Random weapon WeaponGenerator base table by weapon class and tier, affixes from the pool, weapon flags priced by level and gated by tier (vorpal and shocking only from rare)
Mob drops scripts on mob death killer's profile decides the archetype. Weapons and armor in a fixed ratio
Boss signature the death scripts and the armor generator a legendary armor drop from a boss gets one forced affix: a defence against the boss damage type, or a proc of one of its spells
Crafted armor and jewelry craft scripts, budgetStats fixed budget per blueprint tier, split by the archetype. A material can bend the shape of the split (more hp, less mana) without changing the total
Rolled crafts at rare and above craft scripts and the C++ craft roll centre is the piece budget plus mastery. Part of it is fixed and shaped by material, the rest rolls from the loot pool inside a spread
Quest rewards and trophies budgetStats priced as crafted armor of a tier, never a flat bonus
Crafted weapons generateWeapon a base table row is the tier, no affixes. Mastery adds damroll and hitroll scaled by item level
Enchant, temper, khuzdul word enchant and word-effect scripts top up permanent hitroll and damroll to a row of the base table, or armor stats to enchant_budget_cm. Timed
Set bonuses the set behavior <affects> flat per set
Magic items MagicItemGenerator spells picked from spell_value.json into the tier window
Gear advisor C++ gearAdvice, item_value() scores items with the same weights. A generated item is scored by its stored measure_m

Cost of an item

item_model_cost(measure_cm, level) = cost_k * (measure_cm / 100) * level, capped at cost_cap (50000 silver). The boot price of a prototype is the smaller of the model price and the price in its area file, so the model only ever lowers a price. A non-takeable item costs nothing.

Spell prices

spell_value.json gives each spell and each non-spell skill three prices in M at level 50:

Price Meaning
worn a permanent affect from a worn item. Null when the spell has no affect meaning (nukes, heals, pets)
charge one use: a pill, a potion, a scroll, or a wand or staff charge. Charges price linearly
grant the skill granted by an item (learned 100)

Use the table for any spell on an item, a charge, a grant, a proc or a reward. Do not price a spell by its level or by feel. A record also carries excluded (the spell is kept out of magic items) and a short effect note.

Generated item data on the instance

A generated item carries properties that scripts and the advisor read. measure_m is the budget in centi-M. affixes lists what was bought. Craft scripts keep their picks in craft_picks so a refit can replay them at a new level and a reroll can roll afresh. Read props through the prototype for behavior-based items, see Fenia-Behaviors.

Rules for a new source

  1. Pick a tier or a budget in M. Reuse budgetStats, a generator or the base table.
  2. Never a flat per-tier bonus. It shrinks with level, while the ruler scales with rolls.
  3. Keep budgets as centi-M integers in Fenia.
  4. Put tunable numbers in JSON. After a change reload the world configs, then post any script that reads a new key.
  5. A new stat source needs a weight in item_value.json or a price in item_affixes.json, or the advisor will not see it.
  6. A penalty that the model has no weight for is hand-priced in points under the penalty section of the pool.
  7. Alignment data in the pool decides who may roll an affix. Good, neutral and evil variants of a family (sanctuary, stardust, dark shroud) are picked by the killer's alignment. The pool also holds a per-class pick weight curve by level, and a have check that skips an affix the killer already has.
  8. Set an upper bound on stacking. Sanctuary family, haste and resist weapon roll at most twice per item, the second at a tenth of the weight.

Weights worth knowing

  • Melee column, per point: damroll 12, hitroll 6, hp 1, mana 0.1, saves 3. Caster column: damroll 6, hitroll 2, hp 1, mana 0.5, mana gain 0.6, saves 5, spell level 25. These are file values and move when tuned.
  • Affect flags are priced per flag for melee and caster, except sanctuary, protect evil, protect good and haste, which are priced by item level from flags_by_level (sanctuary at level 60 is 59 melee and 282 caster). The flat flags row (sanctuary 300 and 300, haste 110 and 40) is only the fallback when no level is given. Curses are negative (blind -200, sleep -250). A flag the character can cast on itself counts for 10%.
  • Resist, immunity and vulnerability are priced per damage type in res as [resist, immune, vulnerable]. Weapon immunity is the top at 420 points and a bash vulnerability costs 108. The weights follow how common each damage type is in the world and how dangerous it is, see Mechanics-Combat. Resists do not stack.
  • An item that casts a spell while worn is scored at the worn price of the spell, not at a flat trigger bonus.

See also

Clone this wiki locally