Unless stated otherwise, everything here is Diablo II: Resurrected build 3.3.93847, Reign of the Warlock.
Unless stated otherwise, everything here is Diablo II: Resurrected build 3.3.93847, Reign of the Warlock.

Elemental damage never rolls to hit and never meets defense: a spell that reaches its target does its number, and the only things between the number and the monster's life are the multipliers on your side and the resistance on theirs. There are three multipliers and they do not overlap.
damage dealt = skill damage × (1 + skill damage % + mastery %) × (100 − (monster resist − pierce)) ÷ 100
Pierce is worth more the closer the monster is to immune: taking a monster from 75% to 50% resistance doubles the damage that gets through, while +25% skill damage on the same monster adds a quarter.
A monster at 100% or more is immune and takes nothing until the immunity is broken (Resistances and Immunities): against an immune, Conviction and Lower Resist count for a fifth of their value and item pierce for nothing, and a sunder charm sets the resistance to 95% first. Once the monster is under 100, every reduction counts in full, down to the −100% floor, where it takes double damage.
Pierce that goes past the floor is wasted: a monster already at −100% cold resistance gains nothing from more Cold Mastery. Past that, only skill damage and masteries add anything.
Poison is a rate over time: the skill's damage is spread over its length, and poison resistance cuts the rate while Poison Length Reduced on the target cuts the time. See Poison Damage.
What reaches a player goes through the defender's chain in Taking Damage: Energy Shield first, then resistance, then absorb, which heals what it takes. Against a player the number is multiplied by 17% before any of that (Player versus Player).
Written from the game's tables (build 3.3.93847) and the cited pages; a per-level table is computed from skills.txt and skilldesc.txt by the same evaluator the skill pages use. A “legacy rule” is a published engine rule no table proves; a “game table” is read from the table named. · Report incorrect data