[Medium] [Task] Combat spec gap: implement regular enemy defenses — armor, barrier, dodge (spec §5.1, §5.2, §5.3) #257
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Combat Spec Gap: Regular Enemy Defenses (Armor, Barrier, Dodge)
Gap Summary
Enemy defensive stats (
armor,barrier,dodgeChance) are populated onEnemyStateduring room generation (utils/enemy-generator.ts,utils/room-utils.ts) but are never applied in the combat tick pipeline. TheonDamageDealtfunction instores/pipelines/combat-tick.tsonly handles guardian-specific defenses (shield, barrier, healthRegen). Regular enemies deal and take full damage with no defensive reduction.What Exists
EnemyState.armor,.barrier,.dodgeChancefields intypes/game.tsMODIFIER_CONFIGinutils/enemy-generator.tswith full config forarmored,shield,agile,mage,swarmmodifiersgetFloorArmor(),getEnemyBarrier(),getDodgeChance()functions inutils/room-utils.tscombat-tick.ts(shield absorb → barrier reduce → health regen)speedRoomBonusconstant infrastructure in room generationWhat's Missing
1. Damage reduction pipeline for regular enemies (spec §5.2)
The
makeOnDamageDealtfunction instores/pipelines/combat-tick.tsmust apply this order for all enemies (not just guardians):Current code: none of these steps exist.
onDamageDealtonly checksif (guardian && ...).2. Enemy reference in onDamageDealt
The current
makeOnDamageDealtsignature is(damage: number) => { rawMana, elements, modifiedDamage }. It has no access to the target enemy. The pipeline must be refactored so the per-enemy damage callbacks receive the enemy being hit.3. Speed room + agile additive dodge (spec §4.5)
When a room is type
speedAND the enemy has theagilemodifier:Where
speedRoomBonus = 0.20(constant). Currently neither the dodge check nor the additive combination exists.4. Mage barrier recharge (spec §5.2)
Mage-enemy barrier must recharge each tick:
MODIFIER_CONFIG.mage.barrierRechargeRate = 0.05(5% of max HP per tick) exists in data but is never called.Files to Change
stores/pipelines/combat-tick.tsmakeOnDamageDealtto accept enemy target; add dodge/barrier/armor reduction for all enemies not just guardians; add mage barrier recharge; add speed room + agile additive dodgestores/combat-actions.tsonDamageDealtcalls inprocessCombatTickstores/combat-state.types.tsAcceptance Criteria
Out of Scope
combat-tick.ts)Starting implementation of regular enemy defenses (armor, barrier, dodge). This is the foundational combat spec gap that #258 (DoT) and #259 (golemancy) depend on. Plan: refactor
makeOnDamageDealtto accept enemy target, add dodge/barrier/armor pipeline for all enemies, add speed room + agile combo, add mage barrier recharge.✅ Implementation complete. All 921 tests pass (45 test files).
What was implemented:
applyEnemyDefenses()pipeline incombat-tick.ts: dodge → barrier → armor reduction for ALL enemies (spec §5.2)min(0.75, dodgeChance + 0.20)(spec §4.5)effectiveArmorsupport for future armor_corrode debuff compatibilityenemy-defenses.test.tsFiles changed:
src/lib/game/stores/pipelines/combat-tick.ts(184 lines) — Core defense pipelinesrc/lib/game/stores/gameStore.ts(397 lines) — Defense context capture + mage rechargesrc/lib/game/__tests__/enemy-defenses.test.ts(345 lines) — New testsArchitecture decision: Enemy defense context is passed via closure to
makeOnDamageDealt()rather than changing theonDamageDealtcallback signature — this avoids cascading type changes acrosscombat-actions.ts,combat-store.ts, andcombat-state.types.ts.Next: This unblocks issues #258 (DoT/debuff system) and #259 (golemancy combat).