# Attunement System — Design Spec > Describes the three-attunement class system: Enchanter, Invoker, and Fabricator. > Covers slot assignments, unlock conditions, leveling, regen/conversion scaling, > discipline pool gating, and interaction with mana conversion and the incursion system. --- ## 1. Objective Attunements are class-like specializations that gate access to discipline pools and unique capabilities. A player can have multiple attunements active simultaneously, each contributing raw mana regen and (for Enchanter and Fabricator) automatic mana conversion. Attunements level up independently through attunement-specific XP sources, scaling their regen and conversion rates exponentially. **Design goals:** - Three distinct attunements with unique identities and roles - Attunements unlock over time, expanding the player's options - Leveling provides meaningful exponential scaling without being mandatory - Discipline pool access is gated behind attunement unlock status - Invoker's lack of primary mana creates a distinct pact-dependent playstyle --- ## 2. The Three Attunements ### 2.1 Enchanter (Right Hand) — Starting Attunement | Property | Value | |---|---| | **ID** | `enchanter` | | **Slot** | `rightHand` | | **Icon** | `✨` | | **Color** | `#1ABC9C` (Teal) | | **Primary Mana** | `transference` | | **Raw Mana Regen** | +0.5/hour (base) | | **Conversion Rate** | 0.2 raw→transference/hour (base) | | **Unlock** | Starting (unlocked by default) | | **Capabilities** | `['enchanting']` | | **Skill Categories** | `['enchant', 'effectResearch']` | **Disciplines:** 10 disciplines across 4 files (core: 4, utility: 2, spells: 3, special: 1) ### 2.2 Invoker (Chest) — Locked | Property | Value | |---|---| | **ID** | `invoker` | | **Slot** | `chest` | | **Icon** | `💜` | | **Color** | `#9B59B6` (Purple) | | **Primary Mana** | None (gains elemental mana from pacts) | | **Raw Mana Regen** | +0.3/hour (base) | | **Conversion Rate** | None (0 at all levels) | | **Unlock** | Defeat first Guardian | | **Capabilities** | `['pacts', 'guardianPowers', 'elementalMastery']` | | **Skill Categories** | `['invocation', 'pact']` | **Disciplines:** 2 disciplines ### 2.3 Fabricator (Left Hand) — Locked | Property | Value | |---|---| | **ID** | `fabricator` | | **Slot** | `leftHand` | | **Icon** | `⚒️` | | **Color** | `#F4A261` (Earth) | | **Primary Mana** | `earth` | | **Raw Mana Regen** | +0.4/hour (base) | | **Conversion Rate** | 0.25 raw→earth/hour (base) | | **Unlock** | Prove crafting worth | | **Capabilities** | `['golemCrafting', 'gearCrafting', 'earthShaping']` | | **Skill Categories** | `['fabrication', 'golemancy']` | **Disciplines:** 5 disciplines --- ## 3. Unlock Conditions | Attunement | Condition | Implementation | |---|---|---| | **Enchanter** | Starting | Present in initial state: `{ active: true, level: 1, experience: 0 }` | | **Invoker** | Defeat first Guardian | Descriptive: `"Defeat your first guardian and choose the path of the Invoker"` | | **Fabricator** | Prove crafting worth | Descriptive: `"Prove your worth as a crafter"` | Unlocking is performed via `debugUnlockAttunement(attunementId)` in the store, which initializes the attunement at `{ active: true, level: 1, experience: 0 }`. The conditions are currently descriptive strings rather than hard-coded mechanical checks. --- ## 4. Attunement Leveling ### 4.1 XP Thresholds ``` Level 1: 0 XP (starting) Level 2: 1,000 XP Level ≥ 3: Math.floor(1000 * Math.pow(2, level - 2) * 1.25) ``` | Level | XP Threshold | Cumulative XP | |---|---|---| | 1 | 0 | 0 | | 2 | 1,000 | 1,000 | | 3 | 2,500 | 3,500 | | 4 | 5,000 | 8,500 | | 5 | 10,000 | 18,500 | | 6 | 20,000 | 38,500 | | 7 | 40,000 | 78,500 | | 8 | 80,000 | 158,500 | | 9 | 160,000 | 318,500 | | 10 | 320,000 | 638,500 | **Max Level:** `MAX_ATTUNEMENT_LEVEL = 10` ### 4.2 Level-Up Mechanism ``` addAttunementXP(attunementId, amount): state.experience += amount while state.experience >= xpForNextLevel && level < MAX: state.experience -= xpForNextLevel level += 1 log("Attunement leveled up!") ``` XP does **not** roll over beyond the threshold check — the threshold amount is subtracted and any remainder carries into the next level. ### 4.3 Regen and Conversion Rate Scaling Both raw mana regen and conversion rate use the same exponential formula: ``` scaledValue = baseValue × 1.5^(level - 1) ``` **Effective raw mana regen by level (per attunement):** | Level | Enchanter (0.5) | Invoker (0.3) | Fabricator (0.4) | |---|---|---|---| | 1 | 0.500/hr | 0.300/hr | 0.400/hr | | 2 | 0.750/hr | 0.450/hr | 0.600/hr | | 3 | 1.125/hr | 0.675/hr | 0.900/hr | | 4 | 1.688/hr | 1.013/hr | 1.350/hr | | 5 | 2.531/hr | 1.519/hr | 2.025/hr | | 6 | 3.797/hr | 2.278/hr | 3.038/hr | | 7 | 5.695/hr | 3.417/hr | 4.556/hr | | 8 | 8.543/hr | 5.126/hr | 6.834/hr | | 9 | 12.814/hr | 7.689/hr | 10.252/hr | | 10 | 19.221/hr | 11.533/hr | 15.377/hr | **Effective conversion rate by level:** | Level | Enchanter (0.2) | Fabricator (0.25) | |---|---|---| | 1 | 0.200/hr | 0.250/hr | | 2 | 0.300/hr | 0.375/hr | | 3 | 0.450/hr | 0.563/hr | | 4 | 0.675/hr | 0.844/hr | | 5 | 1.013/hr | 1.266/hr | | 6 | 1.519/hr | 1.898/hr | | 7 | 2.278/hr | 2.848/hr | | 8 | 3.417/hr | 4.271/hr | | 9 | 5.126/hr | 6.407/hr | | 10 | 7.689/hr | 9.610/hr | Invoker has `conversionRate = 0` at all levels — no auto-conversion. **Total regen** = sum of `baseRegen × 1.5^(level-1)` across all active attunements. **Total conversion drain** = sum of `baseConversionRate × 1.5^(level-1)` across active attunements that have a non-zero conversion rate. This drain is applied to the raw mana pool. --- ## 5. Attunement XP Gain Sources ### 5.1 Enchanting → Enchanter XP ```typescript calculateEnchantingXP(capacityUsed: number): number { return Math.max(1, Math.floor(capacityUsed / 10)); } ``` - 1 Enchanter XP per 10 capacity used (floored), minimum 1 XP per enchant. ### 5.2 Other Sources The `addAttunementXP(attunementId, amount)` store action is the generic mechanism. Any system can call it to award XP to any attunement. In the codebase as-is, only enchanting has an explicit calculation function. Invoker and Fabricator XP gain is expected to be called from their respective systems (pact signing and item fabrication) but explicit calculation functions are not yet defined. --- ## 6. Discipline Pool Gating ### 6.1 Skill Categories Attunements gate discipline access through **skill categories**: | Category | Disciplines | |---|---| | Always available | `mana`, `study`, `research` | | Enchanter | `enchant`, `effectResearch` | | Invoker | `invocation`, `pact` | | Fabricator | `fabrication`, `golemancy` | The function `getAvailableSkillCategories()` iterates all **active** attunements, collects their `skillCategories` into a Set, and returns the deduplicated array. ### 6.2 Discipline Pool Counts per Attunement | Attunement | File | Count | |---|---|---| | Enchanter Core | `enchanter.ts` | 4 | | Enchanter Utility | `enchanter-utility.ts` | 2 | | Enchanter Spells | `enchanter-spells.ts` | 3 | | Enchanter Special | `enchanter-special.ts` | 1 | | Invoker | `invoker.ts` | 2 | | Fabricator | `fabricator.ts` | 5 | | **Attunement-gated total** | | **17** | The remaining 47 disciplines are available regardless of attunement status (base, elemental, elemental-regen, elemental-regen-advanced pools). ### 6.3 Capability Gating Each attunement grants `capabilities` that unlock specific game systems: | Capability | System | |---|---| | `enchanting` | Enchantment Design/Prepare/Apply pipeline | | `pacts` | Guardian pact signing and boon system | | `guardianPowers` | Guardian power access | | `elementalMastery` | Element mastery bonuses | | `golemCrafting` | Golem summoning (Golemancy) | | `gearCrafting` | Gear fabrication recipes | | `earthShaping` | Earth mana shaping | --- ## 7. Mana Conversion Interaction ### 7.1 Conversion Flow Each tick, the mana system: 1. Computes total raw regen (base + attunement regen + discipline bonus + equipment) × temporalEcho × meditationMultiplier 2. Subtracts incursion reduction: `× (1 - incursionStrength)` 3. Computes total conversion drain: sum of all active attunement conversion rates 4. Applies: `rawMana += totalRegen - totalConversionDrain` (per tick) 5. For each attunement with conversion: adds `conversionRate × HOURS_PER_TICK` to the target element ### 7.2 Invoker's Unique Position The Invoker has **no automatic conversion** — `conversionRate = 0`. Instead, it gains elemental mana types exclusively by signing Guardian pacts. Each guardian's `unlocksMana` array is resolved through `resolveMultiUnlockChain(element)`, which unlocks the guardian's element and all base components. Example: Signing a Metal guardian (floor 90) unlocks `fire`, `earth`, and `metal`. ### 7.3 Conversion and Incursion Incursion reduces net raw mana regeneration: ``` effectiveRegen = max(0, baseRegen × (1 - incursionStrength) × meditationMult - totalConversionPerTick) ``` As incursion strength approaches 95% (day 30), conversion drains can exceed regen, causing raw mana to decrease. Since conversion is contingent on available raw mana, attunement conversion effectively stalls during peak incursion if the raw pool is insufficient. --- ## 8. Puzzle Room Interaction From `spire-climbing-spec.md` §4.3, puzzle rooms appear on every 7th floor and have per-attunement variants: | Room Type | Description | |---|---| | `enchanter_trial` | Enchanter-themed puzzle challenge | | `fabricator_trial` | Fabricator-themed puzzle challenge | | `invoker_trial` | Invoker-themed puzzle challenge | | `hybrid_enchanter_fabricator` | Dual attunement challenge | | `hybrid_enchanter_invoker` | Dual attunement challenge | | `hybrid_fabricator_invoker` | Dual attunement challenge | **Time-based progression system:** Each puzzle room has a base time requirement that varies by floor range (4h for floors 1–20, 8h for 21–50, 16h for 51–100, 24h for 101+). Each relevant attunement reduces the total time needed, up to a maximum 90% reduction shared across all relevant attunements. Progress accumulates at `HOURS_PER_TICK` (0.04h) per tick. The room completes when `puzzleProgress >= puzzleRequired`. --- ## 9. State Fields ```typescript interface AttunementState { id: string; active: boolean; level: number; // 1–10 experience: number; // current XP toward next level } // Initial state (prestige): attunements: { enchanter: { id: 'enchanter', active: true, level: 1, experience: 0 } } ``` --- ## 10. Acceptance Criteria | # | Criterion | |---|---| | AC-1 | Enchanter is the only active attunement at game start (level 1, 0 XP). | | AC-2 | Invoker and Fabricator are locked until unlocked; their unlock conditions are displayed in the Attunements tab. | | AC-3 | Attunement XP accumulates and triggers level-ups at the correct thresholds; each level requires the exact XP specified in the formula. | | AC-4 | Regen and conversion rates scale by `1.5^(level-1)` — a level 10 Enchanter converts at 7.69 raw→transference/hour. | | AC-5 | Both raw regen and conversion from all active attunements are summed and applied each tick. | | AC-6 | Invoker has no automatic mana conversion at any level. | | AC-7 | Enchanting awards Enchanter XP at 1 per 10 capacity used (minimum 1). | | AC-8 | Attunement skill categories correctly gate discipline pool access — Enchanter disciplines require Enchanter to be active. | | AC-9 | Attunement tab shows unlocked/locked visual distinction, XP progress bar, level badge, and all attunement capabilities. | | AC-10 | Puzzle rooms on every 7th floor use per-attunement room types with the correct progress scaling. | | AC-11 | Incursion correctly reduces net raw mana regeneration, potentially stalling conversion at peak incursion. | --- ## 11. Files Reference | File | Role | |---|---| | `src/lib/game/data/attunements.ts` | Attunement definitions (the 3 attunements) | | `src/lib/game/stores/attunementStore.ts` | Attunement state, leveling, XP, unlock | | `src/lib/game/types/attunements.ts` | Attunement type definitions | | `src/components/game/tabs/AttunementsTab.tsx` | Attunement UI display | | `src/lib/game/stores/manaStore.ts` | Mana regen, conversion, incursion effects | | `docs/specs/spire-climbing-spec.md` | Puzzle room types per attunement |