[priority: highest] Entering the Spire with "Climb the Spire" crashes the game #175
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?
Description
When the player clicks "Climb the Spire" (in
LeftPanel.tsxorSpireSummaryTab.tsx), the game crashes/returns to the main view immediately instead of entering Spire Mode.Root Cause
The
enterSpireMode()action insrc/lib/game/stores/combatStore.ts(lines 200–211) setsspireMode: truebut does NOT setcurrentAction: 'climb'. TheSpireCombatPageuseEffectsets it asynchronously, creating a render window where child components (SpireHeader, RoomDisplay, SpireCombatControls, etc.) may access uninitialized state. TheErrorBoundaryinpage.tsx(lines 188–194) catches the resulting render error and callsexitSpireMode(), which snaps the player back to the main game view — appearing as a "crash".Additionally,
enterSpireMode()callsgenerateFloorState(1)which may return a legacyFloorStateshape incompatible with the spire-specific state expected bySpireCombatPagecomponents.Affected Files
src/lib/game/stores/combatStore.tslines 200–211 —enterSpireMode()missingcurrentAction: 'climb'src/components/game/tabs/SpireCombatPage/SpireCombatPage.tsxlines 109–113 —useEffectsets action asyncsrc/app/page.tsxlines 188–194 —ErrorBoundarycatches render error and resetsReproduction
Expected Behavior
Player enters Spire Mode and sees the combat interface.
Starting work on this issue. The root cause is clear:
enterSpireMode()doesn't setcurrentAction: 'climb', andgenerateFloorStateis used instead ofgenerateSpireFloorState. The useEffect in SpireCombatPage tries to async set the action, but during the render window before the effect fires, child components access uninitialized state (currentAction is 'meditate' instead of 'climb'), causing a render error that the ErrorBoundary catches, callingexitSpireMode()which snaps the player back to the main view.Fixed. Two changes made to
src/lib/game/stores/combatStore.ts:Added
import { generateSpireFloorState }from../utils/spire-utils—enterSpireMode()was usinggenerateFloorState()which returns a generic floor state incompatible with the spire-specific components. Now usesgenerateSpireFloorState(1, 0, 1).Added
currentAction: 'climb'to theenterSpireMode()set() call — PreviouslycurrentActionwas left as'meditate'(the default). TheSpireCombatPageuseEffect tried to set it async withsetAction('climb'), but during the render window before the effect fired, child components accessed uninitialized/inconsistent state, causing a render error that the ErrorBoundary caught, callingexitSpireMode()and snapping the player back to the main view.Both changes ensure that by the time React renders
SpireCombatPage, the store is already in a fully consistent spire-climbing state.All 52 combat/spire tests pass. No new TypeScript errors introduced.