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)
- Fix computeDisciplineEffects() to not require GameState parameter
- Fix getUnifiedEffects() to accept proper partial state type
- Replace upgradeEffects as any with proper UnifiedEffects type
- Replace explicit : any annotations with proper types (ComputedEffects, DesignProgress, SpellDef, etc.)
- Fix activity-log.ts eventType casting
- Fix crafting-design.ts computedEffects and designProgress types
- Fix page.tsx grimoire spell rendering with proper SpellDef property names
- Fix StatsTab ManaStatsSection with proper ManaStatsEffects interface
- Remove unused imports (useDisciplineStore from page.tsx, LeftPanel.tsx)
Remaining: 1 as any in craftingStore.ts (pre-existing CraftingStore/GameState architectural mismatch)
- Delete store.ts (355 LOC monolithic store, zero imports)
- Delete crafting-slice.ts (379 LOC legacy crafting module)
- Inline createStartingEquipment() into craftingStore.ts
- Remove legacy equipment/inventory fields from GameState
- Remove EquipmentDef from game.ts imports (unused)
- Fix duplicate EquipmentSpellState export in types.ts
- Fix bluePrintId typo in craftingStore.ts
- Update stores/index.ts to import CraftingState/CraftingActions from craftingStore.types
- Update EquipmentTab.test.ts to test store state instead of deleted module
- Clean up stale comments referencing crafting-slice.ts
- Reduce TS errors from 83 to 72 by removing conflicting legacy types
- 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
Priority 4 fixes:
- #50: getUnlockedAttunements filter now only returns active attunements
- #48: doPrestige return type changed from void to boolean
- #47: ConfirmDialog now catches and displays async errors from onConfirm
- #46: GameStateDebug Fill Mana now uses direct setState instead of loop
- #55: DisciplinesTab statBonus/baseValue props verified correct
- #56: DisciplinesTab tab filtering verified working
Priority 3 fixes:
- #45: drain spell description changed from 'life force' to 'vital energy'
- #44: removed banned 'ascension' skill category
- #43: renamed lifeEssenceDrop to vitalityEssenceDrop
- #42: pactMaster achievement requirement changed from 12 to 9
- #40: golems/utils.ts and equipment/utils.ts now import from index
- #39: removed duplicate RoomType from constants/rooms.ts
- #38: consolidated EquipmentSlot type in types/equipmentSlot.ts
- #37: removed duplicate EnchantmentEffectDef from spell-effects/types.ts
- #36: renamed RARITY_COLORS in loot-drops.ts to LOOT_RARITY_COLORS
- #51: Fix broken import path @/types/disciplines → @/lib/game/types/disciplines
- #52: Fix canProceedDiscipline() called with wrong arguments in discipline-slice.ts
- #53: Add local useState for activeAttunement tab filtering in DisciplinesTab
- #54: Make canProceedDiscipline() defensive when gameState is undefined
- #57: Remove stale CraftingTab export from game/index.ts
- Refactored DisciplineCard to use Zustand selector subscriptions properly
- Added DisciplinePerk type import to discipline-math.ts
- 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!
Files in stores/__tests__/stores-tests/ and stores/__tests__/index-tests/
used relative paths (../../types or ../types) that resolved incorrectly.
Fixed all to use '../../../types' to properly reach src/lib/game/types.ts.
Also fixed mana-calculation.test.ts to import computeElementMax from
the correct location (@/lib/game/stores/index instead of @/lib/game/utils).
- 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
- Added useManaStore import to skillStore.ts
- Added mana deduction logic in startStudyingSkill action
- Mana is now properly deducted when starting to study a skill (unless already paid)
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.
- Added startCraftingEquipment action that validates and initializes equipment crafting
- Added cancelEquipmentCrafting action that cancels crafting and refunds mana
- Used CraftingEquipment functions directly instead of deprecated wrapper actions
- Updated craftingStore imports to include useManaStore and useUIStore
- Fixed crafting/index.tsx barrel file export (removed non-existent type exports)
- Fixed syntax errors in craftingStore.ts (missing commas in function params)
Fixes issue where EquipmentCrafter component couldn't find these actions on craftingStore.
- Fixed src/components/game/GameContext/Provider.tsx
- Fixed src/components/game/GameContext/types.ts
The upgrade-effects.ts imports these from special-effects.ts but doesn't re-export them.
- Updated AGENTS.md to include store/ directory and clarify store architecture
- Updated GAME_BRIEFING.md Code Architecture section with store/ and legacy store info
- Updated skills.md with skill state management information
- Includes other refactoring changes (store hooks, component updates, etc.)
- Updated StatsTab to use hooks directly (useSkillStore, usePrestigeStore, etc.)
- Updated DebugTab to use hooks directly
- Updated all debug child components (GameStateDebug, SkillDebug, AttunementDebug, etc.)
- Updated all stats child components (ManaStatsSection, CombatStatsSection, etc.)
- Fixed UpgradeEffectsSection.tsx syntax errors
- Updated page.tsx to not pass store prop to StatsTab and DebugTab
- All components now use modular stores directly instead of receiving store prop