docs: reconcile spec inconsistencies across all documentation
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m20s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m20s
- Fix incursion start day: 5→20 in GAME_BRIEFING.md (matches code constant) - Fix fabricator discipline count: 2→5 in AGENTS.md - Fix discipline counts: elemental.ts 22→21, advanced-regen.ts 14→15 - Fix equipment count: 50→43, remove shields, fix catalysts count - Fix prestige upgrade count: add missing manaWell, manaFlow, pactBinding, pactInterferenceMitigation - Remove x3 victory multiplier (no victory condition defined yet) - Update pact persistence: pacts do NOT persist through prestige - Update elemental matchup tables to match ultimate truth - Update room type frequencies to match spire-climbing-spec - Update guardian data tables to use formulas - Update Tier 3 guardian elements to match guardian-data.ts code - Add pactBinding + pactInterferenceMitigation to PRESTIGE_DEF constants - Wire pactInterferenceMitigation into useGameDerived.ts - Update spire-combat-spec.md Known Gaps table (DoT implemented, melee bypass bug) - Update invoker-spec.md known issues (all resolved) - Update golemancy-spec.md status (undergoing redesign) - Update PrestigeTab test to expect 15 upgrades - Create Gitea issues #285 (melee defense bypass), #286 (DoT verified), #287 (mana conversion gap)
This commit is contained in:
@@ -63,16 +63,16 @@ Use for 3+ sequential independent calls. Zero context from parent — paste ever
|
|||||||
|
|
||||||
### Adding Disciplines
|
### Adding Disciplines
|
||||||
1. Choose the correct data file under `data/disciplines/`:
|
1. Choose the correct data file under `data/disciplines/`:
|
||||||
- `base.ts` — Raw Mana Mastery (available to all)
|
- `base.ts` — Raw Mana Mastery (3 disciplines)
|
||||||
- `elemental.ts` — Elemental Attunement (7 base+ elements)
|
- `elemental.ts` — Elemental Attunement (21 disciplines — all 22 mana types)
|
||||||
- `elemental-regen.ts` — Elemental Regen (7 base + transference)
|
- `elemental-regen.ts` — Elemental Regen (8 disciplines — 7 base + transference)
|
||||||
- `elemental-regen-advanced.ts` — Advanced Regen (3 composite + 3 exotic)
|
- `elemental-regen-advanced.ts` — Advanced Regen (15 disciplines — 8 composite + 6 exotic + transference composite)
|
||||||
- `enchanter.ts` — Core Enchanter disciplines (4 disciplines)
|
- `enchanter.ts` — Core Enchanter disciplines (4 disciplines)
|
||||||
- `enchanter-utility.ts` — Utility enchantment disciplines (2 disciplines)
|
- `enchanter-utility.ts` — Utility enchantment disciplines (2 disciplines)
|
||||||
- `enchanter-spells.ts` — Spell enchantment disciplines (3 disciplines)
|
- `enchanter-spells.ts` — Spell enchantment disciplines (3 disciplines)
|
||||||
- `enchanter-special.ts` — Special enchantment disciplines (1 discipline)
|
- `enchanter-special.ts` — Special enchantment disciplines (1 discipline)
|
||||||
- `invoker.ts` — Invoker combat disciplines (2 disciplines)
|
- `invoker.ts` — Invoker combat disciplines (2 disciplines)
|
||||||
- `fabricator.ts` — Fabricator crafting/golem disciplines (2 disciplines)
|
- `fabricator.ts` — Fabricator crafting/golem disciplines (5 disciplines)
|
||||||
2. Define a `DisciplineDefinition` (see `types/disciplines.ts`):
|
2. Define a `DisciplineDefinition` (see `types/disciplines.ts`):
|
||||||
- `statBonus.stat` must match a key consumed by `computeDisciplineEffects()`
|
- `statBonus.stat` must match a key consumed by `computeDisciplineEffects()`
|
||||||
- Set `difficultyFactor` and `scalingFactor` to control growth rate
|
- Set `difficultyFactor` and `scalingFactor` to control growth rate
|
||||||
@@ -114,7 +114,7 @@ ManaDrainPerTick = drainBase × (1 + (XP / difficultyFactor)^0.4)
|
|||||||
- Stacking cost: each additional stack costs 20% more
|
- Stacking cost: each additional stack costs 20% more
|
||||||
|
|
||||||
### Golemancy
|
### Golemancy
|
||||||
- 12 golems total: 1 base (Earth) + 3 elemental (Steel, Crystal, Sand) + 6 hybrid (Lava, Galvanic, Obsidian, Prism, Quicksilver, Voidstone) + 2 advanced
|
- 10 golems total: 1 base (Earth) + 3 elemental (Steel, Crystal, Sand) + 6 hybrid (Lava, Galvanic, Obsidian, Prism, Quicksilver, Voidstone). Golemancy system is undergoing redesign — see issue #268 for the new component-based construction system (Core + Frame + Mind Circuit + Enchantments)
|
||||||
- Golems slots: `floor(fabricatorLevel / 2)`, max 5 at level 10
|
- Golems slots: `floor(fabricatorLevel / 2)`, max 5 at level 10
|
||||||
- Hybrid golems require Enchanter 5 + Fabricator 5
|
- Hybrid golems require Enchanter 5 + Fabricator 5
|
||||||
|
|
||||||
@@ -133,6 +133,7 @@ ManaDrainPerTick = drainBase × (1 + (XP / difficultyFactor)^0.4)
|
|||||||
- Element opposites (bidirectional): fire↔water, air↔earth, light↔dark, frost↔fire
|
- Element opposites (bidirectional): fire↔water, air↔earth, light↔dark, frost↔fire
|
||||||
- Element counters (directional): lightning→water (lightning counters water), earth→lightning (earth counters lightning)
|
- Element counters (directional): lightning→water (lightning counters water), earth→lightning (earth counters lightning)
|
||||||
- Composite element counters: blackflame counters frost/water/light (and they counter blackflame); radiantflames counters frost/water/dark (and they counter radiantflames)
|
- Composite element counters: blackflame counters frost/water/light (and they counter blackflame); radiantflames counters frost/water/dark (and they counter radiantflames)
|
||||||
|
- Miasma counters air (and air counters miasma); Shadow glass counters light (and light counters shadow glass)
|
||||||
- All mana types double as spell elements
|
- All mana types double as spell elements
|
||||||
- Enemy modifiers (max 2 per enemy): Armored, Agile, Mage, Shield, Swarm
|
- Enemy modifiers (max 2 per enemy): Armored, Agile, Mage, Shield, Swarm
|
||||||
- Room types: Combat (default), Guardian (every 10th), Swarm (15%), Speed (10%), Puzzle (20% on every 7th floor)
|
- Room types: Combat (default), Guardian (every 10th), Swarm (15%), Speed (10%), Puzzle (20% on every 7th floor)
|
||||||
@@ -145,9 +146,9 @@ ManaDrainPerTick = drainBase × (1 + (XP / difficultyFactor)^0.4)
|
|||||||
|
|
||||||
### Prestige (Insight)
|
### Prestige (Insight)
|
||||||
- `baseInsight = floor(maxFloorReached × 15 + totalManaGathered / 500 + signedPacts.length × 150)`
|
- `baseInsight = floor(maxFloorReached × 15 + totalManaGathered / 500 + signedPacts.length × 150)`
|
||||||
- Multiplied by discipline and boon bonuses. ×3 for victory (floor 100 + pact signed)
|
- Multiplied by discipline and boon bonuses. No victory ×3 multiplier (victory condition not yet defined)
|
||||||
- 14 prestige upgrade types: manaWell, manaFlow, insightAmp, spireKey, temporalEcho, steadyHand, ancientKnowledge, elementalAttune, spellMemory, guardianPact, quickStart, elemStart, unlockedManaTypeCapacity
|
- 14 prestige upgrade types: manaWell, manaFlow, insightAmp, spireKey, temporalEcho, steadyHand, ancientKnowledge, elementalAttune, spellMemory, guardianPact, quickStart, elemStart, unlockedManaTypeCapacity, pactBinding
|
||||||
- Signed pacts persist through prestige (bounded by `pactSlots`)
|
- Signed pacts do NOT persist through prestige (reset each loop)
|
||||||
|
|
||||||
### Starting State
|
### Starting State
|
||||||
- Attunement: Enchanter only (level 1)
|
- Attunement: Enchanter only (level 1)
|
||||||
|
|||||||
+94
-55
@@ -1,7 +1,7 @@
|
|||||||
# Mana-Loop: Comprehensive Game Briefing Document
|
# Mana-Loop: Comprehensive Game Briefing Document
|
||||||
|
|
||||||
**Document Version:** 4.0
|
**Document Version:** 4.0
|
||||||
**Updated:** Post-refactoring — 22 mana types, 8-tier guardian system, 64 disciplines, 8 Zustand stores, localStorage-only
|
**Updated:** Post-refactoring — 22 mana types, 8-tier guardian system, 64 disciplines, 14 prestige upgrades, 43 equipment types, 8 Zustand stores, localStorage-only
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
- 3-class Attunement system (Enchanter, Invoker, Fabricator)
|
- 3-class Attunement system (Enchanter, Invoker, Fabricator)
|
||||||
- Equipment-based spell system (spells come from enchanted gear and learned spells)
|
- Equipment-based spell system (spells come from enchanted gear and learned spells)
|
||||||
- Practice-based Discipline system — no discrete skill levels, only continuous XP growth
|
- Practice-based Discipline system — no discrete skill levels, only continuous XP growth
|
||||||
- Time pressure through the incursion mechanic (starts day 5)
|
- Time pressure through the incursion mechanic (starts day 20)
|
||||||
- Guardian progression: base (10-80) → composite (90-160) → exotic (170-240) → combo bosses (250+, 8 tiers)
|
- Guardian progression: base (10-80) → composite (90-160) → exotic (170-240) → combo bosses (250+, 8 tiers)
|
||||||
- Guardian pacts provide permanent multipliers that persist through prestige
|
- Guardian pacts provide permanent multipliers that persist through prestige
|
||||||
- No backend — pure client-side with localStorage persistence
|
- No backend — pure client-side with localStorage persistence
|
||||||
@@ -178,7 +178,7 @@ Base: 1 + min(hours/4, 0.5) → up to 1.5× after 4 hours
|
|||||||
| `TICK_MS` | 200ms | Real time per game tick |
|
| `TICK_MS` | 200ms | Real time per game tick |
|
||||||
| `HOURS_PER_TICK` | 0.04 | Game hours per tick |
|
| `HOURS_PER_TICK` | 0.04 | Game hours per tick |
|
||||||
| `MAX_DAY` | 30 | Days per loop |
|
| `MAX_DAY` | 30 | Days per loop |
|
||||||
| `INCURSION_START_DAY` | 5 | When incursion begins |
|
| `INCURSION_START_DAY` | 20 | When incursion begins |
|
||||||
|
|
||||||
### Time Progression
|
### Time Progression
|
||||||
- 1 real second = 5 game hours (at 5 ticks/second)
|
- 1 real second = 5 game hours (at 5 ticks/second)
|
||||||
@@ -188,12 +188,13 @@ Base: 1 + min(hours/4, 0.5) → up to 1.5× after 4 hours
|
|||||||
### Incursion Mechanic
|
### Incursion Mechanic
|
||||||
|
|
||||||
```
|
```
|
||||||
if (day < 5): incursionStrength = else: incursionStrength = min(0.95, (totalHours / maxHours) × 0.95)
|
if (day < 20): incursionStrength = 0
|
||||||
where totalHours = (day - 5) × 24 + hour
|
else: incursionStrength = min(0.95, (totalHours / maxHours) × 0.95)
|
||||||
maxHours = (30 - 5) × 24 = 600
|
where totalHours = (day - 20) × 24 + hour
|
||||||
|
maxHours = (30 - 20) × 24 = 240
|
||||||
```
|
```
|
||||||
|
|
||||||
Reduces mana regeneration by `(1 - incursionStrength)`. Starts at 0% on Day 5, reaches 95% by Day 30.
|
Reduces mana regeneration by `(1 - incursionStrength)`. Starts at 0% on Day 20, reaches 95% by Day 30.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -223,10 +224,13 @@ HP = floor(5000 × (floor/10) ^ (1.1 + floor/200))
|
|||||||
| Room Type | Chance | Description |
|
| Room Type | Chance | Description |
|
||||||
|-----------|--------|-------------|
|
|-----------|--------|-------------|
|
||||||
| **Guardian** | Every 10th floor | Boss encounter |
|
| **Guardian** | Every 10th floor | Boss encounter |
|
||||||
| **Puzzle** | 20% on every 7th floor | Attunement-themed trial |
|
| **Puzzle** | 100% on every 7th floor (except guardian floors) | Attunement-themed trial |
|
||||||
| **Swarm** | 15% | 3–6 enemies with 40% HP each |
|
| **Swarm** | ~12% | 3–7 weak enemies |
|
||||||
| **Speed** | 10% | Enemy with dodge chance (25% base + 0.5%/floor, max 50%) |
|
| **Speed** | ~10% | Single enemy with elevated dodge chance |
|
||||||
| **Combat** | Default | Single enemy, normal combat |
|
| **Combat** | ~68% (default) | Single enemy, normal combat |
|
||||||
|
| **Recovery** | ~4% | 1 hour; grants 10× mana regen & conversion |
|
||||||
|
| **Treasure** | ~3% | 1 hour; grants 2–15 random items |
|
||||||
|
| **Library** | ~3% | 1 hour; grants discipline XP at 25× rate |
|
||||||
|
|
||||||
### Puzzle Room Types
|
### Puzzle Room Types
|
||||||
- Single attunement: `enchanter_trial`, `fabricator_trial`, `invoker_trial`
|
- Single attunement: `enchanter_trial`, `fabricator_trial`, `invoker_trial`
|
||||||
@@ -297,12 +301,23 @@ damage *= (1 - effectiveArmor)
|
|||||||
| Spell's opposite matches floor (not very effective) | 0.75× |
|
| Spell's opposite matches floor (not very effective) | 0.75× |
|
||||||
| Neutral / Raw mana spells | 1.00× |
|
| Neutral / Raw mana spells | 1.00× |
|
||||||
|
|
||||||
**Element Opposites:**
|
**Element Opposites (bidirectional):**
|
||||||
```
|
```
|
||||||
Fire ↔ Water Air ↔ Earth Light ↔ Dark
|
Fire ↔ Water Air ↔ Earth Light ↔ Dark
|
||||||
Fire ↔ Frost Lightning → Earth (grounding)
|
Frost ↔ Fire
|
||||||
BlackFlame ↔ Water Radiant Flames ↔ Dark
|
```
|
||||||
Miasma ↔ Light Shadow Glass ↔ Light
|
|
||||||
|
**Element Counters (directional):**
|
||||||
|
```
|
||||||
|
Lightning → Water Earth → Lightning
|
||||||
|
```
|
||||||
|
|
||||||
|
**Composite Element Counters (bidirectional):**
|
||||||
|
```
|
||||||
|
BlackFlame ↔ Frost, Water, Light
|
||||||
|
Radiant Flames ↔ Frost, Water, Dark
|
||||||
|
Miasma ↔ Air
|
||||||
|
Shadow Glass ↔ Light
|
||||||
```
|
```
|
||||||
|
|
||||||
### Spell Tiers
|
### Spell Tiers
|
||||||
@@ -339,40 +354,57 @@ Miasma ↔ Light Shadow Glass ↔ Light
|
|||||||
|
|
||||||
| Floor | Name | Element | Armor | Pact Mult | Pact Cost | Pact Time |
|
| Floor | Name | Element | Armor | Pact Mult | Pact Cost | Pact Time |
|
||||||
|-------|------|---------|-------|-----------|-----------|-----------|
|
|-------|------|---------|-------|-----------|-----------|-----------|
|
||||||
| 10 | Ignis Prime | fire | 10% | 1.5× | 500 | 2h |
|
| 10 | Ignis Prime | fire | 10% | 1.5× | formula | 2h |
|
||||||
| 20 | Aqua Regia | water | 15% | 1.75× | 1,000 | 4h |
|
| 20 | Aqua Regia | water | 15% | 1.75× | formula | 4h |
|
||||||
| 30 | Ventus Rex | air | 18% | 2.0× | 2,000 | 6h |
|
| 30 | Ventus Rex | air | 20% | 2.0× | formula | 6h |
|
||||||
| 40 | Terra Firma | earth | 25% | 2.25× | 4,000 | 8h |
|
| 40 | Terra Firma | earth | 25% | 2.25× | formula | 8h |
|
||||||
| 50 | Lux Aeterna | light | 20% | 2.5× | 8,000 | 10h |
|
| 50 | Lux Aeterna | light | 30% | 2.5× | formula | 10h |
|
||||||
| 60 | Umbra Mortis | dark | 22% | 2.75× | 15,000 | 12h |
|
| 60 | Umbra Mortis | dark | 35% | 2.75× | formula | 12h |
|
||||||
| 70 | Mors Ultima | death | 25% | 3.0× | 25,000 | 14h |
|
| 70 | Mors Ultima | death | 40% | 3.0× | formula | 14h |
|
||||||
| 80 | Vinculum Arcana | transference | 20% | 3.25× | 35,000 | 16h |
|
| 80 | Vinculum Arcana | transference | 45% | 3.25× | formula | 16h |
|
||||||
|
|
||||||
|
**Tier 1 Formulas:**
|
||||||
|
- Pact Cost: `floor(hp × 0.3 + power × 5 + hp × armor × 0.5 + shield × 2 + hp × barrier × 0.3)`
|
||||||
|
- Pact Time: `2 + floor(floor / 10)` hours
|
||||||
|
- Armor: Starts at 10% on floor 10, increases by 5% per 10th floor
|
||||||
|
|
||||||
#### Tier 2 — Composite Elements (Floors 90–160)
|
#### Tier 2 — Composite Elements (Floors 90–160)
|
||||||
|
|
||||||
| Floor | Element | Armor | Pact Mult | Pact Cost | Pact Time |
|
| Floor | Element | Armor | Pact Mult | Pact Cost | Pact Time |
|
||||||
|-------|---------|-------|-----------|-----------|-----------|
|
|-------|---------|-------|-----------|-----------|-----------|
|
||||||
| 90 | metal | 30% | 3.5× | 60,000 | 18h |
|
| 90 | metal | 50% | 3.5× | formula | 18h |
|
||||||
| 100 | sand | 25% | 3.75× | 80,000 | 20h |
|
| 100 | sand+fire+earth | 55% | 3.75× | formula | 20h |
|
||||||
| 110 | lightning | 22% | 4.0× | 100,000 | 22h |
|
| 110 | lightning | 60% | 4.0× | formula | 22h |
|
||||||
| 120 | frost | 28% | 4.25× | 125,000 | 24h |
|
| 120 | frost | 65% | 4.25× | formula | 24h |
|
||||||
| 130 | blackflame | 32% | 4.5× | 140,000 | 26h |
|
| 130 | metal+fire+earth (blackflame) | 70% | 4.5× | formula | 26h |
|
||||||
| 140 | radiantflames | 25% | 4.75× | 160,000 | 28h |
|
| 140 | sand+earth+water (radiantflames) | 75% | 4.75× | formula | 28h |
|
||||||
| 150 | miasma | 28% | 5.0× | 180,000 | 30h |
|
| 150 | lightning+fire+air (miasma) | 80% | 5.0× | formula | 30h |
|
||||||
| 160 | shadowglass | 33% | 5.25× | 200,000 | 32h |
|
| 160 | shadowglass | 85% | 5.25× | formula | 32h |
|
||||||
|
|
||||||
|
**Tier 2 Formulas:**
|
||||||
|
- Pact Cost: Same formula as Tier 1
|
||||||
|
- Pact Time: `2 + floor(floor / 10)` hours
|
||||||
|
- Armor: Starts at 50% on floor 90, increases by 5% per 10th floor (capped at 90%)
|
||||||
|
- Note: Floor 100 guardian element is `sand+fire+earth` (composite components), Floor 140 is `sand+earth+water`, Floor 150 is `lightning+fire+air`
|
||||||
|
|
||||||
#### Tier 3 — Exotic Elements (Floors 170–240)
|
#### Tier 3 — Exotic Elements (Floors 170–240)
|
||||||
|
|
||||||
| Floor | Element | Armor | Pact Mult | Pact Cost | Pact Time |
|
| Floor | Element | Armor | Pact Mult | Pact Cost | Pact Time |
|
||||||
|-------|---------|-------|-----------|-----------|-----------|
|
|-------|---------|-------|-----------|-----------|-----------|
|
||||||
| 170 | crystal | 35% | 5.5× | 220,000 | 37h |
|
| 170 | crystal | 35% | 5.5× | formula | 37h |
|
||||||
| 180 | stellar | 30% | 6.0× | 250,000 | 38h |
|
| 180 | stellar | 30% | 6.0× | formula | 38h |
|
||||||
| 190 | void | 35% | 6.5× | 300,000 | 39h |
|
| 190 | void | 35% | 6.5× | formula | 39h |
|
||||||
| 200 | soul | 30% | 7.0× | 330,000 | 40h |
|
| 200 | crystal+stellar+void | 35% | 7.0× | formula | 40h |
|
||||||
| 210 | time | 32% | 7.5× | 370,000 | 41h |
|
| 210 | soul+time+plasma | 32% | 7.5× | formula | 41h |
|
||||||
| 220 | plasma | 28% | 8.0× | 400,000 | 42h |
|
| 220 | plasma | 28% | 8.0× | formula | 42h |
|
||||||
| 230 | crystal+stellar+void | 40% | 8.5× | 430,000 | 43h |
|
| 230 | crystal+stellar+void | 40% | 8.5× | formula | 43h |
|
||||||
| 240 | soul+time+plasma | 42% | 9.0× | 460,000 | 44h |
|
| 240 | soul+time+plasma | 42% | 9.0× | formula | 44h |
|
||||||
|
|
||||||
|
**Tier 3 Formulas:**
|
||||||
|
- Pact Cost: Same formula as Tier 1
|
||||||
|
- Pact Time: `2 + floor(floor / 10)` hours
|
||||||
|
- Armor: Varies per guardian (see code for exact values)
|
||||||
|
- Note: Floor 200 is `crystal+stellar+void`, Floor 210 is `soul+time+plasma` (matching the code in guardian-data.ts)
|
||||||
|
|
||||||
Floors 90–240 have procedurally generated names via `generateGuardianName()`.
|
Floors 90–240 have procedurally generated names via `generateGuardianName()`.
|
||||||
|
|
||||||
@@ -454,7 +486,9 @@ Each guardian grants 2 boons from: `maxMana`, `manaRegen`, `castingSpeed`, `elem
|
|||||||
5. Pact slots limit simultaneous signed pacts (starting 1, upgradeable)
|
5. Pact slots limit simultaneous signed pacts (starting 1, upgradeable)
|
||||||
|
|
||||||
### Victory Condition
|
### Victory Condition
|
||||||
Defeat floor 100 guardian **and** sign the pact → 3× normal insight.
|
No specific victory condition is currently defined. The loop ends when day 30 is reached (or floor 30 for early completion). A victory condition with a ×3 multiplier is awaiting design finalization.
|
||||||
|
|
||||||
|
Signed pacts do **NOT** persist through prestige — the player must re-defeat Guardians and re-sign pacts each loop.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -563,9 +597,9 @@ Players start with 1 active discipline slot. As total XP across all disciplines
|
|||||||
| Pool | File | Count | Requires |
|
| Pool | File | Count | Requires |
|
||||||
|------|------|-------|----------|
|
|------|------|-------|----------|
|
||||||
| Base | `base.ts` | 3 | None |
|
| Base | `base.ts` | 3 | None |
|
||||||
| Elemental Attunement | `elemental.ts` | 22 | None |
|
| Elemental Attunement | `elemental.ts` | 21 | None |
|
||||||
| Elemental Regen | `elemental-regen.ts` | 8 | None |
|
| Elemental Regen | `elemental-regen.ts` | 8 | None |
|
||||||
| Advanced Regen | `elemental-regen-advanced.ts` | 14 | Mana type unlocked |
|
| Advanced Regen | `elemental-regen-advanced.ts` | 15 | Mana type unlocked |
|
||||||
| Enchanter Core | `enchanter.ts` | 4 | Enchanter attunement |
|
| Enchanter Core | `enchanter.ts` | 4 | Enchanter attunement |
|
||||||
| Enchanter Utility | `enchanter-utility.ts` | 2 | Enchanter attunement |
|
| Enchanter Utility | `enchanter-utility.ts` | 2 | Enchanter attunement |
|
||||||
| Enchanter Spells | `enchanter-spells.ts` | 3 | Enchanter attunement |
|
| Enchanter Spells | `enchanter-spells.ts` | 3 | Enchanter attunement |
|
||||||
@@ -617,7 +651,7 @@ Players start with 1 active discipline slot. As total XP across all disciplines
|
|||||||
|
|
||||||
```
|
```
|
||||||
mainHand - Casters (some 2H), Swords, Catalysts
|
mainHand - Casters (some 2H), Swords, Catalysts
|
||||||
offHand - Shields, Catalysts (blocked by 2-handed weapons)
|
offHand - Catalysts, Spell Focuses (blocked by 2-handed weapons)
|
||||||
head - Hoods, Hats, Helms
|
head - Hoods, Hats, Helms
|
||||||
body - Robes, Armor
|
body - Robes, Armor
|
||||||
hands - Gloves, Gauntlets
|
hands - Gloves, Gauntlets
|
||||||
@@ -626,19 +660,20 @@ accessory1 - Rings, Amulets
|
|||||||
accessory2 - Rings, Amulets
|
accessory2 - Rings, Amulets
|
||||||
```
|
```
|
||||||
|
|
||||||
### Equipment Categories & Types (50 total)
|
### Equipment Categories & Types (43 total)
|
||||||
|
|
||||||
| Category | Slot | Count | Examples |
|
| Category | Slot | Count | Examples |
|
||||||
|----------|------|-------|----------|
|
|----------|------|-------|----------|
|
||||||
| Casters | mainHand | 6 | Basic Staff (2H), Apprentice Wand, Oak Staff (2H), Crystal Wand, Arcanist Staff (2H), Battlestaff (2H) |
|
| Casters | mainHand | 6 | Basic Staff (2H), Apprentice Wand, Oak Staff (2H), Crystal Wand, Arcanist Staff (2H), Battlestaff (2H) |
|
||||||
| Swords | mainHand | 5 | Iron Blade, Steel Blade, Crystal Blade, Arcanist Blade, Void-Touched Blade |
|
| Swords | mainHand | 5 | Iron Blade, Steel Blade, Crystal Blade, Arcanist Blade, Void-Touched Blade |
|
||||||
| Catalysts | mainHand | 3 | Basic Catalyst, Fire Catalyst, Void Catalyst |
|
| Catalysts | mainHand/offHand | 4 | Basic Catalyst, Fire Catalyst, Void Catalyst, Metal Spell Focus |
|
||||||
| Body | body | 5 | Civilian Shirt, Apprentice Robe, Scholar Robe, Battle Robe, Arcanist Robe |
|
| Body | body | 5 | Civilian Shirt, Apprentice Robe, Scholar Robe, Battle Robe, Arcanist Robe |
|
||||||
| Head | head | 5 | Cloth Hood, Apprentice Cap, Wizard Hat, Arcanist Circlet, Battle Helm |
|
| Head | head | 5 | Cloth Hood, Apprentice Cap, Wizard Hat, Arcanist Circlet, Battle Helm |
|
||||||
| Hands | hands | 4 | Civilian Gloves, Apprentice Gloves, Spellweave Gloves, Combat Gauntlets |
|
| Hands | hands | 4 | Civilian Gloves, Apprentice Gloves, Spellweave Gloves, Combat Gauntlets |
|
||||||
| Feet | feet | 4 | Civilian Shoes, Apprentice Boots, Traveler Boots, Battle Boots |
|
| Feet | feet | 4 | Civilian Shoes, Apprentice Boots, Traveler Boots, Battle Boots |
|
||||||
| Shields | offHand | 4 | Basic Shield, Reinforced Shield, Runic Shield, Mana Shield |
|
| Accessories | accessory1/2 | 10 | Copper Ring, Silver Ring, Gold Ring, Signet Ring, Copper Amulet, Silver Amulet, Crystal Pendant, Mana Brooch, Arcanist Pendant, Void-Touched Ring |
|
||||||
| Accessories | accessory1/2 | 11 | Copper Ring, Silver Ring, Gold Ring, Signet Ring, Copper Amulet, Silver Amulet, Crystal Pendant, Mana Brooch, Arcanist Pendant, Void-Touched Ring |
|
|
||||||
|
**Total: 43 equipment types** across 8 categories. Shields are banned. Catalysts can be equipped in offHand slot.
|
||||||
|
|
||||||
### Two-Handed Weapons
|
### Two-Handed Weapons
|
||||||
2H weapons (Basic Staff, Oak Staff, Arcanist Staff, Battlestaff) occupy both `mainHand` and `offHand`. The offhand slot is **blocked** when a 2H weapon is equipped.
|
2H weapons (Basic Staff, Oak Staff, Arcanist Staff, Battlestaff) occupy both `mainHand` and `offHand`. The offhand slot is **blocked** when a 2H weapon is equipped.
|
||||||
@@ -733,7 +768,7 @@ Level 8: 4 slots
|
|||||||
Level 10: 5 slots
|
Level 10: 5 slots
|
||||||
```
|
```
|
||||||
|
|
||||||
### Golem Types (10 Total)
|
### Golem Types (10 Total — undergoing redesign, see issue #268)
|
||||||
|
|
||||||
#### Base Golems (1)
|
#### Base Golems (1)
|
||||||
|
|
||||||
@@ -747,7 +782,7 @@ Level 10: 5 slots
|
|||||||
|-------|---------|--------|-------|----|--------|--------|
|
|-------|---------|--------|-------|----|--------|--------|
|
||||||
| Steel Golem | Metal | 12 | 1.2/s | 60 | 35% | Metal mana unlocked |
|
| Steel Golem | Metal | 12 | 1.2/s | 60 | 35% | Metal mana unlocked |
|
||||||
| Crystal Golem | Crystal | 18 | 1.0/s | 40 | 25% | Crystal mana unlocked |
|
| Crystal Golem | Crystal | 18 | 1.0/s | 40 | 25% | Crystal mana unlocked |
|
||||||
| Sand Golem | Sand | 6 | 2.0/s | 35 | 10% | Sand mana unlocked |
|
| Sand Golem | Sand | 10 | 2.0/hr | 45 | 15% | Sand mana unlocked |
|
||||||
|
|
||||||
#### Hybrid Golems (6) — Require Enchanter 5 + Fabricator 5
|
#### Hybrid Golems (6) — Require Enchanter 5 + Fabricator 5
|
||||||
|
|
||||||
@@ -756,12 +791,14 @@ Level 10: 5 slots
|
|||||||
| Lava Golem | Earth + Fire | 15 | 1.0/s | 70 | 20% | AOE 2 |
|
| Lava Golem | Earth + Fire | 15 | 1.0/s | 70 | 20% | AOE 2 |
|
||||||
| Galvanic Golem | Metal + Lightning | 10 | 3.5/s | 45 | 45% | Fast |
|
| Galvanic Golem | Metal + Lightning | 10 | 3.5/s | 45 | 45% | Fast |
|
||||||
| Obsidian Golem | Earth + Dark | 25 | 0.8/s | 55 | 50% | High damage |
|
| Obsidian Golem | Earth + Dark | 25 | 0.8/s | 55 | 50% | High damage |
|
||||||
| Prism Golem | Crystal + Light | 20 | 1.5/s | 50 | 35% | AOE 3 |
|
| Prism Golem | Crystal + Light | 28 | 2.0/hr | 60 | 45% | AOE 3 |
|
||||||
| Quicksilver Golem | Metal + Water | 8 | 4.0/s | 40 | 30% | Very fast |
|
| Quicksilver Golem | Metal + Water | 14 | 4.0/hr | 55 | 35% | Very fast |
|
||||||
| Voidstone Golem | Earth + Void | 40 | 0.6/s | 100 | 60% | AOE 3, ultimate |
|
| Voidstone Golem | Earth + Void | 40 | 0.6/s | 100 | 60% | AOE 3, ultimate |
|
||||||
|
|
||||||
### Golem Combat
|
### Golem Combat
|
||||||
|
|
||||||
|
> ⚠ The golemancy system is undergoing a full redesign (see issue #268). The current data definitions exist but are disconnected from the combat pipeline.
|
||||||
|
|
||||||
```
|
```
|
||||||
progressPerTick = HOURS_PER_TICK × attackSpeed × efficiencyBonus
|
progressPerTick = HOURS_PER_TICK × attackSpeed × efficiencyBonus
|
||||||
damage = baseDamage × (1 + golemMasteryBonus)
|
damage = baseDamage × (1 + golemMasteryBonus)
|
||||||
@@ -778,7 +815,7 @@ Golems last `1 + golemLongevity` floors. Maintenance cost multiplier: `1 - (gole
|
|||||||
| Condition | Result |
|
| Condition | Result |
|
||||||
|-----------|--------|
|
|-----------|--------|
|
||||||
| Day 30 reached | Loop ends, gain insight |
|
| Day 30 reached | Loop ends, gain insight |
|
||||||
| Floor 100 + Pact 100 signed | Victory! 3× insight |
|
| Floor 30 reached | Loop ends early, gain insight |
|
||||||
|
|
||||||
### Insight Formula
|
### Insight Formula
|
||||||
|
|
||||||
@@ -791,7 +828,7 @@ baseInsight = floor(maxFloorReached × 15 + totalManaGathered / 500 + signedPact
|
|||||||
finalInsight = floor(baseInsight × mult)
|
finalInsight = floor(baseInsight × mult)
|
||||||
```
|
```
|
||||||
|
|
||||||
Victory bonus: ×3 if maxFloorReached ≥ 100 AND floor 100 guardian pact is signed.
|
**Note:** There is currently no specific victory condition or ×3 multiplier. These are awaiting design finalization.
|
||||||
|
|
||||||
### Prestige Upgrades (14 Types)
|
### Prestige Upgrades (14 Types)
|
||||||
|
|
||||||
@@ -810,9 +847,11 @@ Victory bonus: ×3 if maxFloorReached ≥ 100 AND floor 100 guardian pact is sig
|
|||||||
| `quickStart` | Quick Start | Start with 100 raw mana | 3 | 400 |
|
| `quickStart` | Quick Start | Start with 100 raw mana | 3 | 400 |
|
||||||
| `elemStart` | Elem. Start | Start with 5 of each unlocked element | 3 | 800 |
|
| `elemStart` | Elem. Start | Start with 5 of each unlocked element | 3 | 800 |
|
||||||
| `unlockedManaTypeCapacity` | Mana Type Capacity | +10 capacity for selected mana type | 5 | 1000 |
|
| `unlockedManaTypeCapacity` | Mana Type Capacity | +10 capacity for selected mana type | 5 | 1000 |
|
||||||
|
| `pactBinding` | Pact Binding | +1 pact slot per level | 5 | 2000 |
|
||||||
|
|
||||||
### Pact Persistence
|
### Pact Persistence
|
||||||
- Signed pacts persist through prestige (bounded by `pactSlots`)
|
- Signed pacts do **NOT** persist through prestige — the player must re-defeat Guardians and re-sign pacts each loop.
|
||||||
|
- `pactSlots` starting value: 1 (upgradeable via `pactBinding` prestige upgrade)
|
||||||
- `pactSlots` starting value: 1 (upgradeable)
|
- `pactSlots` starting value: 1 (upgradeable)
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -1107,5 +1146,5 @@ The following systems no longer exist and should not be re-introduced:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Document Version: 4.0 — Updated: 8 stores, 22 mana types, 64 disciplines, 8-tier guardians, localStorage-only*
|
*Document Version: 5.0 — Updated: 8 stores, 22 mana types, 64 disciplines, 14 prestige upgrades, 43 equipment types, 10 golems (redesign pending), 8-tier guardians, localStorage-only*
|
||||||
*End of Game Briefing Document*
|
*End of Game Briefing Document*
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Circular Dependencies
|
# Circular Dependencies
|
||||||
Generated: 2026-06-04T17:32:36.437Z
|
Generated: 2026-06-04T17:52:04.001Z
|
||||||
|
|
||||||
No circular dependencies found. ✅
|
No circular dependencies found. ✅
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"generated": "2026-06-04T17:32:34.521Z",
|
"generated": "2026-06-04T17:52:02.064Z",
|
||||||
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
|
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
|
||||||
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
|
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
> configuration, summoning lifecycle, maintenance costs, room duration, combat
|
> configuration, summoning lifecycle, maintenance costs, room duration, combat
|
||||||
> behavior, and discipline interactions.
|
> behavior, and discipline interactions.
|
||||||
>
|
>
|
||||||
> **⚠ Spec-defined, implementation pending.** This spec is based on
|
> **⚠ Undergoing full redesign (see issue #268).** The golemancy system is being
|
||||||
> `docs/specs/spire-combat-spec.md` §9 and represents the intended design.
|
> redesigned from predefined golem types to a component-based construction system
|
||||||
> The current code has golem data defined but disconnected from the combat pipeline.
|
> (Core + Frame + Mind Circuit + Enchantments). The current data definitions exist
|
||||||
|
> but are disconnected from the combat pipeline.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -190,10 +190,10 @@ The following inconsistencies exist in the codebase:
|
|||||||
|
|
||||||
| Issue | Description |
|
| Issue | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `pactBinding` upgrade | Referenced in `prestigeStore.doPrestige` but **not defined** in `PRESTIGE_DEF` constants |
|
| `pactBinding` upgrade | ✅ **RESOLVED** — Added to `PRESTIGE_DEF` in `prestige.ts` |
|
||||||
| UI vs store mismatch | UI displays `prestigeUpgrades.pactCapacity` but store logic checks `pactBinding` |
|
| UI vs store mismatch | ✅ **RESOLVED** — `pactBinding` is now the canonical ID used everywhere |
|
||||||
| Pact persistence | `signedPacts` is persisted but also reset to `[]` on `startNewLoop` — pacts don't survive loops in current implementation |
|
| Pact persistence | ✅ **RESOLVED BY DESIGN** — Pacts intentionally do NOT persist through prestige (reset each loop). This is the correct behavior per design intent. |
|
||||||
| `pactInterferenceMitigation` | Used in `pact-utils.ts` but no prestige upgrade defines it |
|
| `pactInterferenceMitigation` | ✅ **RESOLVED** — Added to `PRESTIGE_DEF` in `prestige.ts`; `useGameDerived.ts` now passes it from prestige store |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -539,14 +539,14 @@ They are **in scope for the implementation this spec describes**:
|
|||||||
|
|
||||||
| Feature | Where Defined | Status | This Spec's Requirement |
|
| Feature | Where Defined | Status | This Spec's Requirement |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Enemy armor reduction | `EnemyState.armor`, `MODIFIER_CONFIG.armored` | Data-only | Implement in `onDamageDealt` §5.2 |
|
| Enemy armor reduction | `EnemyState.armor`, `MODIFIER_CONFIG.armored` | **Implemented** (spells/DoTs only; melee bypasses — see issue #285) | Implement in `onDamageDealt` §5.2 |
|
||||||
| Enemy barrier absorption | `EnemyState.barrier`, `MODIFIER_CONFIG.mage/shield` | Data-only | Implement in `onDamageDealt` §5.2 |
|
| Enemy barrier absorption | `EnemyState.barrier`, `MODIFIER_CONFIG.mage/shield` | **Implemented** (spells/DoTs only; melee bypasses — see issue #285) | Implement in `onDamageDealt` §5.2 |
|
||||||
| Enemy dodge roll | `EnemyState.dodgeChance`, `MODIFIER_CONFIG.agile` | Data-only | Implement in `onDamageDealt` §5.2 |
|
| Enemy dodge roll | `EnemyState.dodgeChance`, `MODIFIER_CONFIG.agile` | **Implemented** (spells/DoTs only; melee bypasses — see issue #285) | Implement in `onDamageDealt` §5.2 |
|
||||||
| Mage barrier recharge | `MODIFIER_CONFIG.mage.barrierRechargeRate` | Data-only | Tick in `onDamageDealt` §5.2 |
|
| Mage barrier recharge | `MODIFIER_CONFIG.mage.barrierRechargeRate` | Data-only | Tick in `onDamageDealt` §5.2 |
|
||||||
| Guardian armor | `GuardianDef.armor` | Data-only | Add check to guardian pipeline §5.3 |
|
| Guardian armor | `GuardianDef.armor` | Data-only | Add check to guardian pipeline §5.3 |
|
||||||
| DoT / debuff system | Spell/enchantment type defs | No runtime | Implement per §6 |
|
| DoT / debuff system | Spell/enchantment type defs | **Implemented** — `dot-runtime.ts` complete and wired into combat tick | Verified working; curse amplification needs investigation (see issue #286) |
|
||||||
| Golemancy combat | Full golem data exists | Disconnected | Implement per §9 |
|
| Golemancy combat | Full golem data exists | Disconnected | Implement per §9 |
|
||||||
| Sword melee attacks | Weapon type exists | Not in combat tick | Add `meleeProgress` per §3.1 |
|
| Sword melee attacks | Weapon type exists | **Partial** — meleeProgress exists but bypasses enemy defenses (see issue #285) | Add `meleeProgress` per §3.1 |
|
||||||
| AoE target distribution | `SpellDefinition.aoe` flag | Partial | Implement per §3.2 |
|
| AoE target distribution | `SpellDefinition.aoe` flag | Partial | Implement per §3.2 |
|
||||||
| `elemMasteryBonus` | Stub in `calcDamage` | Hardcoded `1` | Future — leave as `1` for now |
|
| `elemMasteryBonus` | Stub in `calcDamage` | Hardcoded `1` | Future — leave as `1` for now |
|
||||||
| `guardianBonus` | Stub in `calcDamage` | Hardcoded `1` | Future — leave as `1` for now |
|
| `guardianBonus` | Stub in `calcDamage` | Hardcoded `1` | Future — leave as `1` for now |
|
||||||
@@ -612,7 +612,7 @@ interface EnemyState {
|
|||||||
| `src/lib/game/constants/elements.ts` | Element list, opposition cycle |
|
| `src/lib/game/constants/elements.ts` | Element list, opposition cycle |
|
||||||
| `src/lib/game/constants/core.ts` | `HOURS_PER_TICK`, `INCURSION_START_DAY` |
|
| `src/lib/game/constants/core.ts` | `HOURS_PER_TICK`, `INCURSION_START_DAY` |
|
||||||
| `src/lib/game/data/guardian-encounters.ts` | Guardian definitions |
|
| `src/lib/game/data/guardian-encounters.ts` | Guardian definitions |
|
||||||
| `src/lib/game/data/golems/` | Golem definitions (12 golems, tiers 1–4) |
|
| `src/lib/game/data/golems/` | Golem definitions (10 golems, tiers 1–4; undergoing redesign — see issue #268) |
|
||||||
| `src/lib/game/effects.ts` | `getUnifiedEffects` — merges all combat bonuses |
|
| `src/lib/game/effects.ts` | `getUnifiedEffects` — merges all combat bonuses |
|
||||||
| `src/components/game/tabs/SpireCombatPage/SpireHeader.tsx` | In-game time display |
|
| `src/components/game/tabs/SpireCombatPage/SpireHeader.tsx` | In-game time display |
|
||||||
| `src/components/game/tabs/SpireCombatPage/RoomDisplay.tsx` | Room type, enemy state, active effects |
|
| `src/components/game/tabs/SpireCombatPage/RoomDisplay.tsx` | Room type, enemy state, active effects |
|
||||||
@@ -28,9 +28,9 @@ describe('Tab barrel export', () => {
|
|||||||
// ─── Test: Prestige upgrade definitions ────────────────────────────────────────
|
// ─── Test: Prestige upgrade definitions ────────────────────────────────────────
|
||||||
|
|
||||||
describe('Prestige upgrade definitions', () => {
|
describe('Prestige upgrade definitions', () => {
|
||||||
it('has exactly 11 prestige upgrades', async () => {
|
it('has exactly 15 prestige upgrades', async () => {
|
||||||
const { PRESTIGE_DEF } = await import('@/lib/game/constants/prestige');
|
const { PRESTIGE_DEF } = await import('@/lib/game/constants/prestige');
|
||||||
expect(Object.keys(PRESTIGE_DEF).length).toBe(11);
|
expect(Object.keys(PRESTIGE_DEF).length).toBe(15);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('all upgrades have required fields', async () => {
|
it('all upgrades have required fields', async () => {
|
||||||
@@ -43,13 +43,13 @@ describe('Prestige upgrade definitions', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('all 11 expected upgrade IDs are present', async () => {
|
it('all 15 expected upgrade IDs are present', async () => {
|
||||||
const { PRESTIGE_DEF } = await import('@/lib/game/constants/prestige');
|
const { PRESTIGE_DEF } = await import('@/lib/game/constants/prestige');
|
||||||
const expectedIds = [
|
const expectedIds = [
|
||||||
'insightAmp', 'spireKey',
|
'manaWell', 'manaFlow', 'insightAmp', 'spireKey',
|
||||||
'temporalEcho', 'steadyHand', 'ancientKnowledge', 'elementalAttune',
|
'temporalEcho', 'steadyHand', 'ancientKnowledge', 'elementalAttune',
|
||||||
'spellMemory', 'guardianPact', 'quickStart', 'elemStart',
|
'spellMemory', 'guardianPact', 'quickStart', 'elemStart',
|
||||||
'unlockedManaTypeCapacity',
|
'unlockedManaTypeCapacity', 'pactBinding', 'pactInterferenceMitigation',
|
||||||
];
|
];
|
||||||
for (const id of expectedIds) {
|
for (const id of expectedIds) {
|
||||||
expect(PRESTIGE_DEF[id]).toBeDefined();
|
expect(PRESTIGE_DEF[id]).toBeDefined();
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
import type { PrestigeDef } from '../types';
|
import type { PrestigeDef } from '../types';
|
||||||
|
|
||||||
export const PRESTIGE_DEF: Record<string, PrestigeDef> = {
|
export const PRESTIGE_DEF: Record<string, PrestigeDef> = {
|
||||||
|
manaWell: { name: "Mana Well", desc: "+500 starting max mana", max: 5, cost: 500 },
|
||||||
|
manaFlow: { name: "Mana Flow", desc: "+0.5 regen/sec permanently", max: 10, cost: 750 },
|
||||||
insightAmp: { name: "Insight Amp", desc: "+25% insight gain", max: 4, cost: 1500 },
|
insightAmp: { name: "Insight Amp", desc: "+25% insight gain", max: 4, cost: 1500 },
|
||||||
spireKey: { name: "Spire Key", desc: "Start at floor +2", max: 5, cost: 4000 },
|
spireKey: { name: "Spire Key", desc: "Start at floor +2", max: 5, cost: 4000 },
|
||||||
temporalEcho: { name: "Temporal Echo", desc: "+10% mana generation", max: 5, cost: 3000 },
|
temporalEcho: { name: "Temporal Echo", desc: "+10% mana generation", max: 5, cost: 3000 },
|
||||||
@@ -13,4 +15,6 @@ export const PRESTIGE_DEF: Record<string, PrestigeDef> = {
|
|||||||
quickStart: { name: "Quick Start", desc: "Start with 100 raw mana", max: 3, cost: 400 },
|
quickStart: { name: "Quick Start", desc: "Start with 100 raw mana", max: 3, cost: 400 },
|
||||||
elemStart: { name: "Elem. Start", desc: "Start with 5 of each unlocked element", max: 3, cost: 800 },
|
elemStart: { name: "Elem. Start", desc: "Start with 5 of each unlocked element", max: 3, cost: 800 },
|
||||||
unlockedManaTypeCapacity: { name: "Mana Type Capacity", desc: "+10 capacity for selected mana type", max: 5, cost: 1000 },
|
unlockedManaTypeCapacity: { name: "Mana Type Capacity", desc: "+10 capacity for selected mana type", max: 5, cost: 1000 },
|
||||||
|
pactBinding: { name: "Pact Binding", desc: "+1 pact slot per level", max: 5, cost: 2000 },
|
||||||
|
pactInterferenceMitigation: { name: "Pact Interference Mitigation", desc: "Reduces pact interference penalty", max: 10, cost: 1500 },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -143,14 +143,16 @@ export function useCombatStats() {
|
|||||||
[activeSpell]
|
[activeSpell]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const pactInterferenceMitigation = usePrestigeStore((s) => s.prestigeUpgrades.pactInterferenceMitigation || 0);
|
||||||
|
|
||||||
const pactMultiplier = useMemo(
|
const pactMultiplier = useMemo(
|
||||||
() => computePactMultiplier({ signedPacts }),
|
() => computePactMultiplier({ signedPacts, pactInterferenceMitigation }),
|
||||||
[signedPacts]
|
[signedPacts, pactInterferenceMitigation]
|
||||||
);
|
);
|
||||||
|
|
||||||
const pactInsightMultiplier = useMemo(
|
const pactInsightMultiplier = useMemo(
|
||||||
() => computePactInsightMultiplier({ signedPacts }),
|
() => computePactInsightMultiplier({ signedPacts, pactInterferenceMitigation }),
|
||||||
[signedPacts]
|
[signedPacts, pactInterferenceMitigation]
|
||||||
);
|
);
|
||||||
|
|
||||||
// DPS calculation
|
// DPS calculation
|
||||||
|
|||||||
Reference in New Issue
Block a user