Combat Mechanics Primer

This guide distills the melee and spell resolution rules straight from src/fight.c, src/handler.c, src/magic.c, and src/merc.h.

Class touchstones

Every player class declares a prime attribute and THAC0 progression in class_table. The prime stat feeds the new damage-cap formula while the THAC0 entries drive hit-roll interpolation.

ClassPrime statTHAC0 (level 0 / 32)
MageIntelligence20 → 6
ClericWisdom20 → 2
ThiefDexterity20 → −4
WarriorStrength20 → −10

Source: class_table definition.【F:src/const.c†L640-L659】

Attack roll flow

  1. Setup: one_hit resolves the weapon type, skill, and damage type. Undefined attacks adopt the wielder’s weapon damage type or the character’s innate dam_type.【F:src/fight.c†L603-L676】
  2. THAC0: NPCs pick baseline values by role flag while PCs pull thac0_00 and thac0_32 from class_table. Interpolation by level plus hitroll, skill, and backstab adjustments produces the final to-hit target.【F:src/fight.c†L695-L720】
  3. Armor check: The defender’s armor entry for the damage type is divided by ten. Extreme negatives suffer diminishing returns via (ac + 15) / 5 - 15. Visibility and posture then modify the effective AC before a 0–19 d20 roll determines success.【F:src/fight.c†L722-L763】
  4. Defences: On weapon hits the game checks parry, shield block, then dodge in that order. Each routine scales from either NPC level caps or the defender’s trained skill values.【F:src/fight.c†L1080-L1091】【F:src/fight.c†L1813-L1993】

Offensive scaling

Armor and mitigation

Saving throws

saves_spell() evaluates spell saves as 50 + (victim level − spell level) × 5 − 2 × saving_throw, with berserkers gaining a level/2 bonus. Immunity short-circuits the check while resistance/vulnerability shift the target by ±2. The final save chance is clamped to 5–95% before rolling number_percent().【F:src/magic.c†L203-L220】