D2R Experience Calculations — Reference

This document explains how Diablo II: Resurrected calculates experience, what every formula in the calculator's engine does, and why the results look the way they do. The reference authorities for these formulas are the game's internal data files (monstats.txt, monlvl.txt, levels.txt), Pavke's meticulously verified experience calculator spreadsheet, and The Amazon Basin wiki.

Table of Contents


Core Concepts

Diablo II awards experience when monsters are killed. The amount of XP received from a single kill depends on the monster's base stats, the monster's effective level, the character's level, the number of players in the game, party composition, and several multiplicative bonuses and penalties.

The relationship between character level and XP gain is not smooth. Three distinct penalty systems — level difference, high level, and Classic difficulty — work together to make leveling progressively harder. At level 98, a character receives less than 1% of the raw monster XP. This is why understanding the exact formulas matters: small differences in area level, player count, or monster composition can have outsized effects at high levels.

The central question the calculator answers is: "Given my character level, difficulty, player/party settings, and target area, how much XP will I gain per clear, and how many runs will it take to reach the next level?"

Terminology

TermFull NameDescription
clvlCharacter LevelThe killing character's level (1–99)
mlvlMonster LevelThe monster's effective level for penalty calculations (includes type bonuses)
Base XPBase ExperienceA monster's raw XP value from monstats.txt for the current difficulty
Scaling LevelScaling LevelThe monster level used for the monlvl.txt XP scaling lookup (no type bonuses)
Penalty LevelPenalty LevelThe monster level used for level difference penalty (includes type bonuses)
Area LevelArea LevelThe level assigned to an area for a given difficulty (from levels.txt MonLvlEx columns)
monlvl ScalingMonster Level XP ScalingThe XP multiplier from monlvl.txt keyed by monster level and difficulty
Type MultiplierMonster Type XP MultiplierThe XP bonus based on monster type (1×, 3×, or 5×)
Party SplitParty Level SplitYour share of party XP based on relative character levels

Game Data Files

The calculator draws from several of the game's internal data files:

FileWhat It Provides
monstats.txtBase XP per monster (Exp, Exp(N), Exp(H)) and per-monster levels (Level, Level(N), Level(H))
monlvl.txtXP scaling factors by monster level and difficulty (L-XP, L-XP(N), L-XP(H))
levels.txtArea levels per difficulty (MonLvlEx, MonLvlEx(N), MonLvlEx(H)) and monster spawn lists
desecratedzones.jsonTerror Zone definitions, level boost (+2), and XP bonus (25%)

The Calculation Pipeline

Every monster kill passes through the same sequence of steps. Each step takes the output of the previous step and applies one transformation. The game uses integer arithmetic throughout — results are floored after every operation.

Step 1: Base XP Lookup

Every monster has a base XP value defined in monstats.txt. Each difficulty has its own column:

Difficultymonstats.txt Column
NormalExp
NightmareExp(N)
HellExp(H)

For example, a Fallen in Normal might have Exp = 6, while in Hell it might have Exp(H) = 564.

Step 2: Terror Zone and Event Bonuses

In Terror Zones, the base XP receives a flat 25% bonus. During seasonal events (e.g., 22 Nights of Terror), an additional event bonus of up to 25% stacks additively with the Terror Zone bonus:

bonusedBaseXP = floor(baseXP × (1 + terrorZoneBonus + eventBonus))

Where:

  • terrorZoneBonus = 0.25 if the area is terrorized, 0 otherwise
  • eventBonus = event percentage / 100 (0 to 0.25), only if terrorized

In non-terrorized areas, the base XP is unchanged.

Step 3: Monster Level Scaling

The (possibly bonused) base XP is scaled by a factor from monlvl.txt based on the monster's scaling level (see Monster Level Resolution):

levelScaledXP = floor(bonusedBaseXP × monlvlScaling / 100)

The monlvlScaling value is looked up from the L-XP (Normal), L-XP(N) (Nightmare), or L-XP(H) (Hell) column of monlvl.txt at the row matching the monster's scaling level.

Classic Mode Penalty: In Classic, an additional difficulty penalty is applied after scaling:

  • Normal: no penalty
  • Nightmare: floor(levelScaledXP × 10 / 17)
  • Hell: floor(levelScaledXP × 10 / 27)

Step 4: Monster Type Multiplier

The scaled XP is multiplied based on the monster's type:

Monster TypeMultiplierNotes
Normal×1No bonus
Champion×313/15 of champion spawns (see Berserker Weighting)
Berserker (Champion variant)×52/15 of champion spawns
Unique×5Unique boss monsters and their minions
Minion×5Minions of Unique bosses
Super Unique×5Named bosses (e.g., Bishibosh, Pindleskin)
Boss (Act Bosses)×1Andariel, Duriel, Mephisto, Diablo, Baal, etc.

Special Bosses: Griswold, Radament, and Nihlathak receive the ×5 multiplier (treated as Unique) because they spawn with random monster enchantments (e.g., Cold Enchanted, Lightning Enchanted).

scaledMonsterXP = levelScaledXP × typeMultiplier

Step 5: Player Count Bonus

More players in the game increases XP. The formula is:

playerBonusXP = floor(scaledMonsterXP × (playersInGame + 1) / 2)

This produces the following multipliers:

PlayersMultiplier
1×1.0
2×1.5
3×2.0
4×2.5
5×3.0
6×3.5
7×4.0
8×4.5

Step 6: Party Bonus

When you are in a party with other players nearby (within ~2 screen widths), bonus XP is generated. The party bonus is calculated from the player bonus:

partyBonusXP = floor(playerBonusXP × 89 × (partySize - 1) / 256)

The factor 89/256 ≈ 34.8% bonus per additional party member was verified against Pavke's spreadsheet. When solo (partySize = 1), the party bonus is zero.

Step 7: Party Split

The combined player and party XP is split among party members in proportion to their character levels:

partySplit = characterLevel / (characterLevel + sumOfOtherPartyMemberLevels)

When solo, partySplit = 1.0 (you receive everything).

Step 8: XP Cap

The party-adjusted XP is capped at 8,388,607 (2²³ − 1) per kill:

partyAdjustedXP = min(8388607, floor((playerBonusXP + partyBonusXP) × partySplit))

This cap is almost never reached in practice, but exists as a hard limit in the game's code.

Step 9: Level Difference Penalty

This penalty reduces XP when fighting monsters whose level differs significantly from yours. It works differently depending on character level:

Characters Below Level 25

Uses a fixed lookup table (the Low-Level Penalty Table) keyed by mlvl - clvl. The level difference is clamped to the range −10 to +10. Each entry is a fraction with denominator 256:

if partyAdjustedXP > 1,048,576:
    levelPenalizedXP = floor(partyAdjustedXP / 256) × penaltyValue
else:
    levelPenalizedXP = floor(partyAdjustedXP × penaltyValue / 256)

Penalties apply in both directions — killing monsters too far above or below your level reduces XP. From −5 to +5, no penalty is applied (penaltyValue = 256, i.e. 100%).

Characters Level 25 and Above

Two cases:

Monster level > character level:

if partyAdjustedXP > 1,048,576:
    levelPenalizedXP = floor(partyAdjustedXP / mlvl) × clvl
else:
    levelPenalizedXP = floor(partyAdjustedXP × clvl / mlvl)

This applies the ratio clvl / mlvl directly — the further above you a monster is, the less XP you get.

Monster level ≤ character level:

Uses the Mid-Level Penalty Table, keyed by mlvl - clvl (clamped −10 to 0). Applied the same way as the low-level table (fraction with denominator 256).

Note: For characters level 25+, there is no penalty for fighting monsters above your level using the table — the clvl / mlvl ratio handles that case instead. This means at level 25+, killing higher-level monsters never gives more than 100% XP.

Step 10: High Level Penalty

Starting at character level 70, a severe penalty reduces XP dramatically. This is the primary reason leveling slows to a crawl at high levels.

The penalty is a lookup from the High Level Penalty Table, keyed by character level. Each entry is a fraction with denominator 1024:

if clvl >= 70:
    if levelPenalizedXP > 2,097,152:
        highLevelPenalizedXP = floor(levelPenalizedXP / 1024) × penaltyValue
    else:
        highLevelPenalizedXP = floor(levelPenalizedXP × penaltyValue / 1024)

For characters below level 70, no penalty from the table is applied. However, if the XP exceeds 1,048,576, it is rounded down to the nearest multiple of 1024:

if clvl < 70 and levelPenalizedXP > 1,048,576:
    highLevelPenalizedXP = floor(levelPenalizedXP / 1024) × 1024

At level 98, the penalty value is 6/1024 ≈ 0.59%. At level 99, the penalty is 5/1024 ≈ 0.49%, effectively making it impossible to gain meaningful XP.

Step 11: Final Bonuses

After all penalties, equipment and shrine bonuses are applied additively:

Bonus SourceBonus Range
Annihilus5–10%
Unique Jewel (with XP mod)1–5%
Ondal's Wisdom5%
Experience Shrine50%

The total bonus percentage is summed and applied:

totalBonusPercent = annihilus + jewel + ondals + shrine

if highLevelPenalizedXP > 1,048,576:
    bonusAmount = floor(highLevelPenalizedXP / 100) × totalBonusPercent
else:
    bonusAmount = floor(highLevelPenalizedXP × totalBonusPercent / 100)

finalXP = highLevelPenalizedXP + bonusAmount

Note that the bonus is added to the XP, not multiplied — it is xp + xp × bonus%, not xp × (1 + bonus%). The distinction matters because of the integer floor: only the bonus portion is floored, not the sum.


Monster Level Resolution

Determining a monster's level is the most complex part of the calculation. There are two distinct levels used for different purposes:

Scaling Level vs Penalty Level

  • Scaling Level: Used for the monlvl.txt XP scaling lookup (Step 3). This is the "base" monster level without type bonuses.
  • Penalty Level: Used for the level difference penalty (Step 9). This includes type bonuses (+2 for champions, +3 for uniques, etc.) and any special boss bonuses.

The distinction matters because the monlvl.txt scaling lookup uses one level, but the penalty calculation uses a different, inflated level.

Expansion Mode

Normal Difficulty

All monsters use their individual level from monstats.txt (Level column). Each monster type (Fallen, Zombie, etc.) has its own level that may differ from the area level.

Nightmare and Hell Difficulty

Most monsters use the area level from levels.txt (MonLvlEx(N) or MonLvlEx(H) column). Exceptions:

  • Act Bosses (Andariel, Duriel, Mephisto, Diablo, Baal, etc.): Use their monstats.txt level (Level(N) or Level(H))
  • Special Bosses (Griswold, Radament, Nihlathak): Use their monstats.txt level
  • Super Uniques: Use the area level (NOT monstats.txt — this is a key distinction)

Terror Zone Mode

Terror Zones scale monster levels with the creating character's level.

Normal Difficulty

terrorizedBase = min(45, clvl + 2)
scalingLevel = max(terrorizedBase, naturalLevel)

Because Normal difficulty always uses per-monster levels from monstats.txt, monsters can never go below their natural level — terrorization can only raise them.

Nightmare and Hell Difficulty

terrorizedBase = min(cap, max(areaLevel, clvl + 2))

Where cap is the per-difficulty normal cap (71 for Nightmare, 96 for Hell).

  • Regular monsters and Super Uniques: Use terrorizedBase directly
  • Act Bosses and Special Bosses: Use max(terrorizedBase, naturalLevel) — they can't go below their monstats.txt level

Classic Mode

Classic uses a completely different level scheme. All monsters use their monstats.txt Level column (Normal difficulty) with a flat offset:

DifficultyFormula
NormalLevel
NightmareLevel + 25
HellLevel + 50

The Level(N) and Level(H) columns and the area levels from levels.txt are ignored in Classic mode.

Type Bonuses for Penalty Level

After determining the scaling level, the penalty level adds a type-based bonus:

Monster TypeBonusNotes
Normal+0
Champion+2Berserker variant uses +3, see Berserker Weighting
Unique+3
Minion+3Minions of Unique bosses
Super Unique+3
Boss (Act Boss)+0In Expansion; +3 in Terror Zones
penaltyLevel = scalingLevel + typeBonus

The penalty level is globally capped at 99 (except for special bosses, see below).

Special Bosses

Griswold, Radament, and Nihlathak receive special treatment in two ways:

  1. XP Multiplier: They receive ×5 (treated as Unique) instead of the normal Boss ×1
  2. Penalty Level: They receive an additional +3 bonus on top of any existing type bonus

In Terror Zones, special bosses can exceed the normal level 99 cap for penalty purposes (e.g., penalty level 102 = 99 + 3).


Terror Zones

Level Caps

Terror Zone monster levels are capped by difficulty and monster type:

Monster TypeNormal CapNightmare CapHell Cap
Normal457196
Champion477398
Unique/Minion/Super/Boss487499

Note that the caps for Champions and Uniques are exactly +2 and +3 above the Normal cap, reflecting their type bonuses. This means at the cap, a level 96 character in Hell will have Normal monsters at 96, Champions at 98, and Uniques at 99.

XP Bonus

Terror Zones provide a flat 25% bonus to base XP before any other calculation. This stacks additively with event bonuses (up to 25% during seasonal events like 22 Nights of Terror):

bonusedBaseXP = floor(baseXP × (1 + 0.25 + eventBonus/100))

Boss Penalty Level in Terror Zones

Act Bosses in Terror Zones use a special formula for their penalty level that differs from the standard scalingLevel + typeBonus:

penaltyLevel = max(min(99, clvl + 5), scalingLevel)

This ensures terrorized bosses always have a penalty level at least clvl + 5 (capped at 99), even if their scaling level is lower. Special bosses (Griswold, Radament, Nihlathak) add their +3 on top of this result.


Champion Berserker Weighting

Champions spawn in five varieties: Champion, Fanatic, Ghostly, Possessed, and Berserker. Four varieties share the same XP behavior (×3 multiplier, mlvl+2 for penalties), but Berserkers are different (×5 multiplier, mlvl+3 for penalties).

The game spawns Berserkers with a 2/15 probability and the other four types with 13/15 probability. Because Berserkers use a different penalty level (+3 instead of +2), their XP can differ meaningfully from regular champions — especially at high character levels where the level difference penalty is steep.

The calculator computes champion XP as a weighted average of two complete, independent calculation paths:

regularChampionXP = calculateFullPipeline(baseXP, typeMultiplier=3, penaltyBonus=+2)
berserkerXP       = calculateFullPipeline(baseXP, typeMultiplier=5, penaltyBonus=+3)

championXP = (13/15) × regularChampionXP + (2/15) × berserkerXP

Each path runs through the entire pipeline independently (scaling, player bonus, party, penalties, bonuses) before the weighting is applied. This matters because the level difference penalty is non-linear — weighting the final results produces different numbers than weighting the multipliers and running a single path.


Super Unique Packs

Super Unique monsters (named bosses like Bishibosh, Pindleskin, Shenk) spawn with a pack of minions. The total XP for a pack is:

totalPackXP = bossXP + minionCount × minionXP

The minion count increases with difficulty:

DifficultyMinion Count Adjustment
NormalBase count
NightmareBase count + 1
HellBase count + 2

Normal Minion Exceptions: Most Super Unique minions receive the ×5 Minion multiplier and +3 penalty level bonus. However, two bosses have minions that score normal XP (×1 multiplier, +0 penalty bonus):

  • Shenk the Overseer (overseer1) — his minions are regular Enslaved
  • Nihlathak (nihlathakboss) — his minions are regular monsters

Area XP Aggregation

The calculator computes total XP per area by summing the weighted XP of every monster that spawns there:

areaXP = Σ(spawnCount × xpPerKill) for each monster type in the area

Spawn counts come from the game's area data and vary by difficulty. The calculation uses precision (unfloored) values during accumulation and rounds only at the final sum to minimize rounding error across many monster types.

For champions, the calculator uses the weighted Berserker average described above. For Super Uniques, it includes the full pack (boss + minions). For act bosses, individual XP is floored before multiplication by spawn count (they are known quantities, not statistical averages).


Integer Precision and Order of Operations

Diablo II uses 32-bit integer arithmetic internally. Because of this, the game changes the order of operations at certain thresholds to maintain precision:

ThresholdWhere UsedEffect
1,048,576 (2²⁰)Level difference penalty, rounding, final bonusesDivides first, then multiplies (instead of multiply-then-divide)
2,097,152 (2²¹)High level penaltySame precision swap

For example, the level difference penalty with a table value of P:

if xp > 1,048,576:
    result = floor(xp / 256) × P        // divide first for precision
else:
    result = floor(xp × P / 256)         // multiply first (standard)

These two formulas are mathematically equivalent for real numbers, but produce different results with integer floors. The game uses the version that minimizes precision loss for the given magnitude. The calculator replicates this behavior exactly.


Classic Mode Differences

Classic (non-expansion) mode has several differences from Expansion:

  1. Monster Levels: All monsters use their monstats.txt Level column value with a flat difficulty offset (+0/+25/+50). The Level(N), Level(H), and area level columns are ignored.

  2. Difficulty XP Penalty: After the monlvl scaling, Classic applies an additional penalty:

    • Normal: no penalty (×1)
    • Nightmare: ×10/17 ≈ 58.8%
    • Hell: ×10/27 ≈ 37.0%
  3. No Terror Zones: Terror Zones do not exist in Classic.

  4. Champion Berserker Weighting: In the standard Classic calculation, Berserker weighting is applied the same as Expansion. An alternative "test mode" exists that uses straight ×3 for all champions and does not convert special bosses to ×5.


Level Difference Penalty Tables

Low-Level Penalty Table (Character Level < 25)

Applied when clvl < 25. Keyed by mlvl - clvl, clamped to −10 to +10. Each value is divided by 256 to get the multiplier.

mlvl − clvlPenaltyEffective %
+1052%
+93815%
+89236%
+717468%
+622588%
+5 to −5256100%
−620781%
−715962%
−811043%
−96124%
−10135%

Mid-Level Penalty Table (Character Level ≥ 25, Monster Level ≤ Character Level)

Applied when clvl ≥ 25 and mlvl ≤ clvl. Keyed by mlvl - clvl (always ≤ 0), clamped to −10. Values divided by 256.

mlvl − clvlPenaltyEffective %
0256100%
−1256100%
−2256100%
−3256100%
−4256100%
−5256100%
−620781%
−715962%
−811043%
−96124%
−10135%

When clvl ≥ 25 and mlvl > clvl, the penalty is floor(xp × clvl / mlvl) — a direct ratio instead of a table lookup.


High Level Penalty Table

Applied when clvl ≥ 70. Each value is divided by 1024 to get the multiplier.

LevelPenaltyEffective %LevelPenaltyEffective %
7097695.3%8525625.0%
7192890.6%8619218.8%
7288085.9%8714414.1%
7383281.3%8810810.5%
7478476.6%89817.9%
7573671.9%90616.0%
7668867.2%91464.5%
7764062.5%92353.4%
7859257.8%93262.5%
7954453.1%94202.0%
8049648.4%95151.5%
8144843.8%96111.1%
8240039.1%9780.8%
8335234.4%9860.6%
8430429.7%9950.5%

From level 70 to 84, the penalty decreases by exactly 48 per level (4.7% per level). From 85 onward, the drops accelerate dramatically.


Appendix: Constants

XP Limits

ConstantValueDescription
XP Cap8,388,607Maximum XP per kill (2²³ − 1)
Level Cap99Maximum character and monster level (except special boss penalties)

Precision Thresholds

ThresholdValueDescription
Level Penalty Threshold1,048,576Order of operations changes above this (2²⁰)
High Level Penalty Threshold2,097,152Order of operations changes above this (2²¹)
Rounding Threshold1,048,576XP rounded to nearest 1024 when clvl < 70 and above this
Final Bonus Threshold1,048,576Order of operations changes for bonus calculation (2²⁰)

Terror Zone Constants

ConstantValue
Terror Zone XP Bonus25%
Terror Zone Level Boostclvl + 2
Normal Difficulty Cap (Normal/Champ/Unique)45 / 47 / 48
Nightmare Difficulty Cap (Normal/Champ/Unique)71 / 73 / 74
Hell Difficulty Cap (Normal/Champ/Unique)96 / 98 / 99

Party Constants

ConstantValueDescription
Party Bonus Factor89Numerator in party bonus formula
Party Bonus Denominator256Denominator in party bonus formula

Classic Mode Penalties

DifficultyPenaltyEffective %
Normal×1100%
Nightmare×10/1758.8%
Hell×10/2737.0%

Champion Spawn Weights

TypeWeightProbability
Regular Champion (×3, mlvl+2)1386.7%
Berserker (×5, mlvl+3)213.3%

Super Unique Minion Difficulty Bonus

DifficultyBonus to Minion Count
Normal+0
Nightmare+1
Hell+2

Special Bosses

These three monsters receive ×5 multiplier and +3 penalty level bonus (in addition to any type bonus):

  • Griswold
  • Radament
  • Nihlathak

Bosses with Normal-XP Minions

These Super Uniques have minions that score normal experience (×1 multiplier, +0 penalty bonus) instead of the usual minion experience (×5, +3):

  • Shenk the Overseer
  • Nihlathak

Reference

Based on game data files and The Amazon Basin Wiki.

Based on Pavke's experience calculator spreadsheet.