- Add ActiveEffect, EffectType types to game.ts; activeEffects + effectiveArmor on EnemyState - Add SpellOnHitEffect + onHitEffect field to SpellDefinition - Wire onHitEffect to fire (burn), death (curse), lightning (armor_corrode), frost (freeze), soul (bypassArmor burn) - Add applyOnHitEffect() — applies on-hit effect on successful spell hit (spec §6.2) - Add processDoTPhase() — ticks all active effects after weapon/golem attacks (spec §6.3) - Add bypassArmor/bypassBarrier support in applyEnemyDefenses() (AC-13) - Export standalone applyEnemyDefenses from combat-tick.ts for DoT pipeline - Split DoT runtime into separate dot-runtime.ts (135 lines) to keep combat-actions.ts under 400 lines - Update all enemy generation sites with activeEffects/effectiveArmor defaults - Fix test helpers for new required fields All 921 tests pass (45 test files)
7.5 KiB
Invoker Attunement — Design Spec
Describes the Invoker attunement: identity, unlock flow, mana behavior, full discipline list with stats/perks, systems unlocked, pact interactions, and attunement level interactions.
1. Objective
The Invoker is the pact-focused attunement that transforms Guardian defeats into permanent power. Unlike the other attunements, the Invoker has no primary mana type and no automatic mana conversion — it gains elemental mana exclusively by signing pacts with Guardians. Its disciplines amplify pact power, boon effectiveness, and guardian-related multipliers.
2. Identity
| 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, scales with 1.5^(level-1)) |
| Conversion Rate | None (0 at all levels) |
| Unlock | Defeat first Guardian |
| Capabilities | ['pacts', 'guardianPowers', 'elementalMastery'] |
| Skill Categories | ['invocation', 'pact'] |
3. Unlock Condition and Flow
Condition: Defeat the first Guardian (floor 10).
Unlock flow:
- Defeat the floor 10 Guardian (Ignis Prime)
- Invoker becomes available for activation
- Player activates Invoker → initialized at
{ active: true, level: 1, experience: 0 } - Invoker disciplines become available:
pact-attunement,guardians-boon
The unlock condition is stored as a descriptive string:
"Defeat your first guardian and choose the path of the Invoker"
4. Raw Mana Regen Contribution
Base regen: +0.3/hour (at level 1). Scales exponentially:
effectiveRegen = 0.3 × 1.5^(level - 1)
| Level | Raw Regen |
|---|---|
| 1 | 0.300/hr |
| 5 | 1.519/hr |
| 10 | 11.533/hr |
5. Mana Gain from Pacts (No Conversion)
The Invoker has no automatic mana conversion. Instead, it gains elemental mana types exclusively through Guardian pacts:
When a pact is signed (completePactRitual):
for (const manaType of guardian.unlocksMana || []) {
manaStore.unlockElement(manaType, 0);
}
Each guardian's unlocksMana is resolved via resolveMultiUnlockChain(element),
which walks the element recipe tree to unlock the guardian's element and all base
components:
| Guardian | Element | Unlocks Mana Types |
|---|---|---|
| Floor 10 (Ignis Prime) | fire | fire |
| Floor 20 (Aqua Regia) | water | water |
| Floor 40 (Terra Firma) | earth | earth |
| Floor 90 (Metal) | metal | fire, earth, metal |
| Floor 130 (BlackFlame) | blackflame | fire, earth, metal |
| Floor 150 (Lightning) | lightning | fire, air, lightning |
Signing pacts is the only way for the Invoker to access elemental mana for casting elemental spells and running elemental disciplines.
6. Disciplines
The Invoker's discipline pool contains 2 disciplines.
6.1 Pact Attunement (pact-attunement)
| Field | Value |
|---|---|
| Mana Type | raw |
| Base Cost | 12 |
| Requires | ['signed_pact'] |
| Stat Bonus | pactAffinityBonus +0.05 (base) |
| Scaling Factor | 80 |
| Difficulty Factor | 150 |
| Drain Base | 4 |
Perks:
| Perk ID | Type | Threshold | Bonus |
|---|---|---|---|
pact-affinity-scaling |
once |
100 | Unlock pact affinity scaling |
pact-affinity-infinite |
infinite |
200 | Every 100 XP: pactAffinityBonus +0.05 |
pact-power-boost |
capped |
500 | Every 200 XP: guardianBoonMultiplier +0.03, max 5 tiers |
6.2 Guardian's Boon (guardians-boon)
| Field | Value |
|---|---|
| Mana Type | raw |
| Base Cost | 18 |
| Requires | ['signed_pact'] |
| Stat Bonus | guardianBoonMultiplier +0.10 (base) |
| Scaling Factor | 100 |
| Difficulty Factor | 200 |
| Drain Base | 6 |
Perks:
| Perk ID | Type | Threshold | Bonus |
|---|---|---|---|
boon-1 |
once |
100 | guardianBoonMultiplier +0.10 |
boon-2 |
capped |
200 | Every 350 XP: guardianBoonMultiplier +0.05, max 5 tiers |
6.3 Guardian Boon Multiplier Scaling
Maximum theoretical guardianBoonMultiplier from disciplines:
| Source | Value |
|---|---|
| Base (Guardian's Boon discipline) | +0.10 |
boon-1 perk (once @ 100 XP) |
+0.10 |
boon-2 perk (capped, 5 tiers × 0.05) |
+0.25 |
pact-power-boost perk (capped, 5 tiers × 0.03) |
+0.15 |
| Maximum total | +0.60 |
With the base multiplier of 1.0, the maximum guardian boon multiplier is 1.60.
7. Systems Unlocked
The Invoker attunement gates the Pact System (see pact-system-spec.md):
- Sign pacts with defeated Guardians
- Gain permanent boons and elemental mana unlocks
- Pact slots limit simultaneous signed pacts
- Pact affinity reduces ritual time
8. Puzzle Room Behavior
In the spire, every 7th floor has a puzzle room. When the room type is
invoker_trial, progress scales at 2.5–3% per tick per Invoker level.
9. Attunement Level Interactions
Higher Invoker level affects:
- Raw mana regen:
0.3 × 1.5^(level-1)per hour - No conversion: Invoker never has automatic mana conversion
- Pact affinity: Higher raw regen supports the raw mana cost of pact rituals
Attunement level does not directly affect pact multipliers or boon power — those scale through discipline XP.
10. Known Code Issues
The following inconsistencies exist in the codebase:
| Issue | Description |
|---|---|
pactBinding upgrade |
Referenced in prestigeStore.doPrestige but not defined in PRESTIGE_DEF constants |
| UI vs store mismatch | UI displays prestigeUpgrades.pactCapacity but store logic checks pactBinding |
| Pact persistence | signedPacts is persisted but also reset to [] on startNewLoop — pacts don't survive loops in current implementation |
pactInterferenceMitigation |
Used in pact-utils.ts but no prestige upgrade defines it |
11. Acceptance Criteria
| # | Criterion |
|---|---|
| AC-1 | Invoker is locked until the first Guardian is defeated. |
| AC-2 | Invoker has no primary mana type and no automatic conversion at any level. |
| AC-3 | Signing a pact unlocks the guardian's element and all component elements. |
| AC-4 | Both Invoker disciplines require at least one signed pact to activate. |
| AC-5 | pact-affinity-infinite perk grants +0.05 pactAffinityBonus every 100 XP beyond threshold 200. |
| AC-6 | boon-2 capped perk grants +0.05 guardianBoonMultiplier per tier, max 5 tiers, interval 350 XP. |
| AC-7 | pact-power-boost capped perk grants +0.03 guardianBoonMultiplier per tier, max 5 tiers, interval 200 XP. |
| AC-8 | Maximum theoretical guardianBoonMultiplier from disciplines is 1.60 (base 1.0 + 0.60). |
| AC-9 | Invoker invoker_trial puzzle rooms grant bonus progress per Invoker level. |
| AC-10 | Invoker level scales raw regen by 1.5^(level-1). |
12. Files Reference
| File | Role |
|---|---|
src/lib/game/data/attunements.ts |
Invoker definition |
src/lib/game/data/disciplines/invoker.ts |
Invoker disciplines (2) |
src/lib/game/stores/prestigeStore.ts |
Pact ritual state, slot management |
src/lib/game/stores/pipelines/pact-ritual.ts |
Pact ritual tick processing |
src/lib/game/utils/pact-utils.ts |
Pact multiplier calculations |
src/lib/game/data/guardian-data.ts |
Static guardian definitions |
src/lib/game/data/guardian-encounters.ts |
Procedural guardian lookup |
src/components/game/tabs/GuardianPactsTab.tsx |
Pact signing UI |
docs/specs/attunements/invoker/systems/pact-system-spec.md |
Pact system spec |