Skip to content

Ailment Model

Summary: Ailments are status effects that deal damage of an existing damage type — they are NOT damage types themselves and NEVER get resistances of their own. This document exists so the inheritance model survives contributor turnover: do not add ResistanceBleed or ResistancePoison.


The Inheritance Rule

Project Eternal follows the PoE ailment model: each ailment applies a DoT (or debuff) of an underlying damage type and inherits that type's mitigation.

Ailment Underlying type Mitigated by DoT?
Status.Bleed Physical — (see below) Yes
Status.Ignite Fire ResistanceFire Yes
Status.Poison Corruption ResistanceCorruption Yes
Status.Shock Electric n/a — debuff that reduces all elemental resistances No

Corruption resistance IS the poison resistance. Adding a separate ResistancePoison would either double-dip with ResistanceCorruption or contradict the inheritance rule. Same logic for ResistanceBleed vs armor. If you find yourself adding a per-ailment resistance attribute, stop and re-read this document.

Why Bleed bypasses armor (deliberate)

Armor defends against hits (ExecCalc_Damage). DoTs — including Bleed's physical ticks — skip armor entirely (ExecCalc_DamageOverTime). This is PoE-faithful and intentional:

  • A heavy-armor character is NOT automatically safe from bleed. Ailment pressure stays threatening regardless of hit mitigation.
  • Bleed defense becomes its own itemization decision (the taken-line below), which is exactly the "defense choices are build choices" texture the itemization pillar wants.

The Four Ailment Modifier Axes

Axis Side Mechanism
Chance to inflict Source BleedChance / IgniteChance / PoisonChance / ShockChance (0-100%), rolled by UOnHitAbility
Duration inflicted Source IncreasedStatusDuration (additive %), consumed when the proc's GE spec is built
Damage dealt Source IncreasedDamageOverTime + BleedDamageDealt / IgniteDamageDealt / PoisonDamageDealt on one additive line, applied on every tick
Damage taken Target BleedDamageTaken / IgniteDamageTaken / PoisonDamageTaken (additive %, negative = take less), applied on every tick

All four follow the GDD's single-additive-line rule (Flat / Increased / Reduced — no More/Less multiplier tier). A planned fifth axis — reduced status duration on self ("of Shrugging") — is tracked as its own backlog task.

Per-type Increased* buckets do NOT apply to ticks. Procs seed their tick damage from the post-Increased hit, so re-applying the per-type bucket in the DoT exec made "+50% Physical Damage" secretly worth ~+125% on bleed ticks — the hit→ailment double-dip PoE removed. DoTs scale through their own vocabulary instead: IncreasedDamageOverTime (all DoTs) + the per-ailment dealt-line (this ailment only). This is what gives Feral Dual-Wield / Dread Channeler builds scaling knobs that other builds don't also want.

How the dealt-line selects its attribute

Mirror of the taken-line: ExecCalc_DamageOverTime reads the Status.* asset tag on the executing GE and joins the matching *DamageDealt attribute onto IncreasedDamageOverTime's additive line, applied once per tick:

Tick *= max(0, 1 + (IncreasedDamageOverTime% + AilmentDealt%) / 100)

Authoring modifiers against the dealt-line

Item modifiers target the tags with operation Flat (the attribute holds the summed %):

  • Stats.Offensive.AilmentDealt.Bleed
  • Stats.Offensive.AilmentDealt.Ignite
  • Stats.Offensive.AilmentDealt.Poison

An offensive prefix rolls positive values (e.g. "Hemorrhaging", +25% Bleed damage). No Shock entry — Shock is not a DoT.

How the taken-line selects its attribute

ExecCalc_DamageOverTime reads the Status.* asset tag on the executing GE (GE_Bleed carries Status.Bleed, etc.) and applies the matching *DamageTaken attribute once to the tick:

Tick *= max(0, 1 + TakenPercent / 100)

Keying by status tag (not damage type) means non-ailment DoTs — ground hazards, future channeled degens — are untouched, and positive rolls ("+% bleed damage taken" curses) work for free.

Authoring modifiers against the taken-line

Item modifiers target the tags with operation Flat (the attribute holds the summed %):

  • Stats.Defensive.AilmentTaken.Bleed
  • Stats.Defensive.AilmentTaken.Ignite
  • Stats.Defensive.AilmentTaken.Poison

A defensive suffix rolls negative values (e.g. "of Stanching", −15% Bleed damage taken). No Shock entry: Shock is a resistance debuff, not a DoT — its counterplay is dispel/avoidance, not a damage-taken stat.


Source Reference

What Where
Taken-line application Source/ProjectEternal/Private/AbilitySystem/ExecCalc/ExecCalc_DamageOverTime.cpp
Attributes Source/ProjectEternal/Public/AbilitySystem/EternalAttributeSet.h ("Ailment Damage Taken")
Tags Source/ProjectEternal/Private/EternalGameplayTags.cpp (Stats.Defensive.AilmentTaken.*)
Damage pipeline Damage Execution
Headless power model EternalDoTMath (pure tick kernel + ComputeAilmentDPS stacking) → UBuildEvaluatorLibrary; reference-tested by ProjectEternal.Unit.Combat.DoTMath
Backlog origin FSH-307 — "Audit ailment mitigation"