Mechanics reference
The combat toolbox the sim (@hnd/sim) exposes — every stat, effect,
delivery, status, hook and condition an ability or talent can be built from.
Numbers are pulled live from the engine, so this page can't drift from the code.
Use it to design new classes & talents: pick a delivery, a payload of
effects, and (for passives) hooks or a dynamic modifier.
The one pipeline
Every offensive/defensive interaction funnels through applyPayload: (1) to-hit — hostile only: miss = clamp(avoidance − hitRate) where avoidance is dodge (physical) or spellResist (spell). On a miss only unavoidable effects land. (2) crit — one shared roll, clamp(critChance − critAvoidance). (3) apply each
effect in order. Then hooks fire (onHit / onHitTaken / onCritGiven), and any hp
drop fires onDamaged + a death/kill-credit check.
Stats 15
Read only through getStat(). Power & hp scale with level; the
0..1 avoidance/crit/mitigation stats do not (keeps them readable). Buffs,
items and talents adjust stats by pushing modifiers.
| key | unit | meaning |
|---|---|---|
maxHp | hp | level-scaled max health |
moveSpeed | m/s | chase/patrol speed; slow reduces it (strongest-wins) |
attackPower | power | physical damage base (level-scaled) |
spellPower | power | spell damage base (level-scaled) |
healPower | power | healing base (level-scaled) |
hitRate | 0..1 | attacker: reduces the target's avoidance |
critChance | 0..1 | attacker: chance to crit |
critMultiplier | × | attacker: crit damage/heal multiplier |
critAvoidance | 0..1 | target: subtracts from attacker's critChance |
dodge | 0..1 | target: avoid a physical hit |
spellResist | 0..1 | target: resist a spell (allies never resisted) |
physicalReduction | 0..0.8 | target: multiplicative physical mitigation |
spellReduction | 0..0.8 | target: multiplicative spell mitigation |
aggroRangeM | m | NPC: notice range |
hpRegenPS | hp/s | out-of-combat regen |
Effects 12
The payload. ability.effects[] (and hook effects[])
are a discriminated union, applied to each chosen target. Unavoidable effects land even on a miss; self effects act on the actor. *applyStatus is only avoidable when hostile (a debuff on a foe).
| type | params | class | notes |
|---|---|---|---|
damage | coefficient | avoidable | school-scaled, mitigated, can crit |
heal | coefficient | friendly | healPower-scaled, never missed, can crit |
flatDamage | amount | unavoidable | flat, no to-hit/crit/mitigation (thorns/procs) |
percentHealth | pct, of, heal? | unavoidable | % of max/current hp, flat |
push | speedMS, from | avoidable | knockback impulse (decays via friction) |
applyStatus | status, to? | avoidable* | apply a status; to:'self' rides a targeted cast |
removeStatus | match | — | dispel/cleanse/purge by polarity/kind/element |
consumeStatuses | match, perStackCoefficient | avoidable | detonate stacks for bonus damage (Execute) |
teleport | mode, distanceM? | self | instant blink (forward=aim, toTarget=adjacent) |
jump | mode, distanceM?, speedMS | self | fast glide to destination |
resetCooldown | abilityKind? | self | reset one/all of the actor's cooldowns |
lifesteal | fraction | self | heal actor for a fraction of damage dealt |
Deliveries 7
How targets are chosen — orthogonal to effects (any payload rides any delivery).
self | no target — hits the actor |
single { rangeM, minRangeM?, melee? } | one target in range; impact delay syncs melee |
projectile { rangeM, speedMS } | homing bolt; to-hit rolled at impact |
arc { rangeM, arcDeg } | frontal cone; each target rolls its own hit/crit |
aoe { radiusM, center, filter } | everyone in radius of self/target; flat damage |
groundAoe { radiusM, placeRangeM } | drag to place a center within reach |
aura { radiusM, status, filter } | persistent field applying a link status |
Statuses 9
Everything time-boxed lives in one list; capabilities derive from it each frame.
stun | can't move/turn/act/regen |
sleep | like stun; breaks on any damage |
immobilize | can't move (turn/act ok); blocks self-moves |
slow | moveSpeed × (1 − magnitude); strongest active wins |
dot / hot | periodic damage/heal; snapshot at apply, no crit/variance |
buff | modifier bag + hooks + duration (debuff = polarity) |
stealth | unseen unless within 50% melee; breaks on offense/damage |
taunt | forces an NPC's target onto the caster |
auraLink | membership token placed by an aura field |
Stacking
refresh | reset duration (default; sleep, dot/hot, buffs) |
takeLonger | keep the greater remaining (hard CC: stun, immobilize) |
strongest | all coexist, only the max-magnitude is active (slow) |
stack | increment stacks to maxStacks; modifiers scale by stacks |
Hooks 8
Reactive event → effects on a status (usually a buff). Fire flat & unavoidable, no recursion. Power reflect, lifesteal, procs, detonations.
onHit | landed a hostile effect (ctx.other = victim) |
onHitTaken | hit by a hostile effect (ctx.other = attacker) |
onDamaged | hp dropped from any source (ctx.other = source) |
onDodge | dodged a physical hit |
onResistSpell | resisted a spell |
onCritGiven | landed a crit |
onKill | landed a killing blow |
onExpire | this status expired (Living Bomb detonate) |
Hook target
self | the carrier |
source | ctx.other (attacker / victim) |
aoeAroundSelf | foes-of-the-owner within radiusM of the carrier |
Conditions 9
Gate an ability at trigger time (all must pass). Also reused on hooks. Combos read the element/status tags they leave behind.
casterOutOfCombat / casterInCombathasTargetcasterStealthedcasterHealthBelowPct / AbovePct { pct }targetHealthBelowPct / AbovePct { pct }targetWithinRangeM { rangeM }targetHasStatus { kind }targetHasElement { element }targetIsImmobilized
Casting & channeling
cast: fire on complete; incoming damage pushes it back
500 ms. channel: apply every tick; incoming
damage shortens it 500 ms. No global cooldown — per-ability
only.
Dynamic modifier
A passive stat whose magnitude tracks live state each tick: basis: missingHpPct | currentHpPct | enemiesWithinM, mode: add | factor, capped. Powers Frenzy (HP-scaled attack)
and Bulwark (crowd-scaled mitigation).
Talents
A talent is one effect of a kind below. Points bank (1/level from L2, cap 9);
a branch is a diamond — two free talents, two that need 2 in branch, then the capstone that needs 4. No reassign.
| kind | does |
|---|---|
grantAbility | adds a new button to the bar |
modifyAbility | patches an existing ability (cooldown, +effects, coefficient, range) |
passive | an always-on status: modifiers / hooks / dynamicModifier |
statModifier | flat unconditional stat change(s) |
Live inventory
A frontline bruiser who lives in the thick of it. Strong armour and wide swings let the Warrior hold off many foes at once — charge in, take the hits, and hand them back harder.
Tuning baselines
Single source of truth in config.ts — tuned in the lab, shipped as-is.
| Player attack/spell/heal power (L1) | 11 |
| Player maxHp / speed (L1) | 100 hp / 4 m/s |
| Damage variance (global spread) | ±20% |
| Base crit chance / multiplier | 10% / 1.75× |
| Base dodge / spell resist | 10% / 10% |
| Mitigation cap | 80% |
| Cast pushback / channel shorten | 500 / 500 ms |
| Teleport settle window | 1000 ms |
| Physical reach (pull / loot-walk) | 10 m |
| Regen combat lockout | 5000 ms |