Prestige Store:
- Convert doPrestige() to return Result<void> with specific error codes
(INVALID_PRESTIGE_ID, PRESTIGE_MAX_LEVEL, INSUFFICIENT_INSIGHT)
- Convert startPactRitual() to return Result<void> with specific error codes
(GUARDIAN_NOT_DEFEATED, PACT_ALREADY_SIGNED, PACT_SLOTS_FULL,
INSUFFICIENT_MANA, RITUAL_IN_PROGRESS)
Combat Actions:
- Add try/catch wrapper inside processCombatTick with safe fallback defaults
- Add makeDefaultCombatTickResult helper for error recovery
LocalStorage Error Handling:
- Create safe-persist.ts utility wrapping localStorage with error handling
(corrupted JSON, quota exceeded, unexpected failures)
- Update all 8 Zustand stores to use createSafeStorage() in persist middleware
UI Updates:
- Update GuardianPactsTab to use Result pattern for ritual error messages
Tests:
- Update store-actions-combat-prestige.test.ts for Result return types
- Update store-actions.test.ts ManaStore tests for Result pattern
- Remove duplicate Prestige/Discipline sections from store-actions.test.ts
- All files under 400 line limit
601 tests pass (3 pre-existing failures in spire-utils.test.ts)
- Issue 83: Mana Tide pulse factor now ranges 0.5x-1.5x (was 0.5x-1.0x)
- Issue 82: SteadyStream no longer returns early like EternalFlow; only skips incursion penalty
- Issue 81: Prestige store partialize now includes defeatedGuardians, signedPacts, signedPactDetails, pactRitualFloor, pactRitualProgress, loopInsight, pactSlots
- Issue 80: Combat store partialize now includes floorHP, floorMaxHP, castProgress, spireMode, clearedFloors, golemancy, equipmentSpellStates, activityLog, achievements
- Issue 78: cancelDesign now always cancels designProgress first, then designProgress2
- Issue 79: startDesigningEnchantment now uses designProgress2 when designProgress is occupied
Added 13 regression tests in src/lib/game/__tests__/regression-fixes.test.ts
Refactored craftingStore types to craftingStore.types.ts to stay under 400-line limit
- equipment/utils.ts: import directly from individual equipment modules instead of index.ts
- golems/utils.ts: import directly from individual golem modules instead of index.ts
- combatStore.ts: extract CombatState to combat-state.types.ts, remove debugSetTime (was only user of gameStore import)
- combat-actions.ts: import CombatState from combat-state.types.ts instead of combatStore
- stores/index.ts: re-export CombatState from combat-state.types.ts
- GameStateDebug.tsx: replace debugSetTime calls with direct useGameStore.setState()
Verification: bunx madge --circular src/lib/game → No circular dependency found!
- Fix mana conversion to deduct from regen instead of mana pool (resolves player stuck at 1 mana below cap)
- Fix Spire Tab error by removing unused legacy import (store-modules/enemy-utils)
- Fix Grimoire Tab error by adding Array.isArray check for effects.map
- Move utility functions from legacy store-modules to utils/ to eliminate legacy dependencies
- Add regression test for mana conversion fix
- Update SpellsTab.tsx imports to use utils instead of legacy stores
The startStudyingSkill() and startStudyingSpell() functions in skillStore.ts
were setting currentStudyTarget but not updating currentAction in combatStore.
Added useCombatStore.getState().setAction('study') calls to both functions
so the game tick properly processes study progress.