feat: add prestige system and skill upgrades with comprehensive documentation
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 5m57s

This commit is contained in:
Refactoring Agent
2026-05-01 15:18:09 +02:00
parent 3691aa4acc
commit 03815f27ee
52 changed files with 4056 additions and 873 deletions
+174
View File
@@ -0,0 +1,174 @@
# Task 16: Gate Mana Capacity Research Visibility by Unlocked Mana Type (PRIORITY 4b)
## Context Summary
### 1. How Research Nodes Are Currently Filtered/Displayed
**Location:** `/home/user/repos/Mana-Loop/src/components/game/tabs/SkillsTab.tsx`
**Current Filtering Mechanism:**
- Skills are organized by categories defined in `SKILL_CATEGORIES` (from `/home/user/repos/Mana-Loop/src/lib/game/constants/skills.ts`)
- The `SkillsTab` component uses `getAvailableSkillCategories(store.attunements || {})` to determine which skill categories to display
- `getAvailableSkillCategories` (from `/home/user/repos/Mana-Loop/src/lib/game/data/attunements.ts`) returns categories based on active attunements:
- Always available: `'mana'`, `'study'`, `'research'`, `'ascension'`
- Enchanter attunement adds: `'enchant'`, `'effectResearch'`
- Invoker attunement adds: `'invocation'`, `'pact'`
- Fabricator attunement adds: `'fabrication'`, `'golemancy'`
- Legacy: `'craft'`
**Skill Display Logic (SkillsTab.tsx lines 200-220):**
```typescript
const availableCategories = getAvailableSkillCategories(store.attunements || {});
return SKILL_CATEGORIES
.filter(cat => availableCategories.includes(cat.id))
.map((cat) => {
const skillsInCat = Object.entries(SKILLS_DEF).filter(([, def]) => def.cat === cat.id);
// ... render skills
});
```
**Prerequisites Checking (SkillsTab.tsx lines 269-280):**
- Skills check `def.req` (skill prerequisites)
- Skills check `def.attunementReq` (attunement level requirements)
- Skills with element costs check if player has enough element mana (but skill is still VISIBLE)
**Key Point:** Mana capacity research skills (e.g., `fireManaCap`, `waterManaCap`) are currently ALWAYS visible in the "Mana" category (which is always available). They just show as "cannot study" if the player lacks the required element mana.
---
### 2. Unlocked Mana Types State
**Location:** `/home/user/repos/Mana-Loop/src/lib/game/store.ts` and `/home/user/repos/Mana-Loop/src/lib/game/types/elements.ts`
**GameState Elements Structure:**
```typescript
elements: Record<string, ElementState>;
```
**ElementState Interface:**
```typescript
interface ElementState {
current: number; // Current mana amount
max: number; // Maximum capacity
unlocked: boolean; // Whether this element type is unlocked
}
```
**Base Unlocked Elements:**
- Defined in `/home/user/repos/Mana-Loop/src/lib/game/constants/elements.ts`
- `BASE_UNLOCKED_ELEMENTS = ['transference']` - Only transference is unlocked at game start
**Element Unlocking Mechanisms:**
1. **`unlockElement(element)` action** (store.ts line 2123): Costs 500 raw mana, sets `unlocked: true`
2. **`craftComposite(target)` action**: Automatically unlocks composite elements when crafted
3. **Enchanter attunement**: Auto-unlocks transference element (store.ts line 695)
**All Element Types (from ELEMENTS constant):**
- Base: `fire`, `water`, `air`, `earth`, `light`, `dark`, `death`
- Utility: `transference`
- Composite: `metal` (fire+earth), `sand` (earth+water), `lightning` (fire+air)
- Exotic: `crystal` (sand+sand+light), `stellar` (fire+fire+light), `void` (dark+dark+death)
---
### 3. Mana Capacity Research Skills
**Location:** `/home/user/repos/Mana-Loop/src/lib/game/constants/skills.ts`
**Mana Capacity Research Nodes (lines 9-21):**
```typescript
// Per-mana-type capacity upgrades (Bug 9)
fireManaCap: { name: "Fire Mana Capacity +10%", desc: "...", cat: "mana", max: 10, base: 200, studyTime: 4, cost: { type: 'element', element: 'fire', amount: 100 } },
waterManaCap: { name: "Water Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'water', amount: 100 } },
airManaCap: { name: "Air Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'air', amount: 100 } },
earthManaCap: { name: "Earth Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'earth', amount: 100 } },
lightManaCap: { name: "Light Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'light', amount: 150 } },
darkManaCap: { name: "Dark Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'dark', amount: 150 } },
deathManaCap: { name: "Death Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'death', amount: 200 } },
// Composite element capacity upgrades
metalManaCap: { name: "Metal Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'metal', amount: 250 } },
sandManaCap: { name: "Sand Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'sand', amount: 250 } },
lightningManaCap: { name: "Lightning Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'lightning', amount: 250 } },
// Utility mana capacity upgrades
transferenceManaCap: { name: "Transference Mana Capacity +10%", cat: "mana", cost: { type: 'element', element: 'transference', amount: 100 } },
```
**Key Observation:** Each mana capacity skill has:
- `cost.type: 'element'`
- `cost.element`: The element type this skill applies to
- `cost.amount`: The element mana required to study
---
### 4. How to Gate Capacity Research by Unlocked Mana Type
**Objective:** Hide mana capacity research skills unless the corresponding element type is unlocked.
**Implementation Approach:**
1. **In SkillsTab.tsx, add filtering logic for mana capacity skills:**
When rendering skills in the "mana" category, check if the skill:
- Has `def.cost?.type === 'element'`
- AND `store.elements[def.cost.element]?.unlocked === true`
2. **Modified SkillsTab rendering (around line 220):**
```typescript
{skillsInCat.map(([id, def]) => {
// GATE MANA CAPACITY SKILLS BY UNLOCKED ELEMENT
if (def.cost?.type === 'element') {
const element = store.elements[def.cost.element];
if (!element?.unlocked) {
return null; // Don't render this skill
}
}
// ... rest of skill rendering
})}
```
3. **Alternative: Filter at category level (less granular):**
- Could filter `skillsInCat` before mapping:
```typescript
const visibleSkills = skillsInCat.filter(([id, def]) => {
if (def.cost?.type === 'element') {
return store.elements[def.cost.element]?.unlocked;
}
return true; // Show non-element-cost skills
});
```
4. **Optional: Show locked state instead of hiding:**
- Could show a "locked" badge or tooltip explaining the element needs to be unlocked first
- This would require modifying the skill rendering to handle a "locked due to element not unlocked" state
---
### 5. Files to Modify
1. **`/home/user/repos/Mana-Loop/src/components/game/tabs/SkillsTab.tsx`**
- Add filtering logic to hide mana capacity research skills when the corresponding element is not unlocked
- Location: Around line 220 in the `skillsInCat.map()` function
2. **No backend/store changes needed** - The `unlocked` state already exists in `store.elements`. This is purely a UI/display change.
---
### 6. Testing Considerations
- Test that `fireManaCap` is hidden when `store.elements['fire'].unlocked === false`
- Test that `fireManaCap` becomes visible after calling `store.unlockElement('fire')`
- Test that non-element-cost skills (like `manaWell`, `manaFlow`) are always visible
- Test composite element skills (`metalManaCap`, etc.) hide/show correctly
- Test that the "Mana" category still shows other non-gated skills even when some are hidden
---
### 7. Related Task Context
This task is related to:
- **Task 9 (Bug 9)**: Per-mana-type capacity upgrades - the skills being gated were added in this task
- **Task 12 (Bug 12)**: Research moved to Mana category - this is why capacity research is in the "mana" category
---
**Summary:** The gating logic needs to be added to `SkillsTab.tsx` to filter out mana capacity research skills (`*ManaCap`) when `store.elements[element].unlocked` is `false`. The state already tracks unlocked elements, so no store changes are needed.