# SPEC: SpireTab Refresh & Casting Fixes ## 1. Objective Fix multiple issues with the SpireTab and spell casting system: 1. **Cast bar not updating**: Spell cast progress (`castProgress`) doesn't update visually during combat 2. **Casting doesn't cost mana**: Mana costs are not deducted when spells are cast 3. **SpireTab full-screen experience**: SpireTab should be a dedicated screen where: - Player cannot study skills (must climb down to exit spire first) - Layout is optimized for combat focus 4. **Confusing layout**: Current SpireTab layout is cluttered and needs refresh for better UX **Why**: - Casting feels broken when progress bar doesn't update - Players get free spells (no mana cost) which breaks game balance - Spire should feel like a separate "mode" with focused combat - Current layout confuses players about available actions ## 2. Controls/API ### Player-Facing Controls - **Climb Up/Down buttons**: Change floors (already exists) - **Spell selection**: Click to set active spell (already exists) - **Enter Spire Mode**: Button to enter dedicated spire screen (already exists) - **Cast progress bar**: Visual indicator of spell casting progress (BROKEN - needs fix) - **Climb Down to Exit**: Only way to leave spire mode (NEW behavior) ### Modified Game Internals - `combatStore.ts`: - `castProgress`: Should update 0-1 per tick (fix binding) - `processCombatTick()`: Should properly deduct mana costs via `deductSpellCost()` - `SpireTab.tsx`: - Remove study progress components (player can't study in spire) - Remove crafting progress components (irrelevant in spire) - Add "Climb Down" button to exit spire mode - Refresh layout for clarity ### Public API Changes None (internal bug fixes + UI refresh) ## 3. Project Layout Follow modular architecture rules from AGENTS.md: ### Files to Modify | File | Purpose | Line Count Check | |------|---------|------------------| | `src/components/game/tabs/SpireTab.tsx` | Main SpireTab component - refresh layout, remove study/crafting | Must stay <400 lines | | `src/components/game/tabs/SpireHeader.tsx` | Spire header - ensure maxFloorReached works | Must stay <400 lines | | `src/components/game/tabs/FloorControls.tsx` | Floor controls - add "Climb Down to Exit" | Must stay <400 lines | | `src/lib/game/stores/combat-actions.ts` | Fix mana deduction in `processCombatTick()` | Must stay <400 lines | | `src/lib/game/stores/combatStore.ts` | Ensure `castProgress` updates correctly | Must stay <400 lines | ### Files to Create | File | Purpose | Line Count Check | |------|---------|------------------| | None (modifying existing files only) | | | ### Stores to Use (NO LEGACY STORES!) - ✅ `useCombatStore` from `src/lib/game/stores/combatStore` - ✅ `useManaStore` from `src/lib/game/stores/manaStore` - ✅ `usePrestigeStore` from `src/lib/game/stores/prestigeStore` - ❌ NO `import from '@/lib/game/store'` (legacy!) - ❌ NO `import from '@/lib/game/store-modules/'` (legacy!) ### Module Ownership - SpireTab UI: `components/game/tabs/` - Combat logic: `stores/combat-actions.ts` - Store state: `stores/combatStore.ts` ## 4. Code Style Follow existing project conventions: - TypeScript strict mode, explicit type annotations - Zustand store patterns: `set()`, `get()` for state updates - Use modular stores ONLY (AGENTS.md rule) - Naming: camelCase for variables/functions, PascalCase for interfaces/types - No `any` types, use defined interfaces from `src/lib/game/types/` - Follow ESLint rules (run `npm run lint` before committing) - Use existing patterns for combat/spell casting ### Key Patterns - Cast progress: `useCombatStore((s) => s.castProgress)` (0-1 value) - Mana deduction: Use `deductSpellCost()` from `src/lib/game/utils/` - Guard against undefined stores: Optional chaining `state?.castProgress` ## 5. Testing ### What to Test 1. **Cast bar updates**: `castProgress` changes during combat ticks 2. **Mana costs deducted**: Raw mana/elements decrease when spells cast 3. **No studying in spire**: Study components not rendered when `simpleMode=true` 4. **Climb down to exit**: Button appears in spire mode, clears `spireMode` 5. **Layout refresh**: SpireTab renders cleanly without clutter ### How to Test - Unit tests using Vitest (existing test framework) - Test files in `src/lib/game/stores/__tests__/` - Mock game state to simulate combat ticks - Assert castProgress changes over time - Assert mana decreases after spell cast - Use `useCombatStore.getState()` for assertions ### Tooling - Vitest (test runner) - Zustand store testing patterns (use `getState()`) - Mock `deductSpellCost()` to verify calls ## 6. Boundaries (Out-of-Scope Items) - No changes to spell definitions or damage calculations - No changes to attunement system (separate from spire) - No changes to prestige/system (unless directly related to spire exit) - No new tabs or major architectural changes - No changes to legacy store (we're avoiding it, not fixing it here) - No changes to other tabs (SkillsTab, CraftingTab, etc.) ## Acceptance Criteria (Per Requirement) | # | Requirement | Acceptance Criterion | |---|-------------|----------------------| | 1 | Cast bar updates during spell casting | `castProgress` in combatStore changes 0→1 over time, and UI reflects this | | 2 | Casting costs mana | `rawMana` or element mana decreases by `spell.cost` when spell completes | | 3 | SpireTab is full-screen combat focus | Study/Crafting components NOT rendered when `simpleMode=true` | | 4 | Player must climb down to exit spire | "Climb Down" button visible in spire mode, clears `spireMode` on click | | 5 | Layout refresh for clarity | SpireTab has clear sections: Floor Info, Combat, Controls (no clutter) | | 6 | Use modular stores only | Zero imports from `store.ts` or `store-modules/` in modified files | | 7 | All files <400 lines | Pre-commit hook passes for all modified files | | 8 | Regression tests added | New test file `spire-tab-refresh.test.ts` passes in `npm run test` | ## Verification Checklist (Do NOT implement until approved!) - ☐ SPEC.md committed to version control (not yet) - ☑ Every feature has explicit acceptance criterion (above) - ☑ Out-of-scope items listed (Boundaries section) - ☐ Human has reviewed and approved (**WAITING FOR THIS**) - ☐ No implementation code exists yet (correct - spec only) **I will NOT proceed to PLAN or IMPLEMENT phases until this spec is approved by you (the human).** Please review and approve, or request changes.