Combat
When you issue a combat command ("attack", "dodge"), it is validated immediately and queued. After all commands are captured, the full combat round resolves in order:
Last updated: October 30, 2026
Combat Flow
When you issue a combat command ("attack", "dodge"), it is validated immediately and queued. After all commands are captured, the full combat round resolves in order:
- Your attack fires — hit check runs, then damage calculation, then application
- The enemy counterattacks
- Status effects tick (poison damage, burn, regeneration, etc.)
- Death and victory checks
Why this matters: All your decisions lock in before any results apply, so you never lose an action to a race condition mid-turn.
A potion resolves before the enemies hit. Drinking a health potion, one charge or all of them, heals you and takes no round: the enemies strike on your next act, not in the same breath as the potion, and the turn ends with "What next?". Your charges are the limit, and they refill at the hideout.
Hit Chance Formula
Every attack starts with a 50% base hit chance, then accuracy vs. evasion adjusts it:
- If your accuracy is higher than the enemy's evasion: hit chance goes up, capped at 95%
- If the enemy's evasion is higher than your accuracy: hit chance goes down, minimum 5%
- If your accuracy is 50 or higher, a minimum hit floor applies regardless of enemy evasion:
floor = min(90, accuracy − 10). At accuracy 50 you always hit at least 40%; at accuracy 80, at least 70%; at accuracy 100+, at least 90%.
No attack is ever a guaranteed hit or a guaranteed miss (except when evasion or accuracy is literally zero).
Damage Pipeline
Damage calculation is sequential — each step modifies the result of the previous step:
Step 1: Base Damage Per Type
There are 7 damage types, each calculated independently: Physical, Magical, Fire, Ice, Lightning, Poison, and Chaos. Your resistance to each type reduces incoming damage by that percentage.
Step 2: Block/Deflect
- A shield blocks physical attacks (reduces damage by your block rating)
- A focus deflects magic attacks (reduces damage by your magic deflect rating)
- Only one of these applies per hit — they are mutually exclusive.
- Implementation note: When
hasShieldorhasFocusis true but the correspondingblockRating/magicDeflectRatingis null in the data, the calculation defaults the missing rating to 0L. This protects against malformed enemy data (e.g., LEGENDARY_KNIGHT, SEASONED_WARRIOR, SKELETON_WARRIOR which historically had hasShield=true but no blockRating field) crashing combat. See lines 177-182. Pre-2026-04-26 this was the source of the level-5+ battleground hamster bug.
Step 3: Armor Reduction
After blocking, armor reduces the remaining damage. Enemies can partially bypass your armor with armor penetration, but cannot reduce it below zero.
Exception: Back attacks skip armor entirely (see Step 4).
Step 4: Positional Bonuses
Where you stand relative to the enemy matters enormously:
| Position | Damage Multiplier | Armor | Shield/Block |
|---|---|---|---|
| Front | 1.0x (normal) | Full armor applies | Full block applies |
| Side | 1.25x (+25%) | Full armor applies | Full block applies |
| Back | 1.5x (+50%) | Bypassed entirely | Bypassed entirely |
Back attacks deal 50% more damage AND bypass both armor and shields — this makes positioning the most impactful tactical choice in combat.
An attack comes from behind when it comes from the direction the player faces (DarkTowerBasicDirections.getPositionalAttackType). A player entering a zone faces into it, toward its centre, the way they walked in (), so the enemies standing inside a portal square are in front of them, never behind. Every other arrival faces the same way: a teleport to the hideout, a siege or a rift, a return teleport, a teleport to a party leader, and the death respawn all place the player through , which faces them toward the centre of the zone they land in. Regression: .
Step 5: Critical Strike
A critical hit multiplies damage by your critical multiplier. The default critical multiplier is 1.5x (150%). Gear and paragon bonuses can increase this further.
Level Difference Scaling
When you fight enemies at very different levels, the damage scales dramatically:
| Level Difference | Effect |
|---|---|
| Attacker 10+ levels above | Instant kill |
| Attacker 5+ levels above | +50% damage per level (overwhelming force) — capped at 2.0× |
| Attacker 1-4 levels above | +25% damage per level — capped at 2.0× (cap hit exactly at +4 levels) |
| Same level | Normal damage |
| Attacker below target | No bonus (normal) |
The damage multiplier is capped at 2.0× base damage (MAX_LEVEL_ADVANTAGE_MULTIPLIER = 2.0) regardless of level gap. Fighting enemies above your level won't make you do more damage — but it does award bonus XP.
Class-Weapon Synergy
Every weapon has a type (a swift sword, a heavy war hammer, an arcane wand). A class deals +15% weapon damage when its equipped main-hand weapon is one its archetype favors:
| Class | Favored main-hand weapons |
|---|---|
| Fighter, Barbarian | Axe, War Hammer |
| Rogue, Ranger | Sword, Crossbow |
| Sorcerer, Necromancer | Wand, Staff |
| Cleric, Paladin | Club, Mace |
Any class can still equip any weapon — an off-type weapon just forgoes the bonus. Your class's favored weapon is the stronger pick, never the only allowed one, so a lucky drop of the "wrong" type is never wasted. Each class starts with a weapon of its favored type.
Enemy Density & Engagement Limits
| Limit | Value | What It Means |
|---|---|---|
| Max enemies per square | 5 | A grid square can hold up to 5 enemies |
| Max melee attackers per square | 4 | At most 4 melee enemies on a single square can attack you per round |
| Max total melee attackers per round | 3 | Across all squares, only 3 melee enemies total can attack you in one round |
| Max ranged attackers per square | 4 | At most 4 ranged enemies on a single square can attack you per round |
| Max total ranged attackers per round | 3 | Across all squares, only 3 ranged enemies total can attack you in one round |
Melee and ranged enemies are tracked on independent budgets: even when enemies surround you on multiple squares, no more than 3 melee attacks AND no more than 3 ranged attacks land per round (up to 6 total if a fight has both). Ranged enemies (attackRange > 1) are no longer unbounded — a dense pack sharing a common attackRange (e.g. a zone whose whole roster is attackRange=2) is capped the same way a melee pack is, so it can no longer deal unbounded cumulative damage in a single round.
Early zones cap the pack you meet. Forest Path, Trevmarch Sewers and Trevmarch City spawn so that no square shows more than 4 enemies within two squares, a new character's sight. A zone spawns the enemies that fit under its cap and no more.
A zone can also cut its packs. Burning Gorge spawns each pack at two thirds of its size, rounded down and never below one enemy, so its fights end in fewer rounds. The enemies that spawn pay for the ones the cut left out: each kill's experience and gold scale by the zone's reward percent, the spawned share of the configured population, and its loot rolls repeat for each whole share with the remainder as a chance of one more. The zone's enemy configuration sets packSizePercent; is the rule and the proof.
Star Map Attack System
Star Map nodes unlock special attacks that trigger automatically during combat at fixed intervals:
| Attack Tier | Trigger | Damage Multiplier |
|---|---|---|
| Basic | Every 2 attacks | 1.2x |
| Super | Every 7 attacks | 1.4x |
| Ultimate | Every 14 attacks | 2.0x |
These fire automatically — no action needed on your part.
Skill Gem Triggers
Skill gems slotted into equipment activate special abilities at fixed combat intervals:
| Gem Type | Trigger |
|---|---|
| Attack Skill | Every 6 attacks |
| AOE Skill | Every 10 attacks |
| Magic Skill | Every 13 attacks |
AOE Abilities
Some abilities hit multiple enemies at once. See AOE Ability Reference below for damage %, element, and trigger frequency.
| Ability | Range | Targets |
|---|---|---|
| Fire Nova / Chaos Nova / Storm of Blades | 1 tile radius (square) | All enemies in range |
| Cone of Ice | 4 tiles (cone) | Enemies in cone direction |
| Lightning Strike | 2 tile radius (square) | All enemies in range |
Auto-Attack vs Manual Attack
There are two ways combat triggers:
- Auto-attack — Happens automatically when you move into an enemy's range. Your primary attack hits all enemies on the same square each round, so you can clear groups without targeting individually. This is the primary way combat works during exploration — just walk and fight.
- Manual attack — Type "attack" to trigger combat manually. Works the same as auto-attack (hits all enemies on your square) but lets you initiate combat on your terms.
Combat Log (Damage Review)
Per-round combat narration scrolls past on a voice device, so a player asking "how much am I actually dealing and taking" has no way to review it after the fact. Two things answer that:
- Per-round readout — every combat round already narrates the damage you dealt (the rolled-up player-attack line) and the damage you took ("You took N damage this round. You have M health remaining."). This stays concise by design: one rolled-up line per round, never one line per hit.
- On-request recap — say combat log or what happened any time in Darkness Falls to hear a recap of your most recent rounds: how much damage you dealt, how much you took, and how many enemies you defeated, newest first. The recap is capped to the last few rounds so it never becomes a wall of speech. Before your first fight it simply tells you the command exists.
Status Effects
Damage Over Time
| Effect | Behavior |
|---|---|
| Poison | Poison damage per turn |
| Burning | Increasing fire damage per turn |
| Bleeding | Physical damage over time |
| Acid | Damage + armor reduction |
Stat Modifications
| Effect | Magnitude | Type |
|---|---|---|
| Blessed | +25% all stats | Buff |
| Cursed | -25% all stats | Debuff |
| Haste | +50% attack speed | Buff |
| Slow | -50% movement/attack speed | Debuff |
| Strength/Agility/Intelligence Boost | Temporary increase | Buff |
| Strength/Agility/Intelligence Penalty | Temporary decrease | Debuff |
Special Conditions
| Effect | Behavior | Type |
|---|---|---|
| Frozen | Cannot move or attack | Debuff |
| Stunned | Skip next turn | Debuff |
| Invisible | Cannot be targeted | Buff |
| Regeneration | Heal each turn | Buff |
| Shield | Absorb incoming damage | Buff |
| Vulnerable | Increased damage taken | Debuff |
| Resistant | Reduced damage taken | Buff |
Status Effect Implementation Status
Canonical spec: status-effects.md covers the full overhaul — consumer wiring, stacking elemental builds, enemy debuffs, ground effects, and the SHORT voice rollup. The notes below describe the pre-overhaul state.
The status-effect framework ( apply/process/expire, ticked every combat round by ) is live for the four effects current gear abilities actually produce: Stunned (Stun Blow), Bleeding (Bleed Strike), Vulnerable (Armor Crush), and an Armor buff (Fortify). canCharacterAct gates turns on Frozen/Stunned.
The remaining appliers in (Freeze, Invisibility, Resistance, Magic-Find, Gold-Find, Experience, Critical boosts) and the random buff/debuff dispatchers are framework extension points with no current producer — retained for future gear/powers, deliberately not deleted.
Known gap: stat-modification effects (Vulnerable, Resistant, Blessed/Cursed debuffs, the boosts) are added to a character's effect list, but is never consulted by the damage/loot formulas, so these effects currently have no numeric impact. Wiring getEffectiveStat into combat is a balance change that needs design sign-off before implementation.
Combat Modifiers
| Effect | Type |
|---|---|
| Critical Boost | Increased crit chance |
| Armor Boost / Armor Reduction | Armor changes |
| Damage Boost / Damage Reduction | Damage changes |
Utility Effects
| Effect | Type |
|---|---|
| Magic Find | Increased magic item drops |
| Gold Find | Increased gold drops |
| Experience Boost | Increased XP gained |
Death & Resurrection
Characters have three states: Alive, Downed, and Dead.
- Downed: You cannot act (move, attack, use items). This happens when you fall in a zone your party shares and an ally is there with you. An ally on your square can say resurrect and your name, and you rise on your next turn with just over a third of your health. Say return to hideout at any time to recover instead.
- Dead: You respawn at your hideout with an XP penalty. The zone you fell in rolls its enemies again, so the way back in does not lead to the pack that killed you. Endgame zones keep their encounter.
- After teleporting back: A brief grace period gives you one safe turn to orient yourself before enemies attack.
Warband System
A Warband is a persistent social group that provides passive combat bonuses scaling with the warband's level, up to 25% maximum.
Combat Bonuses
| Perk | Effect | Unlock Level | Max |
|---|---|---|---|
| Damage Bonus | Increases all damage dealt in combat | Level 1 | +25% |
| Healing Bonus | Increases all healing received | Level 1 | +25% |
| Bonus Revive Charges | Extra charges to resurrect downed party members | Level 4 | Varies |
| Shared Waypoints | Party members can use each other's zone checkpoints | Level 4 | — |
| Rare Drop Bonus | Increases rare item drop rates | Level 7 | Varies |
Warband Experience
Every time you earn XP from combat, your warband automatically receives 10% of your XP gain. Warband XP accumulates separately and levels up the warband, unlocking stronger bonuses for all members.
Bonus Scaling
Damage and healing bonuses grow at 1% per warband level, capped at 25%.
AOE Ability Damage Scaling
AOE abilities deal a percentage of the player's base attack damage (flat multiplier, not a percentage-based reduction). The damage is calculated by copying the player's basic attack stats and applying the multiplier to the relevant damage type.
AOE Ability Reference
| Ability | Shape | Range | Damage % | Element | Trigger |
|---|---|---|---|---|---|
| Fire Nova | 1-tile radius (square) | 1 | 70% of base | Fire | Every 10 attacks |
| Chaos Nova | 1-tile radius (square) | 1 | 70% of base | Chaos | Every 10 attacks |
| Storm of Blades | 1-tile radius (square) | 1 | 70% of base | Physical | Every 10 attacks |
| Cone of Ice | Cone (facing direction) | 4 | 50% of base | Ice | Every 10 attacks |
| Lightning Strike | 2-tile radius (square) | 2 | 50% of base | Lightning | Every 10 attacks |
Damage scaling is flat: A 70% Nova takes the player's base attack damage values, multiplies them by 0.7, then runs the result through the standard damage pipeline (hit check, defense, armor, crit). Each enemy in the AOE is attacked independently.
AOE Shape Types
| Shape | Behavior |
|---|---|
SQUARE_ON_CHARACTER |
All squares within N tiles of the player (uses enemySquares()) |
CONE_FROM_CHARACTER |
Squares in the player's facing direction, expanding diagonally at range > 1 |
LINE_FROM_CHARACTER |
Straight line of N squares in the player's facing direction |
Cone implementation: At distance 1, only the forward square. At distance 2+, adds diagonal squares to the left and right of the main line (e.g., facing North also hits NE and NW at range 2+).
Skill Gem Trigger & Chain Mechanics
Skill gems activate automatically during combat based on the player's cumulative attack count. They do NOT chain off each other — each gem independently checks currentAttackCount % triggerFrequency == 0.
Trigger Frequencies
| Gem Category | Frequency | Examples |
|---|---|---|
| Attack Skill | Every 6 attacks | Knock Back, Sneak Attack, Strafe Attack, Enhanced Accuracy, Overpower, Fire/Ice/Lightning/Chaos Blast |
| AOE Skill | Every 10 attacks | Fire Nova, Cone of Ice, Lightning Strike, Chaos Nova, Storm of Blades |
| Magic Skill | Every 13 attacks | Arcane Damage (+30% all damage types) |
| Star Map Basic | Every 2 attacks | Fire/Ice/Lightning/Chaos/Physical Attack (+20% damage) |
| Star Map Super | Every 7 attacks | Fire/Ice/Lightning/Chaos Super Attack (+40% damage) |
| Star Map Ultimate | Every 14 attacks | Super Attack (+100% damage to all types) |
How Multiple Gems Interact
- All equipment slots are checked every attack (10 gear slots + 5 skill slots + star map points)
- Multiple gems can trigger on the same attack — if attack #42 triggers both an AOE gem (42 % 10 == 0 is false, skip) and an attack gem (42 % 6 == 0, fires), both execute
- No chaining/proc mechanics: Gem A triggering does NOT count as an "attack" for Gem B. Only player-initiated attacks increment the counter.
- Custom frequency: If an item property has
howOftenSwingsset, that overrides the default frequency - Attack count 0 is skipped: The first attack (count 0) never triggers any gems
Attack Skill Gem Effects
| Gem | Mechanic | Damage |
|---|---|---|
| Knock Back | Hit + push enemy back 1 square | 1.0x physical |
| Sneak Attack | Teleport behind enemy + back attack | 1.5x physical (back bonus) |
| Strafe Attack | Move to enemy's side + flank attack | 1.25x physical (side bonus) |
| Enhanced Accuracy | +30% accuracy for this attack | 1.0x (base damage) |
| Overpower | +30% physical damage for this attack | 1.3x physical |
| Elemental Blast | +30% elemental damage for this attack | 1.3x (fire/ice/lightning/chaos) |
Zone Modifier Effective Level Formula
In endgame zones (level 100-150), modifiers do NOT change the zone's effective level directly. Instead, they apply percentage bonuses to enemy HP and damage on top of the level-based scaling. The effective level determines base scaling; modifiers add flat percentage bonuses on top.
Endgame Scaling Table
Standard endgame zones use these breakpoints. Abyssal Rift tiers 11-20 extend the same scaling curve beyond level 150 (see endgame.md § Rift Tier Scaling).
| Zone Level | Enemy HP % | Enemy Damage % | Loot % |
|---|---|---|---|
| 100 | 100% | 100% | 100% |
| 110 | 150% | 130% | 150% |
| 120 | 200% | 160% | 200% |
| 130 | 275% | 200% | 275% |
| 140 | 375% | 250% | 375% |
| 150 | 500% | 300% | 500% |
| 160 (rift t10-12) | 650% | 340% | 650% |
| 175 (rift t13-15) | 900% | 400% | 900% |
| 200 (rift t16-18) | 1300% | 480% | 1300% |
| 220 (rift t19-20) | 1700% | 550% | 1700% |
Levels between breakpoints are linearly interpolated. The rift extension rows are the design-side scaling target; standard (non-rift) zones still cap at level 150.
Modifier Stat Bonuses (Additive on Top of Level Scaling)
| Modifier | HP Bonus | Damage Bonus | Loot Bonus |
|---|---|---|---|
| Empowered | +25% | +0% | +15% |
| Frenzied | +0% | +20% | +15% |
| Endless | +0% | +0% | +25% |
| Cursed | +0% | +0% | +20% |
| Nightmare | +0% | +0% | +10% |
| Bloodlust | +0% | +0% | +30% |
| Void-Touched | +0% | +0% | +20% |
| Death's Door | +0% | +0% | +40% |
Combined Formula
totalHpPercent = levelScaling.hpPercent + SUM(modifier.hpBonusPercent)
totalDmgPercent = levelScaling.damagePercent + SUM(modifier.damageBonusPercent)
totalLootPercent = levelScaling.lootPercent + SUM(modifier.lootBonusPercent)
enemyHP = percentOf(totalHpPercent, baseHP)
enemyDamage = percentOf(totalDmgPercent, baseDamage)
All 8 Modifiers on World's End (Level 150)
HP: 500% (level) + 25% (Empowered) = 525%
Damage: 300% (level) + 20% (Frenzied) = 320%
Loot: 500% (level) + 175% (all mods) = 675%
Plus gameplay effects: enemies respawn (Endless), healing -20% (Cursed), visibility -2 (Nightmare), enemy lifesteal 10% (Bloodlust), 5% random teleport (Void-Touched), no potion recharge (Death's Door).
Modifier Gameplay Effects
Implementation status (Wave 4 SHIPPED 2026-07-28): Death's Door + HP/damage/loot scaling remain live. Nightmare (sight −2), Bloodlust (10% enemy heal), Cursed (heal ×0.8 on potion/mend), Void-Touched (5% move teleport), and Endless (respawn before corpse sweep) are wired via DarknessFallsZoneModifierEffects on the real paths. Proof: JUnit + scenario 3017.
| Modifier | Mechanic | Constants |
|---|---|---|
| Cursed | Healing multiplied by 80% (= -20%) | CURSED_HEALING_REDUCTION_PERCENT = 80 |
| Nightmare | Sight distance reduced by 2 squares (min 1) | NIGHTMARE_SIGHT_REDUCTION = 2 |
| Bloodlust | Enemy heals 10% of damage dealt | BLOODLUST_HEAL_PERCENT = 10 |
| Void-Touched | 5% chance (500/10000) per movement to random teleport | VOID_TOUCHED_TELEPORT_CHANCE = 500 |
| Endless | Enemies respawn 30 seconds after death | getEndlessRespawnDelayMs() = 30_000 |
| Death's Door | canRechargePotions() returns false |
Boolean check |
Combat Damage Cap
A per-round damage cap trims the enemy damage of a round the player survives:
maxDamagePerRound = 65% of player's max HP
Death is decided first, in the enemy attack phase, on the round's raw damage: in a zone above the player's level, a round whose raw damage takes the player to 0 health kills them, from full health too, and the death return runs. Resistant, Shield, Guard and then the cap act afterwards on a round the player survived. A survived round over the cap is reduced to it, never below 1 health, and the player hears it in words: "Your resolve absorbs N damage of the onslaught. You have M of X health." is the value, and pins the order; scenario_tests 1385 and 2341 pin a one-round death from full health ending at the hideout.
A level-matched zone never kills in one round. In a zone at or below the player's level, the
death check holds the cap: when a round's raw damage would take the player to 0, a player who began the
round above 65 percent of their health is left at the cap's floor (their round-start health less 65
percent of their maximum) instead of dying, so a player at full health there is never killed by one
round. One who began the round lower can still fall. The round's starting health rides the request
(GameBasicProperties.darknessFallsHitPointsAtRoundStart, set around the enemy phase), and
is the one place it is read;
pins it.
A zone above the player's level keeps death first on raw damage. Deciding death after the modifiers and the cap there too would make a player at full health unkillable in one round anywhere; that wider order is an open balance decision for the owner, not the current behaviour.
The cap does not keep an early zone under the game-balance death rule. The early-zone deaths come from the length of a fight against a pack of ten or more, not from one round: replays the recorded fights of TREVMARCH_SEWERS, FOREST_PATH and TREVMARCH_CITY and pins that the cap leaves each over the rule. Pack size and the zone-entry buffer are the levers, in game-balance.md § Healthy Ranges.