diff --git a/docs/SPEC-SpireTab-refresh.md b/docs/SPEC-SpireTab-refresh.md new file mode 100644 index 0000000..81a98f6 --- /dev/null +++ b/docs/SPEC-SpireTab-refresh.md @@ -0,0 +1,142 @@ +# 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. diff --git a/docs/project-structure.txt b/docs/project-structure.txt index 109885f..88fb0bf 100644 --- a/docs/project-structure.txt +++ b/docs/project-structure.txt @@ -12,6 +12,7 @@ Mana-Loop/ │ └── custom.db ├── docs/ │ ├── GAME_BRIEFING.md +│ ├── SPEC-SpireTab-refresh.md │ ├── project-structure.txt │ └── skills.md ├── download/