# Task6-1 Context: Proposal 1 - Unlocked Mana Type Capacity ## Overview Gathered context for implementing Proposal 1: Unlocked Mana Type Capacity. This proposal likely relates to either: 1. Increasing the mana capacity (max) of unlocked mana types 2. Increasing the number of mana types that can be unlocked ## 1. Existing Prestige Upgrade Structure **File:** `src/lib/game/constants/prestige.ts` ### PrestigeDef Interface (from `src/lib/game/types/skills.ts`) ```typescript export interface PrestigeDef { name: string; desc: string; max: number; cost: number; } ``` ### Current Prestige Upgrades (relevant to mana/elements) ```typescript export const PRESTIGE_DEF: Record = { // ... other upgrades ... // Existing elemental capacity upgrade elementalAttune: { name: "Elemental Attunement", desc: "+25 elemental mana cap", max: 10, cost: 600 }, // Starting elemental mana upgrade elemStart: { name: "Elem. Start", desc: "Start with 5 of each unlocked element", max: 3, cost: 800 }, // ... other upgrades ... }; ``` **Key observations:** - All prestige upgrades use the same structure: name, description, max level, cost - `elementalAttune` already provides +25 elemental mana cap per level (max 10 levels = +250 cap) - `elemStart` gives starting elemental mana when a new loop begins - Upgrades are stored as `Record` where the value is the current level --- ## 2. How Mana Type Unlocks Are Tracked ### Element State Structure **File:** `src/lib/game/types/elements.ts` ```typescript export interface ElementState { current: number; max: number; unlocked: boolean; } ``` ### Elements Storage in GameState **File:** `src/lib/game/types/game.ts` ```typescript export interface GameState { // ... elements: Record; // ... } ``` ### Base Unlocked Elements **File:** `src/lib/game/constants/elements.ts` ```typescript export const BASE_UNLOCKED_ELEMENTS = ['transference']; ``` **Key observations:** - Only `transference` starts unlocked by default - All other 12 elements (fire, water, air, earth, light, dark, death, metal, sand, lightning, crystal, stellar, void) start locked - Elements have a boolean `unlocked` field - no partial unlocking or limits on number of unlocked types ### Unlocking New Elements **File:** `src/lib/game/store.ts` (lines 2176-2195) ```typescript unlockElement: (element: string) => { const state = get(); if (state.elements[element]?.unlocked) return; const cost = 500; if (state.rawMana < cost) return; // ELEMENTAL_AFFINITY: New elements start with 10 capacity const effects = getUnifiedEffects(state.skillUpgrades, state.skillTiers); const newElementMax = hasSpecial(effects, SPECIAL_EFFECTS.ELEMENTAL_AFFINITY) ? 10 : 0; set({ rawMana: state.rawMana - cost, elements: { ...state.elements, [element]: { ...state.elements[element], unlocked: true, max: newElementMax }, }, log: [`✨ ${ELEMENTS[element].name} affinity unlocked!`, ...state.log.slice(0, 49)], }); }, ``` **Key observations:** - Unlocking an element costs 500 raw mana - When unlocked, the element gets `unlocked: true` - New elements start with `max: 0` unless ELEMENTAL_AFFINITY special effect is active (then max: 10) - No limit on the NUMBER of elements that can be unlocked - players can unlock all 12+ types ### Element Definitions **File:** `src/lib/game/constants/elements.ts` Total element types: - **Base (7):** fire, water, air, earth, light, dark, death - **Utility (1):** transference - **Composite (3):** metal, sand, lightning - **Exotic (3):** crystal, stellar, void **Total: 14 element types** (13 unlockable + transference which starts unlocked) --- ## 3. How Mana Capacity Is Applied ### computeElementMax Function **File:** `src/lib/game/store.ts` (lines 415-432) ```typescript export function computeElementMax( state: Pick, effects?: ComputedEffects | UnifiedEffects, element?: string ): number { const pu = state.prestigeUpgrades; const base = 10 + (state.skills.elemAttune || 0) * 50 + (pu.elementalAttune || 0) * 25; // Apply upgrade effects if provided if (effects) { let bonus = effects.elementCapBonus; // Global bonus // Add per-element bonus if element is specified and available if (element && (effects as UnifiedEffects).perElementCapBonus) { const perElementBonus = (effects as UnifiedEffects).perElementCapBonus[element]; if (perElementBonus) { bonus += perElementBonus; } } return Math.floor((base + bonus) * effects.elementCapMultiplier); } return base; } ``` **Key observations:** - Base capacity formula: `10 + (elemAttune skill levels * 50) + (elementalAttune prestige levels * 25)` - Effects system can modify capacity via: - `elementCapBonus`: Global flat bonus - `elementCapMultiplier`: Global multiplier - `perElementCapBonus[element]`: Per-element flat bonus (from equipment) - **Currently, all unlocked elements share the SAME max capacity** (calculated once and applied to all) - The `perElementCapBonus` exists but is currently only used for equipment effects ### Usage in Store Initialization **File:** `src/lib/game/store.ts` (lines 670-710) ```typescript function makeInitial(overrides: Partial = {}): GameState { const pu = overrides.prestigeUpgrades || {}; // ... const elemMax = computeElementMax( { skills: overrides.skills || {}, prestigeUpgrades: pu, skillUpgrades: overrides.skillUpgrades, skillTiers: overrides.skillTiers }, effects ); const elements: Record = {}; Object.keys(ELEMENTS).forEach((k) => { const isUnlocked = BASE_UNLOCKED_ELEMENTS.includes(k); let startAmount = 0; // Start with some elemental mana if elemStart upgrade if (isUnlocked && pu.elemStart) { startAmount = pu.elemStart * 5; } elements[k] = { current: overrides.elements?.[k]?.current ?? startAmount, max: elemMax, // <-- Same max for ALL elements unlocked: isUnlocked, }; }); // ... } ``` **Key observation:** The same `elemMax` is applied to ALL elements regardless of type or unlock status. --- ## 4. Save Data Structure (Cross-Loop Persistence) ### GameState Prestige-Related Fields **File:** `src/lib/game/types/game.ts` ```typescript export interface GameState { // ... // Prestige insight: number; totalInsight: number; prestigeUpgrades: Record; memorySlots: number; memories: string[]; // Elements elements: Record; // ... } ``` ### What Persists Through Loops **File:** `src/lib/game/store.ts` (lines 2255-2290) ```typescript startNewLoop: () => { const state = get(); const insightGained = state.loopInsight || calcInsight(state); const total = state.insight + insightGained; // ... (keep some spells through temporal memory) const newState = makeInitial({ loopCount: state.loopCount + 1, insight: total, totalInsight: (state.totalInsight || 0) + insightGained, prestigeUpgrades: state.prestigeUpgrades, // <-- PERSISTS memories: state.memories, skills: state.skills, manaHeartBonus: newHeartBonus, }); // ... set(newState); }, ``` **Key observations:** - `prestigeUpgrades` (all upgrade levels) persist through loops - `insight` and `totalInsight` persist and accumulate - `elements` are NOT persisted - they are reinitialized in `makeInitial()` - On new loop, element unlocks are lost (player must re-unlock elements) - `BASE_UNLOCKED_ELEMENTS` and `pu.elemStart` determine which elements start unlocked/have starting mana ### Purchasing Prestige Upgrades **File:** `src/lib/game/store.ts` (lines 2235-2250) ```typescript doPrestige: (id: string) => { // ... const lvl = state.prestigeUpgrades[id] || 0; if (lvl >= pd.max || state.insight < pd.cost) return; const newPU = { ...state.prestigeUpgrades, [id]: lvl + 1 }; set({ insight: state.insight - pd.cost, prestigeUpgrades: newPU, // ... }); }, ``` **Key observations:** - Upgrades purchased with `insight` currency - Each level costs the same amount (flat cost model) - Max level check prevents over-purchasing - New upgrade level is saved to `prestigeUpgrades` record --- ## Summary of Key Points for Task6-1 1. **Prestige upgrades** follow a simple structure: `{ name, desc, max, cost }` 2. **Element capacity** is currently global (same for all elements), calculated from: - Base: 10 - Skill: `elemAttune` levels × 50 - Prestige: `elementalAttune` levels × 25 - Effects: bonuses and multipliers 3. **Element unlocks** are per-type (boolean), cost 500 raw mana each 4. **No limit** on number of unlocked element types currently exists 5. **Per-element capacity** bonuses exist in effects system (`perElementCapBonus`) but aren't widely used 6. **Cross-loop persistence:** prestige upgrades and insight persist; element unlocks do NOT persist 7. **14 total element types** available (13 unlockable + transference) ## Questions for Implementation Depending on what "Unlocked Mana Type Capacity" means: **If it means increasing capacity (max mana) of unlocked types:** - Could add a new prestige upgrade similar to `elementalAttune` - Could modify the `computeElementMax` function - Could add per-element capacity tracking **If it means increasing the NUMBER of types that can be unlocked:** - Need to add a limit/cap on unlocked types (currently unlimited) - Need to add a prestige upgrade to increase this limit - Need to modify `unlockElement` to check against the limit