This is a short public summary. The full audit is in
docs/research/2026-10-11-combat-audit.md:
68 behaviours, each with its evidence, verdict and action.
Method
We compared every combat behaviour we could name with the retail record:
- Carbine's patch notes (all 108 pages, kept verbatim on the Fandom wiki);
- the archived "Deep Dive: Combat Stat Revamp" post;
- Carbine developer comments;
- the shipped UI (Lua, strings and API documentation);
- the client's own tables;
- the client's decompiled code.
Each finding is labelled reference (the public record), derived (the
client's data or code) or guess (our own extrapolation). Where retail left
no evidence, the value stays designed and is listed in
docs/design/designed-values.md with its basis.
Bezgelor's combat began as a port of NexusForever's damage calculator, threat list and telegraph geometry. That work made this audit possible. Where we now differ, it is because new evidence appeared (mostly the decompiled client), and the differences are written down so other projects can use them.
Results
| Verdict | Count |
|---|---|
| Matches retail | 26 |
| Differed, now fixed (6 of these were bugs the new tests found) | 20 |
| Differs, filed as issues (#97-#101) | 9 |
| Unknown (no retail evidence) | 13 |
The findings most likely to interest other emulator projects:
-
The client's rating formula. The routine at 0x140453b60 in the 64-bit
client turns a rating into a chance:
The percentage is in percent units, not a fraction. Armor (GameFormulak = datafloat0 / level * datafloat01 (percent per point) t = (datafloat02 - dataint0) / k (start of the soft cap) pct = dataint0 + k * rating if rating < t pct = datafloat02 + k*e*cos(e/(e+datafloat03) * pi/2), e = rating - t otherwise value = min(pct/100 + base, dataint01/100)- is on the curve from its first point. Critical mitigation uses GameFormula 1242. The client has no attacker-versus-victim level term.
- Moment of Opportunity: CCState 9 (Vulnerability), 50% extra damage (the MoO spells' own tooltip), 2-6 s per spell.
- Interrupt armor recharges on a timer. Creature overrides most often use 5000 ms.
- Diminishing returns: the only published rule is for Taunt and Pacify: 3 applications per rolling 10 s, each 25% shorter.
- Respawn timers were randomised ranges. Normal creatures came back in about a minute.
- Evading creatures are a full reset and can't be kept in combat with damage.
Tests behind it
-
27 property-based tests (StreamData) covering:
- the damage pipeline;
- telegraph geometry;
- auras, interrupt armor, shields, absorbs, threat and diminishing returns.
- Zone-level scenarios: crowd control, mid-cast deaths, leash, casting while moving, telegraph edges, threat and taunt, pets, stealth, duels, aggro by level.
- A sweep of every class's level 1-15 kit (112 abilities).
-
A soak: 50 players and 500 creatures. Results are in
soak-2026-10-11.md. - Headless end-to-end runs through the real protocol, every packet checked by the client's own parser: pull, fight, kill, loot, die, resurrect and repair, for three classes.