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
GameContext (Provider, hooks, context-create, types) was never wired into
the app — no layout or page wrapped children with GameProvider. The only
consumer, MemorySlotPicker, was itself orphaned (never imported/rendered).
The app uses direct Zustand hooks throughout. Removes 6 dead files.
Fixes#65
- #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).
- Added @playwright/test as dev dependency
- Created playwright.config.ts with Chromium config and webServer setup
- Created e2e/combat.spec.ts (5 tests for spire mode, floor display)
- Created e2e/enchanting.spec.ts (4 tests for design/crafting tab, enchant flow)
- Created e2e/equipment.spec.ts (5 tests for equip, slots, 2H blocking)
- Created docs/tasks/TASK-001-playwright-setup.md
- All 13 E2E tests passing
Bug 1: EquipmentTab handleEquip was passing useCombatStore to equipItem()
which needs the crafting store (has equipmentInstances/equippedInstances).
Fixed by using useCraftingStore instead.
Bug 2: processCraftingTick() from crafting-slice.ts was never called in the
game tick loop. Added call in tick-logic.ts when currentAction is
'design'/'prepare'/'enchant'/'craft' so enchantment progress advances.
Bug 3: equipmentSpellStates was initialized as [] and never populated from
equipped items. Added logic in tick-logic.ts to build equipmentSpellStates
from active equipment spells when climbing (currentAction === 'climb').
- 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)
- SkillDebug.tsx: Use useSkillStore.getState().incrementSkillLevel() and setSkillLevel() instead of direct setState
- ElementDebug.tsx: Use getState() for consistency
- AttunementDebug.tsx: When unlocking Enchanter, also unlock transference element
- GameStateDebug.tsx: Use proper store actions (debugSetFloor, resetFloorHP, debugSetTime) and fix Switch component usage
- SkillsTab.tsx: Replace useGameStore with useSkillStore for currentStudyTarget
- SkillUpgradeDialog.tsx: Migrate to useSkillStore, fix commitSkillUpgrades call
- SkillRow.tsx: Remove parallel study feature (startParallelStudySkill doesn't exist in skillStore), remove hasParallelStudy reference
- Update index.ts export to point to new SkillsTab location
- Delete old legacy tabs/SkillsTab.tsx file
- 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.)
- Fix game loop store mismatch (page.tsx was using old store, gameHooks using new store)
- Fix StatsTab.tsx calling getStudySpeedMultiplier with wrong arguments
- Add ErrorBoundary to page.tsx for better error handling
- Fix import syntax issues in page.tsx
- Ensure build succeeds with fixes