How damage is worked out
The whole path from a statistic to a health bar, in the order it happens.
Every blow in the game goes through one function. Not by convention — by construction: there is a single place where health goes down, and everything that can hurt a player is routed through it. That is what makes this page short enough to be true.
The order
Mitigate the school. Physical damage is answered by Armor, magic damage by Magic Resist. The reduction is flat and one-for-one: a point of Armor cancels a point of Physical Damage. Never below zero — damage does not heal.
mitigated = max(0, damage − mitigation)Add True Damage. Added after mitigation, so nothing reduces it. This is the whole of its design: it is the statistic that beats a defensive build rather than out-scaling it.
blow = mitigated + trueDamageWeight it by where it landed. A trauma resolves into an ordered path through the body's hit volumes, and that path yields one weight for the whole blow. Applied once, over the sum — mitigating per volume would make a deeper wound hurt less, because armour would be paid for every volume the shot passed through.
damage = round(blow × locationWeight)Spend shields. Absorption stands between that number and the health bar: the matching school's pool first, then the general one. See Shields.
Take the remainder off health. Whatever the shields did not absorb.
Death
Death is not a flag. A player is dead exactly while their health is at zero, so a corpse cannot disagree with its health bar.
That leaves one thing that is not damage: losing a vital volume. A trauma that takes the head or destroys the torso kills directly, by setting health to zero — it does not roll a large number and hope. This is why a shield does not save you from decapitation: a shield absorbs harm, and losing your head is not harm, it is an outcome.
The numbers, as they actually are
A player's full health pool, and every statistic they carry before anything is equipped, are rendered below straight from the simulation.
640| Statistic | Base | What it does |
|---|---|---|
| physicalDamage | 55 | Answered by Armor. |
| magicDamage | 0 | Answered by Magic Resist. |
| trueDamage | 0 | Answered by nothing. Added after mitigation. |
| haste | 0 | Shortens cooldowns, by division. |
| movementSpeed | 6 | Metres per second. |
| armor | 30 | Cancels Physical Damage, one for one. |
| magicResist | 30 | Cancels Magic Damage, one for one. |
An enemy's health pool and its own statistics follow the same rule.
420| Statistic | Value |
|---|---|
| physicalDamage | 70 |
| magicDamage | 85 |
| armor | 25 |
| magicResist | 25 |
Spells
There is no basic attack. The thing you do by default is a spell like any other and is meant to be swapped, so it is an entry in a table rather than a special case.
Timing is gameplay and lives in the simulation — the client stretches its animation to fit what this says. The alternative is combat timing living inside an exported GLB, where nobody can reason about it.
Every spell is listed below, with its tick counts converted into seconds at the server's tick rate.
20| Spell | School | Cost | Cast | Lands on | Reach | Cooldown | Kind |
|---|---|---|---|---|---|---|---|
| kick | physical | 15 | 1.0 s | 0.6 s | 2.4 m | 2.2 s | crush |
A worked example
An unmodified player kicks an unmodified enemy, square in the torso.
The player's Physical Damage is mitigated by the enemy's Armor, leaving the difference — both figures are in the tables above.
True Damage is added. Base is zero, because nobody is born ignoring armour.
The sum is weighted by where the blow landed, then rounded.
The enemy carries no shields, so all of it reaches health.
Haste
Cooldowns are shortened by Haste, which divides rather than subtracts:
ticks = max(1, round(cooldown / (1 + haste / 100)))100 Haste halves a cooldown, 200 thirds it, and no amount of it ever reaches zero. Subtracting would have meant some finite pile of Haste removed cooldowns altogether, and a cost you can delete is not a cost.
Last updated Aug 3, 2026