# Transference Channel — Design Spec > Describes the Transference Channel system: an active combat mechanic for the > Enchanter attunement that lets the player hold a button to drain Transference > mana and boost the cast speed of all equipment spells and melee attacks. --- ## 1. Objective The Enchanter attunement currently lacks an active combat mechanic. The Invocation system (Invoker attunement) provides automatic combat acceleration through guardian channeling. The Transference Channel gives the Enchanter a **manual, hold-to-channel button** that spends Transference mana to temporarily accelerate all equipment-based combat actions. **Design goals:** - Give the Enchanter an **active, holdable** combat button - Spend **Transference mana** — the only utility mana type — as the fuel - Boost **equipment spells and melee attacks only** — not the player's active spell - Create a **resource management decision**: channel now for burst speed, or conserve Transference for enchanting and disciplines - Scale through a new Enchanter discipline that trades mana cost for potency - Complement (not compete with) Invocation — different resource, different trigger, different target --- ## 2. The Channel Button ### 2.1 UI Placement A **"Channel Transference"** button on the `SpireCombatPage`, visible only when: - The Enchanter attunement is active (`attunements.enchanter.active === true`) - The player is in `climb` action (combat) - The player has at least 1 Transference mana ### 2.2 Interaction Model | Property | Value | |---|---| | **Interaction** | Press and hold (mousedown / touchstart) to channel, release to stop | | **Keyboard** | Optional hotkey (e.g., `C`) for accessibility | | **Visual** | Button glows while active; shows Transference drain rate | | **Cooldown** | None — player controls start/stop | The hold-to-channel interaction is intentional: it creates a "power moment" where the player chooses to actively engage. The game is fully playable without it — this is an optional acceleration for players who want active involvement. ### 2.3 Hold Behavior While the button is held: 1. Transference mana drains at `drainRate` per tick (see §3) 2. All equipment spells and melee attacks gain `speedMultiplier` cast speed 3. If Transference reaches 0: channel stops automatically (no penalty) 4. If player leaves `climb` action: channel stops automatically 5. If player releases button: channel stops immediately --- ## 3. Drain Rate and Speed Multiplier ### 3.1 Mana Economy Context Transference mana is generated slowly through the Enchanter's automatic conversion (0.2/hour at level 1, scaling with `1.5^(level-1)`). At level 10, this is ~7.69/hour. Transference is also the fuel for all Enchanter disciplines and the enchanting pipeline. The Channel system is designed as a **burst expenditure** — the player accumulates Transference over time and then spends it in combat for temporary acceleration. The drain rate must be high enough to create meaningful decisions ("can I afford to channel right now?") but not so high that it's trivially exhausted. ### 3.2 Base Values | Parameter | Base Value | Description | |---|---|---| | `baseDrainRate` | 0.08 Transference/tick | 0.4 Transference/second at 200ms/tick | | `baseSpeedMultiplier` | 1.5× | Equipment spells and melee attack 50% faster | ### 3.3 Duration Estimate At base values with various Transference pool sizes: | Transference Pool | Drain Rate | Approximate Duration | |---|---|---| | 20 | 0.08/tick | 250 ticks = 50 seconds | | 50 | 0.08/tick | 625 ticks = 125 seconds | | 100 | 0.08/tick | 1250 ticks = 250 seconds | With discipline scaling (e.g., 1.8× speed at ~1.8× drain): | Transference Pool | Drain Rate | Approximate Duration | |---|---|---| | 50 | 0.144/tick | 347 ticks = 69 seconds | | 100 | 0.144/tick | 694 ticks = 139 seconds | The discipline makes each "pool of Transference" worth less raw seconds but more effective combat time because actions complete faster. ### 3.4 Scaling with Discipline A new discipline (`transference-channeling`) controls the tradeoff between mana cost and speed: ``` effectiveDrainRate = baseDrainRate × (1 + intensityBonus) × (1 - channelEfficiency) effectiveSpeedMultiplier = baseSpeedMultiplier + speedBonus ``` Where `intensityBonus` and `speedBonus` come from the discipline's stat bonus and perks (see §5). **Design philosophy:** The discipline lets the player invest XP to get more speed, but at proportionally higher mana cost. Perks can shift the ratio in the player's favor (more speed per mana). --- ## 4. What Gets Boosted ### 4.1 Affected | Action | Boosted? | Notes | |---|---|---| | **Equipment spell casts** | ✅ Yes | All `equipmentSpellStates` cast progress | | **Melee sword attacks** | ✅ Yes | All `meleeSwordProgress` accumulators | ### 4.2 Not Affected | Action | Boosted? | Notes | |---|---|---| | **Player's active spell** | ❌ No | The manually-selected spell is not equipment | | **Invocation spells** | ❌ No | Invocation is pact-based, not equipment-based | | **Golem attacks** | ❌ No | Golems are independent entities | | **DoT ticks** | ❌ No | DoTs are time-based, not cast-based | ### 4.3 Implementation — Speed Multiplier Application The channel state is tracked in the combat store. When active, the multiplier is applied to `progressPerTick` calculations for equipment spells and melee: ``` // Equipment spells (in combat-actions.ts equipment spell block) const channelMult = state.isChanneling ? state.channelSpeedMultiplier : 1.0; const eProgressPerTick = HOURS_PER_TICK * eSpellCastSpeed * totalAttackSpeed * channelMult; // Melee (in combat-melee.ts) const channelMult = state.isChanneling ? state.channelSpeedMultiplier : 1.0; const meleeProgressPerTick = HOURS_PER_TICK * swordAttackSpeed * attackSpeedMult * channelMult; ``` **Important:** The speed multiplier only affects cast *progress accumulation*. It does NOT affect mana costs per cast. Equipment spells still cost the same mana per cast — they just complete faster. This prevents the feedback loop where faster casting drains mana exponentially faster. --- ## 5. New Discipline: Transference Channeling ### 5.1 Definition | Field | Value | |---|---| | **ID** | `transference-channeling` | | **Name** | Transference Channeling | | **Attunement** | `enchanter` | | **Mana Type** | `transference` | | **Base Cost** | 15 | | **Stat Bonus** | `channelIntensity` +0.10 (base) | | **Scaling Factor** | 100 | | **Difficulty Factor** | 180 | | **Drain Base** | 4 | **Main stat: `channelIntensity`** This stat controls both the speed boost and the drain rate: ``` speedBonus = channelIntensity × 0.5 // added to baseSpeedMultiplier intensityBonus = channelIntensity × 1.0 // multiplier on drain rate ``` At 0 XP: `channelIntensity = 0.10` → speed = 1.5 + 0.05 = 1.55×, drain = 0.08 × 1.10 = 0.088/tick. The stat scales with XP via the standard discipline math: ``` StatBonus = baseValue × (XP / scalingFactor)^0.65 = 0.10 × (XP / 100)^0.65 ``` ### 5.2 Perks | Perk ID | Type | Threshold | Bonus | Description | |---|---|---|---|---| | `channel-efficiency` | `once` | 100 | `channelEfficiency` +0.15 | 15% less drain for same speed — shifts the ratio in the player's favor | | `channel-power` | `infinite` | 200 | Every 150 XP: `channelIntensity` +0.05 | Core scaling — more speed (and proportionally more drain) | | `channel-mastery` | `capped` | 400 | Every 200 XP: `channelEfficiency` +0.10, max 3 tiers | Late-game efficiency — up to 45% less drain | ### 5.3 Effective Formulas with Perks ``` channelEfficiency = 0 + sum of efficiency perks (0.15 from once, up to 0.30 from capped) hard-capped at 0.60 — prevents drain rate from reaching 0 effectiveSpeedMultiplier = 1.5 + (channelIntensity × 0.5) effectiveDrainRate = 0.08 × (1 + channelIntensity × 1.0) × (1 - channelEfficiency) ``` > **The `channelEfficiency` cap of 0.60** is enforced in the formula itself. Even if > perk bonuses would exceed 0.60, the effective drain rate can never go below > `0.08 × (1 + intensity) × 0.40`. This ensures channeling always costs meaningful > Transference mana. **Example at 500 XP with all perks:** - `channelIntensity` = 0.10 × (500/100)^0.65 + 0.05 × 2 (two infinite intervals) ≈ 0.24 + 0.10 = 0.34 - `channelEfficiency` = 0.15 + 0.20 (two capped tiers) = 0.35 - Speed = 1.5 + 0.34 × 0.5 = 1.67× - Drain = 0.08 × (1 + 0.34) × (1 - 0.35) = 0.08 × 1.34 × 0.65 = 0.070/tick ### 5.4 Discipline Identity *"I channel transference mana through my equipment, making my enchanted gear strike and cast faster. The more I master this, the faster I go — but it costs more mana to sustain."* --- ## 6. Store Changes ### 6.1 Combat Store (`combatStore.ts`) New state fields: ```typescript // Transference Channel state isChanneling: boolean; // true while button is held channelSpeedMultiplier: number; // current speed multiplier (1.5+) channelDrainRate: number; // current drain rate per tick ``` New actions: ```typescript startChanneling: () => void; stopChanneling: () => void; ``` ### 6.2 Combat State Types (`combat-state.types.ts`) Add to `CombatState`: ```typescript isChanneling: boolean; channelSpeedMultiplier: number; channelDrainRate: number; ``` Add to `CombatActions`: ```typescript startChanneling: () => void; stopChanneling: () => void; ``` ### 6.3 No Changes To - `manaStore.ts` — Transference mana is drained via existing element deduction - `craftingStore.ts` — enchanting is unaffected - `prestigeStore.ts` — no prestige interaction - `invocation-utils.ts` — Invocation is completely separate --- ## 7. Combat Tick Integration ### 7.1 Modified Flow in `combat-actions.ts` The channel state is read from the combat store at the start of each tick. The speed multiplier is applied to equipment spell and melee progress: ``` 1. Read isChanneling from combat store 2. If isChanneling: a. Drain Transference: transferencePool -= channelDrainRate b. If transference <= 0: stop channeling (set isChanneling = false) 3. Compute channelMult = isChanneling ? channelSpeedMultiplier : 1.0 4. Equipment spell progress: eProgressPerTick *= channelMult 5. Melee progress: meleeProgressPerTick *= channelMult ``` > **File size note:** `combat-actions.ts` is currently 377 lines. Adding channel drain > logic and speed multiplier application may push it toward the 400-line limit. If so, > extract the channel logic into a new file (e.g., `combat-channel.ts`) and call it > from `processCombatTick`. ### 7.2 Transference Drain Transference is drained from the mana store. The drain uses the existing element deduction pattern: ```typescript // Per tick while channeling: const transferencePool = useManaStore.getState().elements.transference; if (transferencePool.current >= channelDrainRate) { useManaStore.getState().deductElement('transference', channelDrainRate); } else { // Insufficient mana — stop channeling useCombatStore.getState().stopChanneling(); } ``` ### 7.3 Auto-Stop Conditions Channeling stops when any of the following is true: 1. Player releases the button 2. Transference mana reaches 0 3. Player leaves `climb` action 4. Enchanter attunement is deactivated mid-combat > **Room transitions:** Channeling **persists** across room transitions within the same > climb. If the player is channeling and kills an enemy (triggering > `advanceRoomOrFloor`), channeling continues into the next room. The `isChanneling` > state is stored on the combat store and is not reset by room transitions — only by > the auto-stop conditions above or by spire exit. --- ## 8. UI Changes ### 8.1 SpireCombatPage Add a **"Channel Transference"** button between the SpireHeader and RoomDisplay: - **Visible when:** Enchanter active + in `climb` action - **Button style:** Teal-colored (#1ABC9C, matching Enchanter), with Transference icon (🔗) - **While channeling:** Button glows, shows drain rate per second - **Transference bar:** Small bar below button showing remaining Transference mana - **Tooltip:** "Hold to channel transference mana through your equipment, boosting attack speed" ### 8.2 SpireCombatControls Add a compact channel status indicator: - Shows "⚡ Channeling" with speed multiplier when active - Hidden when not channeling ### 8.3 No New Tabs All channel information is visible in the existing SpireCombatPage layout. --- ## 9. Data Flow Summary ``` Player holds button → startChanneling() [combatStore] → isChanneling = true, channelSpeedMultiplier = 1.5+, channelDrainRate = 0.08+ gameStore.tick() → buildTickContext() [snapshots all stores] → processCombatTick() [combat-actions.ts] → If isChanneling: - Deduct transference mana from manaStore - If transference <= 0: stopChanneling() → channelMult = isChanneling ? channelSpeedMultiplier : 1.0 → Equipment spell progress: eProgressPerTick *= channelMult → Melee progress: meleeProgressPerTick *= channelMult → applyTickWrites() [writes combat store changes back] Player releases button → stopChanneling() [combatStore] → isChanneling = false ``` --- ## 10. Acceptance Criteria | # | Criterion | |---|---| | AC-1 | "Channel Transference" button is visible on SpireCombatPage when Enchanter is active and player is in `climb` action. | | AC-2 | Button is hidden when Enchanter is inactive, player is not in `climb`, or Transference pool is 0. | | AC-3 | Holding the button (mousedown) activates channeling; releasing deactivates it. | | AC-4 | While channeling, Transference mana drains at `channelDrainRate` per tick. | | AC-5 | When Transference reaches 0, channeling stops automatically with no penalty. | | AC-6 | While channeling, all equipment spell cast progress is multiplied by `channelSpeedMultiplier`. | | AC-7 | While channeling, all melee sword attack progress is multiplied by `channelSpeedMultiplier`. | | AC-8 | The player's active spell is NOT affected by channeling. | | AC-9 | Invocation spells are NOT affected by channeling. | | AC-10 | Golem attacks are NOT affected by channeling. | | AC-11 | DoT ticks are NOT affected by channeling. | | AC-12 | Base drain rate is 0.08 Transference/tick; base speed multiplier is 1.5×. | | AC-13 | `transference-channeling` discipline scales `channelIntensity` stat with XP. | | AC-14 | `channel-efficiency` once perk (100 XP) grants 15% drain reduction. | | AC-15 | `channel-power` infinite perk (200 XP, every 150 XP) grants +0.05 `channelIntensity`. | | AC-16 | `channel-mastery` capped perk (400 XP, every 200 XP, max 3 tiers) grants +0.10 `channelEfficiency` per tier. | | AC-17 | `channelEfficiency` is capped at 0.60 (prevents drain from reaching 0). | | AC-18 | Channel state resets on spire exit (`isChanneling = false`). | | AC-19 | Existing saves without channel fields get default values (`isChanneling = false`, `channelSpeedMultiplier = 1.5`, `channelDrainRate = 0.08`). | | AC-20 | Channel stops automatically when player leaves `climb` action. | | AC-21 | Speed multiplier affects cast progress accumulation only — mana costs per cast are unchanged. | --- ## 11. Files Reference | File | Role | |---|---| | `src/lib/game/stores/combatStore.ts` | New channel state fields + `startChanneling`/`stopChanneling` actions | | `src/lib/game/stores/combat-state.types.ts` | Type definitions for new state | | `src/lib/game/stores/combat-actions.ts` | Channel drain + speed multiplier application for equipment spells (or extracted to `combat-channel.ts` if file size exceeds 400 lines) | | `src/lib/game/stores/combat-melee.ts` | Speed multiplier application for melee attacks | | `src/lib/game/data/disciplines/enchanter.ts` | Add `transference-channeling` discipline definition | > **Implementation note:** `enchanter.ts` currently has 4 disciplines (146 lines). If > adding `transference-channeling` would push it toward the 400-line limit (e.g. when > combined with the `room-enchanting` discipline from the room enchantments spec), > create a new file `enchanter-combat.ts` (following the existing pattern of > `enchanter-utility.ts`, `enchanter-spells.ts`, etc.) and re-export from > `data/disciplines/index.ts`. | `src/lib/game/effects/discipline-effects.ts` | Add `channelIntensity` and `channelEfficiency` to known bonus stats | | `src/components/game/tabs/SpireCombatPage/SpireCombatPage.tsx` | Channel button UI | | `src/components/game/tabs/SpireCombatPage/SpireCombatControls.tsx` | Compact channel status indicator | | `docs/specs/attunements/enchanter/systems/transference-channel-spec.md` | **THIS FILE** | --- ## 12. Out of Scope - Channel affecting the player's active spell - Channel affecting Invocation spells - Channel affecting golem attacks - Channel affecting DoT ticks - Auto-channel toggle (manual hold only in v1) - Channel working outside of combat (`climb` action only) - Prestige upgrades that affect channeling - Channel interacting with the enchanting pipeline (Design/Prepare/Apply)