Files
Mana-Loop/docs/specs/mana-conversion-spec.md
T
n8n-gitea c22f9c3bd5
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m2s
feat: add mana conversion system spec and ticket
2026-06-04 13:24:15 +02:00

16 KiB
Raw Blame History

Mana Conversion System — Specification

Overview

This spec defines a unified mana conversion system that replaces the current fragmented approach (attunement conversions, discipline conversions, manual conversion, and guardian pact conversions). All conversion types use the same core mechanics: consuming source mana types to produce a destination mana type, with costs deducted from regen (not from the mana pool directly).


1. Element Distance from Raw Mana

Every mana type has a distance from raw mana. This value is used in two places:

  1. Calculating conversion cost ratios
  2. Calculating meditation multiplier strength for that element's conversion

Distance Table

Element Category Distance
Raw 0
Fire, Water, Air, Earth, Light, Dark, Death Base 1
Transference Utility 1
Metal, Sand, Lightning, Frost, BlackFlame, RadiantFlames, Miasma, ShadowGlass Composite 2
Crystal, Stellar, Void, Soul, Plasma Exotic (tier 1) 3
Time Exotic (tier 2) 4

Reusable Function

// src/lib/game/utils/element-distance.ts
export function getElementDistance(elementId: string): number

Returns the distance for any element. If a composite element's recipe contains components at different distances, the element's distance = max(component distances) + 1.


2. Conversion Cost Ratios

All conversions produce 1 unit of destination mana. The cost depends on the destination's distance from raw.

Cost Formula

For a destination element at distance d:

  • Raw mana cost = 10^(d+1)

    • Distance 1 (base): 10^2 = 100 raw per 1 element
    • Distance 2 (composite): 10^3 = 1,000 raw per 1 element
    • Distance 3 (exotic): 10^4 = 10,000 raw per 1 element
    • Distance 4 (time): 10^5 = 100,000 raw per 1 element
  • Each component mana cost = 10 * (d + 1) per 1 destination element

    • Distance 1: 10 * 2 = 20 of that element per 1 destination
    • Distance 2: 10 * 3 = 30 of that element per 1 destination
    • Distance 3: 10 * 4 = 40 of that element per 1 destination
    • Distance 4: 10 * 5 = 50 of that element per 1 destination

Cost Table (per 1 unit of destination mana)

Destination Distance Raw Cost Each Component Cost Components
Fire (base) 1 100
Transference 1 100
Metal 2 1,000 30 fire + 30 earth fire, earth
Sand 2 1,000 30 earth + 30 water earth, water
Lightning 2 1,000 30 fire + 30 air fire, air
Frost 2 1,000 30 air + 30 water air, water
BlackFlame 2 1,000 30 dark + 30 fire dark, fire
Radiant Flames 2 1,000 30 light + 30 fire light, fire
Miasma 2 1,000 30 air + 30 death air, death
Shadow Glass 2 1,000 30 earth + 30 dark earth, dark
Crystal 3 10,000 40 sand + 40 light sand, light
Stellar 3 10,000 40 plasma + 40 light plasma, light
Void 3 10,000 40 dark + 40 death dark, death
Soul 3 10,000 40 light + 40 dark + 40 transference light, dark, transference
Plasma 3 10,000 40 lightning + 40 fire + 40 transference lightning, fire, transference
Time 4 100,000 50 soul + 50 sand + 50 transference soul, sand, transference

Key Constraint

Raw mana cost is always greater than any individual component cost. This is inherent in the formula: 10^(d+1) for raw vs 10*(d+1) for each component.


3. Conversion Rate — Unified Formula

All three sources (disciplines, attunements, guardian pacts) contribute to a single base conversion rate for each element. This rate is then exponentially boosted by attunement levels and pact bonuses.

Formula

finalRate = (disciplineRate + attunementBaseRate + pactBaseRate) ^ (1 + attunementLevelBonus + pactLevelBonus)

Where:

  • disciplineRate = sum of conversion rates from active disciplines for this element (see §4)
  • attunementBaseRate = sum of base conversion rates from attunements for this element (see §5)
  • pactBaseRate = sum of base conversion rates from guardian pacts for this element (see §6)
  • attunementLevelBonus = sum of relevant attunement levels (e.g., Enchanter level for transference, Fabricator level for earth)
  • pactLevelBonus = count of pacts with guardians that have this element as primary × Invoker attunement level

Example

A player with:

  • Fire Conversion discipline active (rate = 0.5)
  • Enchanter attunement level 3 (no fire base rate, but level contributes to exponent if fire is the attunement's primary)
  • Fabricator attunement level 2 (earth primary, so contributes to earth conversions)
  • 2 fire-type guardian pacts, Invoker level 3

For fire mana conversion:

baseRate = 0.5 (discipline) + 0 (no attunement base for fire) + 0 (no pact base for fire)
exponent = 1 + 0 (no attunement has fire as primary) + 0 (no fire-type pact bonus)
finalRate = 0.5^1 = 0.5/hr

For metal mana conversion (fire + earth):

baseRate = 0.35 (metal discipline) + 0 (no attunement base) + 0 (no pact base)
exponent = 1 + 2 (Fabricator level 2, earth is a component of metal) + 0
finalRate = 0.35^3 = 0.0429/hr

Wait — this produces lower rates at higher levels, which is wrong. The exponent should be a multiplier, not an exponent on the rate. Let me restate:

Corrected Formula

finalRate = (disciplineRate + attunementBaseRate + pactBaseRate) × (1 + attunementLevelBonus + pactLevelBonus)

Where the multiplier is additive:

  • attunementLevelBonus = sum of relevant attunement levels × 0.5 (each level adds +50% to rate)
  • pactLevelBonus = count of pacts with this element × Invoker level × 0.25

So:

finalRate = baseRate × (1 + Σ(attunementLevel_i × 0.5) + Σ(pactCount_element × invokerLevel × 0.25))

Revised Example

For metal mana with Metal Conversion discipline (0.35/hr), Fabricator level 2:

baseRate = 0.35
multiplier = 1 + (2 × 0.5) = 2.0
finalRate = 0.35 × 2.0 = 0.70/hr

For transference mana with Transference Conversion discipline (0.4/hr), Enchanter level 3:

baseRate = 0.4
multiplier = 1 + (3 × 0.5) = 2.5
finalRate = 0.4 × 2.5 = 1.0/hr

4. Discipline Contributions

Each conversion discipline provides a base rate that scales with XP.

Base Rates (per hour)

Element Base Rate Difficulty Factor Scaling Factor
Fire, Water, Air, Earth, Light, Dark, Death 0.5 120 60
Transference 0.4 100 50
Metal, Sand, Lightning, Frost 0.35 160 80
BlackFlame, RadiantFlames, Miasma, ShadowGlass 0.30 170 85
Crystal, Void 0.25 220 110
Stellar, Soul, Plasma 0.20 240 120
Time 0.15 260 130

XP Scaling

The discipline's effective rate bonus follows the standard stat bonus formula:

statBonus = baseValue × (XP / scalingFactor)^0.65

The discipline's total contribution to the base rate is:

disciplineRate = baseRate + statBonus

Perks

Each discipline has perks that add flat bonuses to the rate:

  • once perk: grants +baseRate to the conversion rate at threshold XP
  • infinite perk: every N XP grants +baseRate × 0.5 to the conversion rate

5. Attunement Contributions

Attunements provide a base conversion rate for their primary mana type, plus a level-based multiplier to all conversions involving their element.

Attunement Base Rates

Attunement Primary Mana Base Rate (per hour)
Enchanter Transference 0.2
Fabricator Earth 0.25
Invoker None 0

Attunement Level Multiplier

Each attunement level adds +0.5 to the multiplier for conversions where the attunement's primary element is either:

  • The destination element, OR
  • A component element of the destination

Example: Fabricator (earth) level 3 boosts:

  • Earth conversions (earth is destination)
  • Metal conversions (earth is component)
  • Sand conversions (earth is component)
  • Shadow Glass conversions (earth is component)

But NOT fire conversions (earth is not involved).


6. Guardian Pact Contributions

Guardian pacts provide:

  1. A base conversion rate for the guardian's element
  2. A level bonus to the multiplier, scaled by Invoker attunement level

Pact Base Rate

Each signed pact grants +0.15/hr base rate for the guardian's primary element.

Pact Level Bonus

For each signed pact whose guardian has element E as primary:

pactLevelBonus_E += invokerLevel × 0.25

So an Invoker at level 4 with 2 fire-type pacts grants:

pactLevelBonus_fire = 2 × 4 × 0.25 = 2.0

This adds to the multiplier for fire conversions and any composite that uses fire.


7. Meditation Multiplier

Meditation boosts conversion rates, but the boost is reduced for elements further from raw.

Formula

meditationBoost = 1 + (meditationMultiplier - 1) / distance

Where distance is the destination element's distance from raw mana.

Element Distance Meditation Strength
1 (base) Full: meditationMultiplier
2 (composite) Half: 1 + (med - 1) / 2
3 (exotic) Third: 1 + (med - 1) / 3
4 (time) Quarter: 1 + (med - 1) / 4

For elements with components at different distances, use the highest distance value (i.e., the weakest meditation boost).


8. Regen Deduction Model

All conversion costs are deducted from mana regen, not from the mana pool directly. This means:

  1. Each element has a gross regen (from attunements, upgrades, etc.)
  2. Conversions that consume this element as a source reduce the effective regen
  3. The remaining regen is the net regen that actually adds to the pool

Raw Mana

rawNetRegen = rawGrossRegen
  - Σ (conversionRate_destination × rawCost_destination) for all active conversions

Element Mana (e.g., fire)

fireNetRegen = fireGrossRegen
  + fireProducedRate (from raw→fire conversion)
  - Σ (conversionRate_destination × fireCost_destination) for all conversions using fire as component

Display Format

Each element's regen display shows:

Fire Mana Regen:
  +0.50/hr converted from raw mana (Fire Conversion discipline, rate × attunement multiplier × meditation)
  -0.15/hr being converted into Metal mana (30 per unit × 0.005 units/hr)
  -0.10/hr being converted into Lightning mana (30 per unit × 0.0033 units/hr)
  ─────────────────
  +0.25/hr net fire mana regen

9. Insufficient Regen — Auto-Pause

If a conversion's source cost exceeds the gross regen of that source type, the conversion is completely disabled (not partially throttled).

Conditions

A conversion for element E is paused if:

conversionRate_E × sourceCost_source > sourceGrossRegen

for any source type (raw or component element) in the conversion.

UI Warning

When a conversion is paused due to insufficient regen:

  • The conversion's entry in the stats tab shows a red warning: "⚠️ PAUSED: Insufficient [source] regen (need X/hr, have Y/hr)"
  • The mana display for the source element shows a warning icon next to the draining conversion

Auto-Resume

When regen increases (e.g., attunement levels up, new discipline XP gained, meditation active), paused conversions automatically resume if the regen now covers the cost.


10. No Manual Conversion

The existing convertMana action and processConvertAction are removed. All mana conversion happens passively through the unified system. The "convert" player action is removed from the action buttons.


11. Stats Tab Display

The Stats tab includes a new Conversion Stats section showing:

Per-Element Conversion Table

For each element with active conversions:

┌─────────────────────────────────────────────────────────────┐
│ 🔥 FIRE MANA CONVERSION                                     │
│                                                             │
│ Base Rate:        0.50/hr  (Fire Conversion discipline)     │
│ Attunement Bonus: ×1.00     (no attunement for fire)        │
│ Pact Bonus:       ×1.00     (0 fire-type pacts)             │
│ Meditation:       ×1.00     (not meditating)                │
│ ─────────────────────────────────────────                   │
│ Effective Rate:   0.50/hr  → produces 0.50 fire/hr         │
│                                                             │
│ Costs (deducted from raw regen):                            │
│   Raw: 100 × 0.50 = 50.0 raw/hr                           │
│                                                             │
│ Drained by downstream conversions:                          │
│   → Metal:    30 × 0.005 = 0.15 fire/hr                   │
│   → Lightning: 30 × 0.003 = 0.10 fire/hr                  │
│                                                             │
│ Net Fire Regen:  +0.50 - 0.15 - 0.10 = +0.25 fire/hr      │
└─────────────────────────────────────────────────────────────┘

Formula Summary

A collapsible formula reference is shown at the top:

Conversion Rate Formula:
  finalRate = (disciplineRate + attunementBase + pactBase) × attunementMult × pactMult × meditationMult

Where:
  attunementMult = 1 + Σ(relevantAttunementLevel × 0.5)
  pactMult = 1 + Σ(pactCount_element × invokerLevel × 0.25)
  meditationMult = 1 + (meditationMultiplier - 1) / elementDistance

Cost per 1 unit of destination:
  rawCost = 10^(distance+1)
  componentCost = 10 × (distance+1) per component

All costs deducted from source regen (not from mana pool).
Conversions pause if source regen < conversion cost.

12. Implementation Notes

New Files

  • src/lib/game/utils/element-distance.tsgetElementDistance() function
  • src/lib/game/utils/conversion-rates.ts — Unified conversion rate calculator
  • src/lib/game/data/conversion-costs.ts — Cost ratio table per element

Modified Files

  • src/lib/game/data/disciplines/elemental-regen.ts — Update base rates, remove drain model
  • src/lib/game/data/disciplines/elemental-regen-advanced.ts — Update base rates, remove drain model
  • src/lib/game/data/attunements.ts — Update conversion rates to match new system
  • src/lib/game/effects/discipline-effects.ts — Update conversion computation
  • src/lib/game/stores/gameStore.ts — Replace tick conversion logic with unified system
  • src/lib/game/stores/manaStore.ts — Remove convertMana, processConvertAction, craftComposite
  • src/lib/game/stores/prestigeStore.ts — Add pact conversion rate data
  • src/components/game/tabs/StatsTab/ElementStatsSection.tsx — Add conversion display
  • src/components/game/ManaDisplay.tsx — Add per-element regen breakdown

Removed

  • Manual conversion (convertMana, processConvertAction)
  • Composite crafting via craftComposite (replaced by passive conversion)
  • The "convert" action from player actions
  • Per-tick mana pool deduction for conversions (replaced by regen deduction)

13. Migration Notes

Existing save data will need migration:

  • Active discipline conversion rates are preserved (the XP and discipline IDs stay the same)
  • Attunement conversion rates are recalculated from the new base rates
  • Any manually-converted element mana in pools is preserved
  • The convertMana and craftComposite store actions are kept as no-ops for save compatibility but have no UI