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.

Gear-granted ability upgrades are a different surface: see Ability authoring: gear grants (the ItemAbilityGrants/ type) for an item that hands a player a whole ability, rather than a stat.

Everything on this page is authored onto an item id, so every copy carries it. To roll stats onto one particular item a player already owns - an anvil ritual, a stamped reward, a rolled drop - see Rolled Stats & Stamping. It draws from the same stat ids catalogued below.

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.

Prefer a content pack: author one file per item under Server/Item/Items/ inside a pack folder, zip it, and drop the .zip into your server Mods/ folder. Building the zip.

Global stat ids
12
Per-school stat ids
27
Per-skill stat families
12
Ability channels
7
Damage schools
9

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

3 ids per school - two attacker-side ids (PERCENT and FLAT) and one victim-side resist id - 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 for that school, granted attacker-side.
MMO_BonusFlat_<School>EntityStat (flat)optionalFlat damage bonus, composed before the percent multiply, attacker-side.
MMO_SchoolResist_<School>EntityStat (percent)optionalPercent resistance to that school, granted victim-side - whatever grants it (armor, weapon enhancement, mastery) sums on this one channel, and the engine applies the matching resistance while it is worn.
* required

Valid <School> values (9): Fire, Ice, Lightning, Water, Arcane, Void, Poison, Life, Physical. Full ids, e.g. MMO_Bonus_Fire, MMO_BonusFlat_Void, MMO_SchoolResist_Poison. Poison is the toxin school, an overlay over the vanilla Poison damage cause rather than a mapped essence. Life is the drain and lifesteal school, so gear granting MMO_Bonus_Life scales soul-draining and vampiric hits. Physical is the broadest of the set: it is the school of every plain weapon strike and of any hit that names no school at all, and its resist id also covers the vanilla Slashing, Bludgeoning and Projectile causes that fold into it, so MMO_SchoolResist_Physical is what a general-purpose breastplate wants rather than a per-element channel. See the damage-school roster for the full list and which abilities carry each one.

An armor piece granting native per-school resistance:

json
"Armor": { "StatModifiers": { "MMO_SchoolResist_Fire": [ { "Amount": 4, "CalculationType": "Additive" } ] } }

Ability channels (gear-reachable ability numbers)

7 global, not-per-skill ids fold flat additive bonuses into the SAME per-cast number an ability body's own ParamKeys already compose through - see Ability authoring: numbers for the body-side half of this fold.

FieldTypeDefaultDescription
MMO_AbilityRangeworld unitsoptionalFlat additive range bonus. Folds onto a body node's distance ParamKey.
MMO_AbilityRadiusworld unitsoptionalFlat additive radius bonus (a selection or zone geometry: MmoSelect Sphere/Cone, MmoZone.Radius). Folds onto a body node's radius ParamKey.
MMO_AbilityDamageRadiusworld unitsoptionalFlat additive damage-splash radius bonus (MmoDamage/MmoBeam radius, MmoDash hit radius). Folds onto a body node's damageRadius ParamKey.
MMO_AbilityDurationmillisecondsoptionalFlat additive duration bonus. Folds onto a body node's durationMs ParamKey.
MMO_AbilityCostReductionresource unitsoptionalFlat cost reduction, subtracted from the ability-level cost; the Cost.json Min: 0 clamp floors the result so it can never refund. Folds onto a body node's cost ParamKey.
MMO_AbilityIFramesmillisecondsoptionalFlat additive i-frame duration bonus. Folds onto a body node's iframesDurationMs ParamKey.
MMO_AbilityPiercepierce countoptionalFlat additive pierce-count bonus. Folds onto a body node's pierceCount ParamKey.
* required

Every channel ships base Max 0: additive-first authoring only

A Multiplicative-only StaticModifier on a base-0 channel folds to 0 * x = 0 and is silently inert - nothing errors, the item just does nothing. Author these as Additive. Each is also capped by the server's own bound under Server/MMOSkillTree/ModifierClamps/, which the owner can tighten further in mods/mmoskilltree/ability-clamps.json, so a stacked pack cannot push a number past what the server intends.

A ring granting bonus ability radius:

json
"Armor": { "StatModifiers": { "MMO_AbilityRadius": [ { "Amount": 1.5, "CalculationType": "Additive" } ] } }

Per-skill stats

12 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.
MMO_CooldownReduction_<SkillId>EntityStatoptionalFamily CooldownReduction. Global sibling: MMO_CooldownReduction.
MMO_Level_<SkillId>EntityStatoptionalFamily Level - read-only, not gear-grantable. Global sibling: none - read-only, mirrors the skill's own level.
* 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. MMO_Level_<SkillId> is the odd one out: it mirrors the skill's own level rather than anything gear can grant, and is what a Requires factor reads to gate on a skill level.

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>, every MMO_SchoolResist_<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.
Ability channels (MMO_Ability*)exceptionoptionalRaw units (world units, milliseconds, resource units, pierce count) - 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.

Target defaults to Max (shown in the worked examples below); 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 filled in, with no authorable escape. A stat-bearing tool authored the weapon way can never mine hard blocks.

A tool authors its stats as an ordinary native Utility.StatModifiers block instead, with Usable and Compatible left unset (both default to false). That is a stat surface with no side effects, because the engine never applies a utility block for an item that is merely held; the mod applies it while the tool is in hand:

json
"Utility": {
  "StatModifiers": {
    "MMO_Luck_MINING": [ { "Amount": 10, "CalculationType": "Additive" } ]
  }
}

Every stat id on this page works here, with the same whole-percent-point convention as an Armor or Weapon block.

Client tooltips do not auto-row a held tool's utility stats, so the mod generates the stat text into the item's description at runtime, one colored line per additive modifier, and the number lives only in the asset instead of being duplicated into language text. Author your flavor prose on the server.items.<Id>.description.base key; the item JSON's own Description field still points at the plain server.items.<Id>.description key. Author server.items.<Id>.description yourself if you want full manual control: boot packs load before the generated text, and the first writer of a key wins. See Which .lang file does my key go in? for why the prefix is server. here.

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",
  "Utility": {
    "StatModifiers": {
      "MMO_Luck_MINING": [ { "Target": "Max", "CalculationType": "Additive", "Amount": 10 } ]
    }
  },
  "Quality": "Uncommon",
  "ItemLevel": 20
}

An offhand or utility-slot accessory is not a held tool

An accessory that authors Usable: true uses the same Utility.StatModifiers block, but gets no generated stat lines: the engine applies it natively and the client already rows it in the tooltip's own stats section, so generated lines would print everything twice. Only its .description.base prose is written through, and an accessory without that prose gets no generated description at all.

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 tag, not a stat

Everything above grants stat bonuses through a native stats block. A separate raw tag, MMO_Weapon_Type, does a different job for weapons: it grants no stat at all, 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 (12 ids per skill, the 12 families times every active skill) are generated at runtime, at server start and again 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": "server.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, a whole-percent lifesteal bonus, and native Void resistance:

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

A custom tool

Grants bonus mining luck and bonus mining XP through a utility stats block - never a Weapon block, which would zero its mining power:

Server/Item/Items/My_Lucky_Pickaxe.json
{
  "TranslationProperties": { "Name": "server.items.My_Lucky_Pickaxe.name",
    "Description": "server.items.My_Lucky_Pickaxe.description" },
  "Parent": "Tool_Pickaxe_Steel",
  "Utility": {
    "StatModifiers": {
      "MMO_Luck_MINING": [ { "Amount": 15, "CalculationType": "Additive" } ],
      "MMO_BonusXp_MINING": [ { "Amount": 10, "CalculationType": "Additive" } ]
    }
  },
  "Quality": "Rare",
  "ItemLevel": 40
}