# 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; ``` **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.