[High] [Bug] Spells continue casting and draining mana after all enemies are dead in a room #346
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?
Bug: Spells continue casting and draining mana after all enemies in a room are dead
Description
When descending the spire and reaching floor 1 room 0, if the player has cleared the enemy in that room, they continue to cast spells and drain mana for no reason. Once there are no enemies, spell casting should stop.
This is not limited to floor 1 room 0 — it affects any combat room where all enemies have been killed but the room has not yet been cleared (e.g., during the same tick where the killing blow lands, or in edge cases during descent where a room with 0 enemies is generated).
Root Cause
Missing
floorHP > 0guard on the primary spell casting loop.In
src/lib/game/stores/combat-actions.ts, the primary spell castingwhileloop (lines ~148–196) has this condition:It checks:
It does NOT check whether there are any living enemies (
floorHP > 0orcurrentRoom.enemies.some(e => e.hp > 0)).Compare with the melee sword loop (line 267) which does have this guard:
And the golem attack loop (line 312):
And the DoT processing (line 335):
So the primary spell loop is the only combat damage source that lacks an enemy-presence check.
What Happens Step-by-Step
currentAction === 'climb'so the combat tick runsspellDefis truthy (player hasmanaBoltactive)weaponCastProgress['primary']accumulates past 1.0 from previous tickswhileloop fires: cast progress >= 1 AND player has mana → spell castsdeductSpellCost()drains manaapplyDamageToRoom()is called — sinceroom.enemies.length === 0, it falls back to directfloorHPsubtraction (line 43–47 ofcombat-damage.ts), settingfloorHPto 0 and returningroomCleared: trueadvanceRoomOrFloor()is called, moving to the next roomweaponCastProgress['primary']was >= 2 (multiple casts queued), the loop continues casting into the new room without checking if that room has enemiesThe
applyDamageToRoomEmpty-Enemies Fallback Makes It WorseIn
combat-damage.tslines 43–47:When enemies array is empty, damage is still applied to
floorHPdirectly, androomClearedreturnstruewhenfloorHP <= 0. This means:roomClearedtriggersadvanceRoomOrFloor()repeatedlyweaponCastProgress['primary']to 0, but the loop may have already queued multiple castsIs This an Issue in Non-Combat Rooms?
Yes, partially. Non-combat rooms (library, recovery, treasure, puzzle) have
enemies: []by design. However, the non-combat room tick path ingameStore.ts(line 295–307) only runs whenroomTypeis one of those types, and the combat tick path only runs whencurrentAction === 'climb'. The issue is that:currentActionis still'climb', the combat tick still runsapplyDamageToRoomwith empty enemies applies damage tofloorHP(which is 0 for non-combat rooms), triggeringroomCleared: trueHowever, in practice the non-combat room tick handler in
gameStore.ts(line 295) runs after the combat tick, so the combat tick may advance the room before the non-combat handler gets a chance to process it.Severity Assessment
Files Involved
src/lib/game/stores/combat-actions.tsfloorHP > 0guardsrc/lib/game/stores/combat-actions.tsfloorHP > 0guard (correct)src/lib/game/stores/combat-actions.tsfloorHP > 0guard (correct)src/lib/game/stores/combat-actions.tsfloorHP > 0guard (correct)src/lib/game/stores/combat-damage.tsapplyDamageToRoomempty-enemies fallback — applies damage tofloorHPeven with no enemiesReproduction Steps
Alternative reproduction:
castProgressto a high value (e.g., 5)Suggested Fix
Add
floorHP > 0to the primary spell castingwhileloop condition incombat-actions.ts:This matches the pattern already used by the melee, golem, and DoT loops.
Starting work on Issue #346. Root cause confirmed: primary spell casting while loop in combat-actions.ts is missing
floorHP > 0guard. The melee, golem, and DoT loops all have it — only the primary spell loop lacks it. Also fixing the equipment spell loop which has the same issue.✅ Fixed Issue #346. Added
floorHP > 0guard to both the primary spell casting while loop and the equipment spell casting while loop in combat-actions.ts. This matches the pattern already used by melee, golem, and DoT loops. All 17 existing tests pass + 5 new regression tests added.