Back to Calculator

D2R IAS Calculations — Reference

This document explains how Diablo II: Resurrected calculates attack speed, what breakpoints are, and how every formula in the calculator's engine works. The reference authority for these formulas is the original IAS calculator's source code, which was reverse-engineered from the game's animation system.

Table of Contents


Core Concepts

Diablo 2's animations run at 25 frames per second. Every attack animation has a fixed number of frames per direction (FPD) determined by the character class and weapon type. The game speeds up or slows down this animation based on the character's total effective attack speed. Because the result is measured in integer frames, the relationship between IAS and attack speed is not smooth — it jumps at specific thresholds called breakpoints.

The central question the calculator answers is: "Given my character, weapon, skill, and modifiers, how many frames does each attack take, and how much more IAS do I need to reach the next breakpoint?"

Terminology

AbbreviationFull NameDescription
IASIncreased Attack SpeedTotal IAS from all gear except weapon-specific IAS
WIASWeapon IASIAS on the weapon itself (relevant for dual-wield)
GIASGear IASIAS from non-weapon gear when WIAS is being tracked separately
SIASSkill IASSpeed contribution from skills (Fanaticism, BoS, etc.) and debuffs
IEIASItem EIASThe effective IAS after applying the diminishing-returns conversion
EIASEffective IASThe final combined speed modifier: SIAS - WSM + IEIAS
WSMWeapon Speed ModifierIntrinsic speed of the weapon base (-30 to +20). Lower is faster.
FPDFrames Per DirectionBase frame count for the attack animation
FPAFrames Per AttackThe actual frame count after speed modification (what breakpoints show)

The EIAS Formula

All sources of attack speed ultimately combine into a single number: EIAS (Effective Increased Attack Speed). This is the number the game's animation engine actually uses.

IAS to EIAS Conversion (Diminishing Returns)

IAS does not scale linearly. The conversion from IAS to EIAS uses:

IEIAS = floor(120 * IAS / (120 + IAS))

This creates diminishing returns:

IASIEIASMarginal gain per 20 IAS
00
2017+17
4030+13
6040+10
8048+8
10054+6
12060+6

At 120 IAS you've only gained 60 EIAS. The formula asymptotically approaches 120 EIAS but never reaches it.

The inverse conversion (EIAS back to IAS) is:

IAS = ceil(120 * EIAS / (120 - EIAS))

Single-Weapon EIAS

For standard (non-dual-wield) attacks:

EIAS = SIAS - WSM + floor(120 * (GIAS + WIAS) / (120 + GIAS + WIAS))

Where:

Dual-Wield EIAS

When dual-wielding with sequence/dual-wield skills (Frenzy, Dragon Claw, Double Swing, etc.), the formula changes to average both weapons:

WSM = (WSM1 + WSM2) / 2
IEIAS = (floor(120 * (GIAS + WIAS1) / (120 + GIAS + WIAS1)) + floor(120 * (GIAS + WIAS2) / (120 + GIAS + WIAS2))) / 2
EIAS = floor(SIAS - WSM + IEIAS)

Note: The WSM averaging and IEIAS averaging both use the unrounded intermediate values. Only the final EIAS is floored (using the trun function, which floors positive numbers and ceils negative numbers).

EIAS Limits

EIAS is clamped before use:

FormMinimumMaximum
Human-8575
Wereform (Werewolf/Werebear)-85150

The higher wereform cap exists because wereforms apply a speed reduction factor that counteracts the higher EIAS range. The practical speed achievable is similar.

Animation Speed and Frame Count

Once EIAS is known, the game calculates how many frames the attack takes.

Base Animation Speed

Most attacks use a base animation speed of 256. Exceptions:

ConditionAnimation Speed
Default256
Laying Traps128 (half speed)
Claw (non-charge-up, non-kick) with 12 FPD227
Claw (non-charge-up, non-kick) with other FPD208
Druid Kick with One-Handed Swinging / Two-Handed Sword224

Human Form Speed Calculation

For human form characters, the speed increase is:

speedIncrease = floor(animationSpeed * (100 + clamp(EIAS)) / 100)

Then the frame count is:

FPA = ceil(256 * (FPD - startingFrame) / speedIncrease) - offset

Where:

Wereform Speed Calculation

Wereforms use a fundamentally different formula. Instead of a simple percentage, they apply a speed reduction factor:

speedReduction = fpdWereform / fpdHuman
speedIncrease = floor((animationSpeed + floor(animationSpeed * clamp(EIAS) / 100)) * speedReduction)

Where:

This means wereforms have a multiplier on their speed that depends on the ratio between their wereform frames and the human frames for that weapon. Weapons with high human FPD give wereforms a proportionally larger speed reduction.

What Breakpoints Are

Because FPA is an integer (you can't have fractional frames), the relationship between EIAS and attack speed is a step function. The FPA stays constant across a range of EIAS values, then drops by 1 at a specific threshold.

For example, an Amazon with a Phase Blade might see:

IASFPA
011
610
169
308
527
896

The breakpoint at IAS 6 means: any IAS from 0-5 gives 11 FPA, but 6+ gives 10 FPA. There is no benefit to having 5 IAS — you need to hit exactly 6 to gain a frame. This is why the calculator exists — to tell you the exact thresholds so you don't waste gear affixes on IAS that doesn't reach the next breakpoint.

How the Calculator Finds Breakpoints

The engine iterates over every possible acceleration value from 0 (or -85 for EIAS mode) to the maximum allowed value, computes the resulting frame count at each step, and records only the values where the frame count changes. Those change points are the breakpoints.

Skill Categories

Standard Skills

Skills that use the weapon's normal attack animation: Standard Attack, Concentrate, Berserk, Bash, Stun, Sacrifice, Vengeance, Conversion, Tiger Strike, Cobra Strike, Phoenix Strike, Feral Rage, Rabies.

These use the weapon type's FPD directly from the animation data tables. Some characters have alternate attack animations (e.g., Amazon with swords has two different swing animations that alternate).

Sequence Skills

Multi-frame skills with hardcoded frame counts that differ from the weapon's normal animation:

SkillSequence FPD
Jab18 (thrusting) / 21 (other)
ImpaleSame as Jab
Fists of Fire / Claws of Thunder / Blades of Ice12 (claw/unarmed) / 16 (other or dual-wield)
Dragon Claw12 (claw/unarmed) / 16 (other)
Double Swing / Frenzy17
Double Throw12

Rollback Skills

Multi-hit skills where each successive hit starts from a "rolled back" animation frame, making later hits faster than the first:

SkillHitsRollback FactorFinal Hit Uses
Zeal1 rollback hit + final100% (no rollback)FPD2
Dragon Talon1 rollback hit + final100% (no rollback)FPD2
Fury3 rollback hits + final70%FPD2
Strafe4 rollback hits + final50%FPD2
Fend4 rollback hits + final30%FPD2

The rollback calculation is iterative:

For each hit after the first:
  rollback = trun(trun((256 * previousRollback + speedIncrease * previousHitLength) / 256) * ((100 - rollbackFactor) / 100))
  hitLength = ceil(256 * (FPD1 - rollback) / speedIncrease)

Final hit:
  hitLength = ceil(256 * (FPD2 - lastRollback) / speedIncrease) - 1

Where FPD2 is the "second phase" frame count (weapon-type-dependent, used for the finishing animation).

The result is displayed as a formatted string like (4)+3+5 where:

Strafe and Fend generate two breakpoint tables: one for even arrow/hit counts and one for odd counts, because the oscillating even/odd behavior produces different timings.

Whirlwind

Whirlwind is unique in several ways:

  1. Uses truncation (floor) instead of ceiling for frame calculation:
    FPA = floor(256 * (actionFrame - startingFrame) / speedIncrease)
    
  2. Uses the weapon type's action frame instead of FPD
  3. Barbarian Two-Handed Swords are always treated as One-Handed Swinging for Whirlwind
  4. When dual-wielding, two independent tables are generated and then merged into a combined effective-speed table (see Dual-Wield Mechanics)

Special Skills

SkillBehavior
KickFixed 13 FPD (Assassin) or 12 FPD (other characters). Used for kicking barrels/objects.
Dodge/Avoid/EvadeFixed 9 FPD, always uses Fanaticism as the table variable. Independent of weapon.
Laying TrapsFixed 8 FPD, half animation speed (128 instead of 256).
SmiteFixed 12 FPD.
Dragon TailStandard FPD but with a -40 SIAS penalty.
Dragon TalonFixed 4-frame action frame, rollback with 100% factor (1 hit + final).

Dual-Wield Mechanics

When Dual-Wield Is Available

Dual-Wield-Only Skills

Dragon Claw, Double Swing, Frenzy, and Double Throw require dual-wielding. When these skills are selected, the IAS table variable is hidden and replaced with Primary/Secondary Weapon IAS.

WSM and IEIAS Averaging

For dual-wield sequence skills (Fists of Fire, Claws of Thunder, Blades of Ice, Dragon Claw, Double Swing, Frenzy, Double Throw), both weapons' WSM and IEIAS values are averaged:

effectiveWSM = (primaryWSM + secondaryWSM) / 2
effectiveIEIAS = (IEIAS_primary + IEIAS_secondary) / 2

This means a fast off-hand weapon partially compensates for a slow main-hand weapon.

Whirlwind Dual-Wield Merge

Whirlwind with two weapons generates three tables:

  1. Primary weapon table — Breakpoints for the main-hand weapon alone
  2. Secondary weapon table — Breakpoints for the off-hand weapon alone
  3. Merged table — Combined effective speed

The merge algorithm:

  1. Takes the first breakpoint from each table
  2. Averages their FPA values (ceiling)
  3. Sorts all remaining breakpoints by acceleration threshold
  4. For each subsequent breakpoint, updates the corresponding hand's FPA and recomputes the average
  5. Only records a merged breakpoint when the new average is strictly lower than the previous

The merged table uses the EIAS values from the slower weapon (the one with higher EIAS, since that weapon determines the bottleneck).

Note: The merge algorithm is a simplification. It doesn't consider all possible combinations of frame values more than 1 frame apart. For edge cases, manual combination is required.

Wereform Speed Reduction

When a character is in Werewolf or Werebear form, the game uses different base FPD values:

WereformFPD1FPD2FPD3
Werewolf13913
Werebear121012

Special overrides:

The speed reduction ratio FPD3 / FPDhuman is applied as a multiplier on the animation speed, effectively making wereform attacks slower with weapons that have fast human-form animations and faster with weapons that have slow human-form animations.

Attack Speed Skills

These skills provide EIAS bonuses using a diminishing-returns formula:

Standard Formula

For Fanaticism, Burst of Speed, Werewolf, and Frenzy:

bonus = min(minBonus + floor(factor * floor(110 * level / (level + 6)) / 100), maxBonus)
SkillMinFactorMaxExample (level 20)
Fanaticism10304010 + floor(30 * floor(110 * 20 / 26) / 100) = 10 + floor(30 * 84 / 100) = 10 + 25 = 35
Burst of Speed15456015 + floor(45 * 84 / 100) = 15 + 37 = 52
Werewolf10708010 + floor(70 * 84 / 100) = 10 + 58 = 68
Frenzy050500 + floor(50 * 84 / 100) = 42
Holy Freeze25355025 + floor(35 * 84 / 100) = 25 + 29 = 54 → capped at 50

Maul Formula

Maul uses a different formula:

bonus = factor * (floor(level / 2) + 3)

With factor = 3, this gives:

Skill Predicates

Attack speed skills only apply when their conditions are met:

When a skill is selected as the table variable (the X-axis of the breakpoint table), its EIAS contribution is excluded from the base calculation and instead varied across the table rows. This lets you see breakpoints as a function of that skill's level.

Debuffs

Debuffs reduce SIAS (applied additively before the EIAS formula):

DebuffSIAS Reduction
Decrepify-50 (not applied to Dodge)
Chilled-50
Slowed By-N (variable, user-entered)
Holy FreezeLevel-based (see formula above)
Mark of Bear+25 (bonus, player characters only)

Skill-Specific SIAS Adjustments

Some skills have built-in SIAS modifiers:

SkillSIAS Adjustment
Double Swing+20
Dragon Tail-40
Jab, Fists of Fire, Claws of Thunder, Blades of Ice, Dragon Claw, Frenzy, Double Throw-30 (player characters only)

Table Variables

The breakpoint table's left column (the "variable") can display different values depending on what the user wants to optimize for:

Table VariableDescriptionRange
EIASRaw EIAS value-85 to 75 (150 for wereforms)
IASTotal IAS from gear0 to 88 (83 for 2H, 78 for mercs)
Primary Weapon IASIAS on main-hand weapon0 to 120
Secondary Weapon IASIAS on off-hand weapon0 to 120
FanaticismFanaticism skill level0 to 60
Burst of SpeedBurst of Speed skill level0 to 60
WerewolfWerewolf skill level0 to 60
MaulMaul skill level0 to 60
FrenzyFrenzy skill level0 to 60

When a skill-based table variable is selected, the breakpoint table shows skill levels on the left and FPA on the right. The conversion from internal EIAS breakpoints to skill levels uses the inverse of the attack speed skill formula (a reverse lookup table built at initialization).

WIAS Conversion

Converting internal EIAS breakpoints to WIAS values requires working backward through the dual-wield averaging formula:

neededIEIAS = 2 * neededEIAS - 2 * SIAS + WSM1 + WSM2 - IEIAS_otherHand
neededWIAS = convertEIAStoIAS(neededIEIAS) - GIAS

This is the most complex conversion because it must account for the other hand's contribution.

URL Sharing Format

The ?data= query parameter encodes the full calculator state as a - separated string with spaces converted to underscores. The 20 fields in order:

#FieldTypeExample
1Characterint (0-10)2 (Barbarian)
2Wereformint (0-2)0 (Human)
3Primary WeaponstringPhase_Blade
4Primary WIASint0
5Is One-Handedbool (0/1)0
6Secondary WeaponstringNone
7Secondary WIASint0
8SkillstringWhirlwind
9Table Variableint (0-8)1 (IAS)
10IASint0
11Fanaticismint0
12Burst of Speedint0
13Werewolfint0
14Maulint0
15Frenzyint0
16Mark of Bearbool (0/1)0
17Holy Freezeint0
18Slowed Byint0
19Decrepifybool (0/1)0
20Chilledbool (0/1)0

Example URL:

?data=2-0-Phase_Blade-0-0-None-0-Whirlwind-1-0-0-0-0-0-0-0-0-0-0-0

This format is identical between the original calculator and this rewrite. Links generated by either calculator will load correctly in both.

Appendix: Constants and Limits

EIAS Bounds

ParameterValue
Minimum EIAS-85
Maximum EIAS (human)75
Maximum EIAS (wereform)150

IAS Iteration Limits

These define how far the calculator iterates when generating breakpoint tables:

Table VariableMax Value
Character IAS (one-hand/barbarian)88
Character IAS (two-handed)83
Mercenary IAS78
Weapon IAS60 (iteration) / 120 (display cap)
Skill levelsSkill-specific max

The trun Function

The engine uses a custom truncation function that matches Diablo 2's internal integer math:

function trun(n: number): number {
  if (n === -0) n = 0;
  return n >= 0 ? Math.floor(n) : Math.ceil(n);
}

This truncates toward zero (positive numbers floor, negative numbers ceil), matching C-style integer division. The -0 check prevents IEEE 754 negative-zero from affecting comparisons.