Gear Stats: MMO_* Item Stats

Grant any of the mod's tracked stats from a plain item Armor or Weapon block - the same native mechanism a vanilla stat like Health already uses, no plugin code needed

Since 1.6.0

The mod registers one native Hytale EntityStat per scalar it tracks, under the MMO_* id prefix. Because these are real EntityStats, any item's Armor or Weapon block can grant them through a StatModifiers entry - the exact same field a vanilla item uses to grant Health or Stamina. Authoring a gear stat needs no AbilityMod, no reward, and no plugin code at all.

Content pack assetServer/Item/Items/<Id>.jsonItem/Items/

This is the native Hytale item schema, not an MMOSkillTree-custom asset type - see hytale-shared-source/HytaleAssets/Schema/ for the official codec contract. The MMO_* stat ids themselves are Java-registered (EntityStat definitions, code-only); the item JSON that references them is plain pack content.

Global stat ids
12
Per-school stat ids
12
Per-skill stat families
10
Damage schools
6

Global stats (not skill/school-scoped)

12 ids, none of them tied to a specific skill or damage school.

FieldTypeDefaultDescription
MMO_DefenseEntityStatoptionalWriter-backed (the skill tree / mastery also write here).
MMO_CritChanceEntityStatoptionalWriter-backed.
MMO_CritMultiplierEntityStatoptionalBase-only (base max 1.5). Raw multiplier scale, not whole-percent - see the convention note below.
MMO_LifestealEntityStatoptionalWriter-backed.
MMO_LifestealFlatEntityStatoptionalWriter-backed. Absolute (raw), not whole-percent.
MMO_ComboDamageEntityStatoptionalWriter-backed.
MMO_ComboDamageFlatEntityStatoptionalWriter-backed. Absolute (raw).
MMO_FallDamageReductionEntityStatoptionalWriter-backed.
MMO_EffectDurationEntityStatoptionalWriter-backed.
MMO_CooldownReductionEntityStatoptionalWriter-backed.
MMO_LuckEntityStatoptionalWriter-backed.
MMO_BonusXpEntityStatoptionalWriter-backed.
* required

Per-school stats

One PERCENT id and one FLAT id per school, all base-only (empty by default until an item grants them). Flat composes into the base before the percent multiply: (base + flat) * (1 + percent).

FieldTypeDefaultDescription
MMO_Bonus_<School>EntityStat (percent)optionalPercent damage bonus against/for that school.
MMO_BonusFlat_<School>EntityStat (flat)optionalFlat damage bonus, composed before the percent multiply.
* required

Valid <School> values (six): Fire, Ice, Lightning, Water, Arcane, Void. Full ids, e.g. MMO_Bonus_Fire, MMO_BonusFlat_Void. See Damage schools for how an ability's Cause ties into these same six schools.

Per-skill stats

10 channels per skill, registered at runtime for every active skill (built-in or added via custom-skills.json). Id shape is always MMO_<Family>_<SkillId>.

FieldTypeDefaultDescription
MMO_Damage_<SkillId>EntityStatoptionalFamily Damage. Global sibling: none - always per-skill.
MMO_DamageFlat_<SkillId>EntityStatoptionalFamily DamageFlat. Global sibling: none - always per-skill.
MMO_CritChance_<SkillId>EntityStatoptionalFamily CritChance. Global sibling: MMO_CritChance.
MMO_CritMultiplier_<SkillId>EntityStatoptionalFamily CritMultiplier. Global sibling: MMO_CritMultiplier.
MMO_Lifesteal_<SkillId>EntityStatoptionalFamily Lifesteal. Global sibling: MMO_Lifesteal.
MMO_LifestealFlat_<SkillId>EntityStatoptionalFamily LifestealFlat. Global sibling: MMO_LifestealFlat.
MMO_ComboDamage_<SkillId>EntityStatoptionalFamily ComboDamage. Global sibling: none.
MMO_ComboDamageFlat_<SkillId>EntityStatoptionalFamily ComboDamageFlat. Global sibling: none.
MMO_Luck_<SkillId>EntityStatoptionalFamily Luck. Global sibling: MMO_Luck.
MMO_BonusXp_<SkillId>EntityStatoptionalFamily BonusXp. Global sibling: MMO_BonusXp.
* required

Example: MMO_Damage_SWORDS, MMO_Luck_MINING, MMO_BonusXp_FISHING. MMO_Damage_<SkillId> scales both plain weapon swings and any ability whose damage resolves to that combat skill (ability XpRouting.Skills first, held-weapon fallback second) - it is not scoped to plain swings only.

The whole-percent-point convention

Every PERCENT-family StatModifiers amount is authored in whole percent points: a +10% bonus is "Amount": 10, never 0.10. This covers every global writer-backed stat, every MMO_Bonus_<School>, and every per-skill PERCENT channel.

json
"Armor": { "StatModifiers": { "MMO_Bonus_Fire": [ { "Amount": 10, "CalculationType": "Additive" } ] } }
FieldTypeDefaultDescription
MMO_CritMultiplier(_<SkillId>)exceptionoptionalRaw multiplier units on the same whole-number scale: 50 = +0.5x added to the 1.5x base. Not a percent-point.
MMO_*Flat* (any family)exceptionoptionalAbsolute values, authored exactly like any raw stat - not whole-percent-point.
Health / Mana / vanilla statsexceptionoptionalStay authored exactly as before this convention existed.
* required

DamageResistance is a different convention entirely

Native DamageResistance uses engine fractions (e.g. 0.25 = 25%, CalculationType: "Percent"). Do not apply the whole-percent-point rule to it - that rule is MMO_*-specific.

ModifierTarget defaults to Max; CalculationType for StatModifiers is Additive / Multiplicative only (Percent belongs to DamageResistance, a different enum).

The Parent full-object-replace trap

Armor/Weapon is a whole-object replace, not a per-field merge

Omitting the Armor/Weapon block entirely still inherits the parent's block by reference - but the moment you author Armor/Weapon at all, even to add one line, you must restate the whole object (its existing DamageResistance, StatModifiers, EntityStatsToClear, ...) or you silently drop everything else the parent granted.

Real example of the trap avoided (a Weapon_Sword_Steel child item). The vanilla parent's Weapon block (inherited from Template_Weapon_Sword) carries the sword's signature-charge mechanic - the child copies that verbatim and adds one new MMO_Damage_SWORDS line instead of replacing the block outright:

Example_Duelists_Blade.json
"Weapon": {
  "EntityStatsToClear": ["SignatureEnergy"],
  "StatModifiers": {
    "SignatureEnergy": [ { "Amount": 20, "CalculationType": "Additive" } ],
    "MMO_Damage_SWORDS": [ { "Amount": 10, "CalculationType": "Additive" } ]
  }
}

A pack cannot ship a Parent-inheriting item that partially overrides Armor/Weapon - this is a structural limitation of native Parent inheritance, not a missing MMOSkillTree feature.

Held tools: the one exception

Never a Weapon block on a tool

The engine zeroes an item's tool power the moment its Weapon block is non-null (source- proven in BlockHarvestUtils.getSpecPowerDamageBlock, no authorable escape). A stat-bearing tool authored the weapon way can never mine hard blocks.

A tool instead authors the mod's raw-tag channel, MMO_Tool_Stats, on the item's Tags block:

json
"Tags": { "MMO_Tool_Stats": [ "MMO_Luck_MINING:10" ] }

Entries are "<StatId>:<points>" strings (whole percent points), read while the item is held. Only the MMO_Luck_* and MMO_BonusXp_* channels consume this tag - other stat ids placed in it are inert.

Client tooltips do not auto-row tag stats (that is a StatModifiers-only surface), so a runtime generator (ToolStatDescriptionGenerator) appends a colored +<points>-style stat line into the item's description at runtime. Author flavor prose on the new items.<Id>.description.base key - the item JSON's own Description field still points at the plain items.<Id>.description key. Authoring description directly yourself instead fully overrides the generated value (first-writer-wins; boot packs load before the generator's runtime pack).

examples/phase-i-school-pack/Server/Item/Items/Example_Tool_Pickaxe_Fortune.json
{
  "TranslationProperties": { "Name": "server.items.Example_Tool_Pickaxe_Fortune.name",
    "Description": "server.items.Example_Tool_Pickaxe_Fortune.description" },
  "Parent": "Tool_Pickaxe_Iron",
  "Tags": { "MMO_Tool_Stats": [ "MMO_Luck_MINING:10" ] },
  "Quality": "Uncommon",
  "ItemLevel": 20
}

The block-tool gate is an id substring match

The item's id must contain the literal substring Tool_Pickaxe_ (or the matching family substring for other tool types) - a case-sensitive id-substring match, no Tags/Categories fallback. In the example above this comes for free from the Tool_Pickaxe_Iron parent id.

MMO_Weapon_Type: a different tag entirely

MMO_Tool_Stats grants stat bonuses. A separate tag, MMO_Weapon_Type, does the opposite job for weapons: it does not grant any stat, it only routes combat XP to a skill when a custom weapon's item id does not match any xp-maps.json pattern for its family.

json
"Tags": { "MMO_Weapon_Type": [ "SWORDS" ] }

Full field reference, matching rules, and troubleshooting: see Weapon Skill Tags. Values there are skill ids; the first registered match wins.

Tooltip labels

The closed Hytale client names an item's stat tooltip line via itemTooltip.stats.<StatId> in the client lang namespace (client.lang, not mmoskilltree.lang) - a missing matching key falls back to printing the raw stat id.

  • All 12 global MMO_* stat labels ship in client.lang for all 9 locales.
  • Per-skill labels (10 ids per skill, the 10 families times every active skill) are runtime-generated by StatTooltipLangGenerator at plugin start and on any skill-roster change - a disabled, renamed, or newly-added skill never needs a hand-edited label.
  • A pack or owner overrides any generated label (or supplies a localized custom-skill name) by shipping its own client.lang with the same key (boot packs load first, first-writer-wins).

Worked examples

A custom sword

Grants extra sword-skill damage plus a flat fire bonus, on top of the vanilla parent's own block:

Server/Item/Items/My_Ember_Blade.json
{
  "TranslationProperties": { "Name": "mypack.items.My_Ember_Blade.name" },
  "Parent": "Weapon_Sword_Steel",
  "Weapon": {
    "EntityStatsToClear": ["SignatureEnergy"],
    "StatModifiers": {
      "SignatureEnergy": [ { "Amount": 20, "CalculationType": "Additive" } ],
      "MMO_Damage_SWORDS": [ { "Amount": 12, "CalculationType": "Additive" } ],
      "MMO_BonusFlat_Fire": [ { "Amount": 5, "CalculationType": "Additive" } ]
    }
  },
  "Quality": "Rare",
  "ItemLevel": 45
}

A custom armor piece

Grants a defense bonus and a whole-percent lifesteal bonus:

Server/Item/Items/My_Vampiric_Chestplate.json
{
  "TranslationProperties": { "Name": "mypack.items.My_Vampiric_Chestplate.name" },
  "Parent": "Armor_Chest_Iron",
  "Armor": {
    "StatModifiers": {
      "MMO_Defense": [ { "Amount": 5, "CalculationType": "Additive" } ],
      "MMO_Lifesteal": [ { "Amount": 3, "CalculationType": "Additive" } ]
    }
  },
  "Quality": "Epic",
  "ItemLevel": 55
}

A custom tool

Grants bonus mining luck via the tag channel - never a Weapon block, which would zero its mining power:

Server/Item/Items/My_Lucky_Pickaxe.json
{
  "TranslationProperties": { "Name": "mypack.items.My_Lucky_Pickaxe.name",
    "Description": "mypack.items.My_Lucky_Pickaxe.description" },
  "Parent": "Tool_Pickaxe_Steel",
  "Tags": { "MMO_Tool_Stats": [ "MMO_Luck_MINING:15", "MMO_BonusXp_MINING:10" ] },
  "Quality": "Rare",
  "ItemLevel": 40
}