Custom passives
A custom passive is an id you add toPassivesConfig.json and to a class Passives array. It shows on the class sheet (name, icon, and the text for the tier on screen). It runs only when the player has that class and the tier is high enough.
Built-in passives (High Guard, Thick Skin, and the rest) keep their current combat behavior. Registering those ids does nothing.
JSON
mods/Zuxaw_RPGLeveling/Classes/PassivesConfig.json:
- Name, Icon, and Template are what the class sheet shows. Icon is a Hytale item id.
- Template replaces
{Key}with the numbers in T for the tier tab the player is looking at (T0 through T4). A later tier only needs the keys that change. - Unlock hides the row until that tier.
- A language key
passives.<id>.nameorpassives.<id>.templateoverrides Name and Template when you want a translation. Otherwise the JSON is enough.
/lvl reload or a restart. The sheet draws four passives. Handlers still run for every passive on the class.
Code
Register once when your mod starts. A command, a key, a potion, or any other moment your code already handles:triggerPassive does nothing if the player does not have the class, the tier is too low, or the id is a built-in passive.
Damage dealt, damage taken, or a kill:
PassiveWhen.HURT is damage taken. PassiveWhen.KILL is a kill. Those handlers do not run from triggerPassive.
ctx.get("DamagePercent") is the merged T value for the player’s tier. ctx.player() is the player. On a hit, ctx.addDamagePercent and ctx.addHeal change that hit. Several handlers for the same id and the same moment add together.
api.hasPassive(player, "GuardPulse") is true only when the selected class lists it and the tier has unlocked it.
api.unregisterPassive("GuardPulse") removes every handler for that id.
A new moment (a potion, a key, another mod’s event) does not need a RPG Leveling update. Call triggerPassive from the code that already sees that moment.