Elements & Status Effects
Fire, cold, lightning, and poison damage, plus the DoT / freeze / stun status effects and how resistances reduce them.
On this page
Damage comes in two kinds: physical and elemental. They roll and resolve separately. Physical damage is reduced by Defense Rating, Constitution, and Reduced-Physical affixes (which share a single 50% cap — see Combat); each element is reduced only by its own matching resistance.
The four elements
The elements are Fire, Cold, Lightning, and Poison. Flat elemental damage from a weapon or skill applies on hit, on top of your physical damage:
elementalDamage = rawElementalDamage × (1 − resistance)
Flat elemental damage is speed-normalised per hit: a slow weapon applies a proportionally larger elemental rider per swing, so elemental DPS is equal across weapon speeds.
Resistances & the 75% cap
Fire, Cold, Lightning, and Poison resistances are each capped at 75% for your hero. Single-element resistance affixes roll on armour, amulets and rings; All Resistances stays amulet-only. Some skills and passives raise resistances too. Resistances can also go negative (a vulnerability), and enemies are capped higher, at 95%.
Some weapon and amulet affixes apply resistance penetration, reducing the target’s resistance by a flat amount before mitigation — this makes elemental builds much stronger against high-resistance enemies. Debuff/penetration effectiveness is itself capped at 90%.
The three caps are hand-tunable constants in src/data/balance/combat.ts:
| Cap | Value | Constant (combat.ts) |
|---|---|---|
| Hero resistance (per element) | 75% | FORMULA_CONFIG.maxResistance (line 40) |
| Enemy resistance | 95% | FORMULA_CONFIG.maxEnemyResistance (line 58) |
| Debuff / penetration effectiveness | 90% | MAX_DEBUFF_EFFECTIVENESS (line 82) |
Every resistance value — hero and enemy, direct hit and DoT — is clamped to [0, 0.95] inside damageAfterResistance, and penetration is clamped to [0, 0.90] before it is subtracted.
Status effects
When you carry flat elemental damage (or use the matching skill), a landed hit can apply a status effect. Fire, Cold, and Lightning roll a 10% proc chance per hit; Cold and Lightning normalise that chance by weapon speed (slow weapons roll a higher per-hit chance) so crowd-control uptime per second is equal across weapons. Poison’s damage-over-time applies on every hit. Bleed comes from the Rend main skill rather than an element.
| Icon | Effect (source) | Proc chance | Duration | Magnitude | Resisted by |
|---|---|---|---|---|---|
| Ignite / Burn — Fire | 10% per hit (flat) | 6 s | 25% of the hit’s fire damage, split into 0.5 s ticks | Fire resistance | |
| Poison — Poison damage | Always (every hit) | 6 s | The flat poison-damage value, spread evenly over the duration (0.5 s ticks) | Poison resistance | |
| Bleed — Rend (physical) | On every Rend hit | 5 s | amount × bleed%, spread evenly over the duration | Unresisted | |
| Freeze — Cold | min(1, 0.10 × weaponInterval) | 2 s | Slows the enemy’s attack speed by 30% | — (crowd control) | |
| Stun — Lightning | min(1, 0.10 × weaponInterval) | 2 s | Pauses the enemy’s attack timer entirely | — (crowd control) |
Durations, tick rate, and the proc chance are the hand-tunable constants in src/data/balance/status-effects.ts: FIRE_DOT_DURATION_SECONDS = 6, POISON_DOT_DURATION_SECONDS = 6 (unified with fire in v0.8.12 — the flat-poison affix and the poison-skill path both use this same value), BLEED_DOT_DURATION_SECONDS = 5, LIGHTNING_STUN_DURATION_SECONDS = COLD_FREEZE_DURATION_SECONDS = 2, DOT_TICK_INTERVAL_SECONDS = 0.5, and PLAYER_ELEMENTAL_PROC_CHANCE = 0.10.
DoT magnitude — exact formulas
All three damage-over-time effects are stored as a damage-per-second value that ticks every 0.5 s. Poison and Ignite are reduced by the enemy’s matching resistance when applied (minus any penetration, capped at 90%); Bleed is physical and never resisted (src/core/simulation.ts, applyPlayerElementalOnHit + applyEnemyDamageOverTime).
-
Ignite (Fire DoT) — the total is a fixed fraction of your flat fire damage, independent of duration:
FIRE_DOT_DAMAGE_FACTOR = 0.25 / 6 # = 0.25 over the 6 s duration dotPerSecond = fireDamage × FIRE_DOT_DAMAGE_FACTOR totalIgnite = dotPerSecond × 6 = fireDamage × 0.25 (before fire resistance)The proc chance is a flat 10% (not speed-normalised): the DoT magnitude already scales off
fireDamage, which is itself speed-normalised per hit, so slow weapons land bigger-but-rarer ignites for equal DPS. -
Poison DoT — the flat poison-damage stat is the DoT total, spread over the duration, and it is applied on every landed hit with no proc roll:
dotPerSecond = poisonDamage / 6 totalPoison = poisonDamage (before poison resistance)Because it never rolls a proc, poison is the most consistent DoT — but on multi-hit skills (Zeal) the poison damage still applies on every sub-hit while status procs only roll on the first.
-
Bleed (Rend) — physical, unresisted, magnitude scales off the damage of the Rend hit:
totalBleed = amount × bleedPercent # amount = the post-mitigation physical hit dotPerSecond = totalBleed / 5
Freeze and Stun are fixed-duration crowd control (no damage), so instead their chance is speed-normalised by the weapon’s intrinsic interval — procChance = min(1, 0.10 × weaponInterval) — giving equal CC uptime per second on fast and slow weapons. Freeze applies COLD_FREEZE_ATTACK_SPEED_REDUCTION = 0.30; Stun sets the enemy action-speed factor to 0 for its duration.
Worked example — a 200 fire-damage hit
Suppose your flat fire damage is 200 and you land a hit that rolls an Ignite (10% chance):
totalIgnite = 200 × 0.25 = 50fire damage over 6 s (before resistance).dotPerSecond = 50 / 6 ≈ 8.33, and withDOT_TICK_INTERVAL_SECONDS = 0.5each tick deals8.33 × 0.5 ≈ 4.17, i.e. 12 ticks of ~4.17 across the 6 seconds.- Against an enemy with 40% fire resistance, the whole DoT is scaled by
(1 − 0.40):50 × 0.60 = 30total, ~2.5 per tick.
The instant fire portion of that same swing (200 × (1 − 0.40) = 120) lands separately and immediately; the 50-point (pre-resist) Ignite is the DoT rider stacked on top. Multiple ignites stack in parallel — a fresh proc does not refresh the old one.
DoT stacking
Multiple damage-over-time instances stack — applying a new ignite, poison, or bleed does not refresh or overwrite an existing one. Each ticks down in parallel. Note that on multi-hit attacks (such as Zeal), the elemental damage applies on every hit, but a status proc (and Crushing Blow) rolls only on the first hit.