Section 04·WoW Combat Log Reference

Damage & Healing

Field positions for SPELL_DAMAGE, SWING_DAMAGE, ENVIRONMENTAL_DAMAGE, SPELL_HEAL, and SPELL_ABSORBED. The actual damage and healing formulas. The cheat-death exclusion list.

This page documents how damage and healing get encoded, and the formulas that produce numbers matching the de-facto community standard. All field positions assume advanced combat logging is enabled.

SPELL_DAMAGE Suffix

SPELL_DAMAGE, SPELL_PERIODIC_DAMAGE, RANGE_DAMAGE (and their _SUPPORT variants) all use this suffix at fields 31+. Total field count: 42. The advanced block (12–30) describes the target for these events.

FieldNameDescription
31baseAmountEffective damage post-mitigation. The number you want.
32rawAmountPre-mitigation. Diagnostics only — do not sum this.
33overkillDamage past 0 HP. -1 if not a killing blow.
34schoolSchool bitfield (duplicates spell school for compatibility)
35resistedResisted amount (partial resists)
36blockedBlocked amount
37absorbedInformational. Use the SPELL_ABSORBED event, not this field.
38critical1 on crit, nil otherwise
39glancingLegacy, basically always nil now
40crushingLegacy, basically always nil now
41abilityHintString tag — ST (single-target) or AOE. Useful for filtering ST vs cleave performance.

SWING_DAMAGE Suffix

No spell prefix, so offsets shift -3. Total field count: 38 (or 39 if off-hand). The advanced block (9–27) describes the source for SWING_DAMAGE and the target for SWING_DAMAGE_LANDED — they're the same swing logged twice.

FieldNameDescription
28baseAmountEffective damage post-mitigation
29rawAmountPre-mitigation, diagnostics only
30overkill-1 if not killing
31schoolAlways 0x1 (physical) for swings
32resisted
33blocked
34absorbedInformational; use SPELL_ABSORBED to count
35critical1 on crit, nil otherwise
36glancingLegacy, always nil
37crushingLegacy, always nil
38 (optional)isOffHand1 for off-hand swings; field is omitted entirely for main-hand swings

Critical: SWING_DAMAGE_LANDED is not a separate hit. It's the same auto-attack reported again with the target's advanced block instead of the source's. Counting both SWING_DAMAGE and SWING_DAMAGE_LANDED doubles every melee swing.

ENVIRONMENTAL_DAMAGE Suffix

The advanced block comes first in this event, then the environmental type, then the damage suffix. The source GUID is always 0000000000000000 (no actor — the world did it):

FieldNameDescription
1–4sourceAlways 0000000000000000, name nil, generic flags
5–8targetThe player taking damage
9–27Advanced loggingThe 19-field block (describes target — the player who got hurt)
28environmentalTypeFalling, Lava, Fire, Slime, Drowning, Fatigue
29baseAmountEffective damage
30rawAmountPre-mitigation
31overkill0 or positive if killing, -1 otherwise
32school
33resisted
34blocked
35absorbed
36–38crit / glancing / crushingUsually nil

When a player dies from a knockback or platform fall, this is the event that records it. Death analysis pipelines that only look at SPELL_DAMAGE / SWING_DAMAGE will silently miss those deaths.

Empirical note: This layout was verified against real M+ and raid logs. Total field count is 39. The environmentalType string lives at field 28 — after the advanced block, not before it.

SPELL_HEAL Suffix

SPELL_HEAL and SPELL_PERIODIC_HEAL:

FieldNameDescription
31healedToHPRaw heal minus shield-converted portion. Don't use for totals.
32amountTotal healing including overheal. Use this.
33overhealWasted healing (already at full HP).
34absorbedToShieldHeal converted to a shield (Atonement, Pain and Gain). Already inside amount.
35critical1 on crit

SPELL_ABSORBED — The Three-Way Event

SPELL_ABSORBED records "an attack happened, but a shield ate it." It encodes three or four entities: attacker, defender, absorber (the shield-caster, sometimes the same as the defender), and the shield spell. It comes in two formats depending on whether the absorber is the same as the defender:

Format 1: 22 fields — shield on someone else

RangeContent
1–4Attacker (GUID, name, flags, raid flags)
5–8Defender
9–11Damage spell info
12–15Absorber (the shield-caster)
16–18Absorb spell info (the shield)
19amount — amount absorbed
20totalAmount — full attempted damage before absorb
21critical1 if the absorbed hit would have crit, nil otherwise

Format 2: 19 fields — self-shielded

RangeContent
1–4Attacker
5–8Defender
9–12Absorber (= defender)
13–15Absorb spell info
16amount — amount absorbed
17totalAmount — full attempted damage before absorb
18critical1 if the absorbed hit would have crit, nil otherwise

Your parser has to count the fields to figure out which format it is. There is no header to disambiguate.

The Damage Formula

effectiveDamage = max(0, baseAmount + blocked + resisted - max(0, overkill))
  • Overkill IS subtracted. Effective damage delivered, not raw damage rolled. One-shot a 1M HP boss for 5M = 1M counted, not 5M.
  • overkill = -1 means "didn't kill." Treat negative as zero before subtracting.
  • Don't add the absorbed field. It's informational; the absorbed damage already lives in a separate SPELL_ABSORBED event with its own amount. Adding both double-counts partial absorbs.
  • Add blocked and resisted. They were dealt; the target just mitigated them.

The Healing Formula

effectiveHealing = max(0, amount - overheal)
  • Don't subtract absorbedToShield. That portion was real healing converted into a shield buff; it counts.
  • Some "absorbs" are not healing. Cheat-death and Stagger-style mechanics get logged as SPELL_ABSORBED but should NOT be added to healing totals:
Spell IDNameClass/SpecWhy excluded
114556PurgatoryBlood Death KnightOne-shot save mechanic, not healing
31850Ardent DefenderProtection PaladinSame — damage prevention on lethal hits
31230Cheat DeathSubtlety RogueSame
115069StaggerBrewmaster MonkDelayed self-damage, not a shield. The "absorbed" amount ticks back as damage. Counting it inflates Brewmaster healing by ~95% on tank logs.

Pet Damage Attribution

Pet damage gets credited to the owner. Three signals, ranked by reliability:

PrioritySignalWhy it can be wrong
1 (best)SPELL_SUMMON eventAuthoritative — you saw the player summon the pet
2ownerGUID in advanced loggingReliable but absent if advanced logging is off
3 (worst)Player buff aura on the petWrong for raid-wide auras

You will see pet damage before you see the SPELL_SUMMON. Pets summoned before combat (warlock demons, hunter pets, DK ghouls) start dealing damage immediately, and ownership data arrives later. The right architecture: buffer unknown-owner pet damage and retroactively reassign when the owner is discovered. Get this wrong and warlocks parse 30% lower than they should.

Citing this page

If this reference helped, please link back so others can find it. Suggested citation:

Damage & Healing — WoW Combat Log Reference (WowCoach.gg). https://wowcoach.gg/docs/combat-log/damage-and-healing