- Add isChanneling, channelSpeedMultiplier, channelDrainRate to CombatState - Add startChanneling/stopChanneling actions to combat store - Add transference-channeling discipline with 3 perks (channel-efficiency, channel-power, channel-mastery) - Add channelIntensity and channelEfficiency to KNOWN_BONUS_STATS - Create combat-channel.ts with drain + speed multiplier computation - Apply channel speed multiplier to equipment spells and melee attacks - Add Channel Transference hold-button UI to SpireCombatPage - Add compact channel status indicator to SpireCombatControls - Channel state resets on spire exit, persists across room transitions - All 1235 existing tests pass
17 KiB
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
climbaction (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:
- Transference mana drains at
drainRateper tick (see §3) - All equipment spells and melee attacks gain
speedMultipliercast speed - If Transference reaches 0: channel stops automatically (no penalty)
- If player leaves
climbaction: channel stops automatically - 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
channelEfficiencycap of 0.60 is enforced in the formula itself. Even if perk bonuses would exceed 0.60, the effective drain rate can never go below0.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.34channelEfficiency= 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:
// 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:
startChanneling: () => void;
stopChanneling: () => void;
6.2 Combat State Types (combat-state.types.ts)
Add to CombatState:
isChanneling: boolean;
channelSpeedMultiplier: number;
channelDrainRate: number;
Add to CombatActions:
startChanneling: () => void;
stopChanneling: () => void;
6.3 No Changes To
manaStore.ts— Transference mana is drained via existing element deductioncraftingStore.ts— enchanting is unaffectedprestigeStore.ts— no prestige interactioninvocation-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.tsis 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 fromprocessCombatTick.
7.2 Transference Drain
Transference is drained from the mana store. The drain uses the existing element deduction pattern:
// 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:
- Player releases the button
- Transference mana reaches 0
- Player leaves
climbaction - 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. TheisChannelingstate 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
climbaction - 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.tscurrently has 4 disciplines (146 lines). If addingtransference-channelingwould push it toward the 400-line limit (e.g. when combined with theroom-enchantingdiscipline from the room enchantments spec), create a new fileenchanter-combat.ts(following the existing pattern ofenchanter-utility.ts,enchanter-spells.ts, etc.) and re-export fromdata/disciplines/index.ts. |src/lib/game/effects/discipline-effects.ts| AddchannelIntensityandchannelEfficiencyto 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 (
climbaction only) - Prestige upgrades that affect channeling
- Channel interacting with the enchanting pipeline (Design/Prepare/Apply)