feat: add prestige system and skill upgrades with comprehensive documentation
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 5m57s

This commit is contained in:
Refactoring Agent
2026-05-01 15:18:09 +02:00
parent 3691aa4acc
commit 03815f27ee
52 changed files with 4056 additions and 873 deletions
+330
View File
@@ -0,0 +1,330 @@
# Subtask 18 Context: Enchantment Power Effect + Audit Stubs
## Current Enchantment Power Effect Status
### Definition Status
- **"Enchantment Power" is NOT defined as an enchantment effect** in `src/lib/game/data/enchantments/` directory
- The `ENCHANTMENT_EFFECTS` catalog (in `enchantment-effects.ts` and `enchantments/index.ts`) does not contain any effect with "Enchantment Power" as a defined effect
- Searching for "Enchantment Power" in enchantment files returns no results
### How Enchantment Power is Referenced
The `enchantPower` stat IS referenced in **skill upgrade perks** in `src/lib/game/skill-evolution.ts`:
| Perk ID | Name | Effect | Skill Tree |
|---------|------|--------|------------|
| `en_t1_l5_a` | Artisan's Touch | `+10% Enchantment Power` | Enchanting T1 |
| `en_t1_l10_a` | Greater Artisan | `+15% Enchantment Power` | Enchanting T1 |
| `en_t2_l5_a` | Expert Artisan | `+25% Enchantment Power` | Enchanting T2 |
| `en_t2_l10_a` | Master Artisan | `+35% Enchantment Power` | Enchanting T2 |
| `en_t3_l5_a` | Cosmic Artisan | `+50% Enchantment Power` | Enchanting T3 |
| `en_t3_l10_a` | [ELITE] OMNI-ARTISAN | `2x enchantment power` | Enchanting T3 |
| `en_t4_l5_a` | Astral Artisan | `+75% Enchantment Power` | Enchanting T4 |
| `en_t4_l10_a` | Galactic Artisan | `+100% Enchantment Power` | Enchanting T4 |
| `en_t5_l5_a` | Divine Artisan | `+150% Enchantment Power` | Enchanting T5 |
| `en_t5_l10_a` | [ELITE] ASCENDED ARTISAN | `5x enchantment power` | Enchanting T5 |
| `es_t1_l5_c` | Quick Work | `+5% Enchantment Power` | Essence Shaping T1 |
| `es_t1_l10_c` | Superior Work | `+10% Enchantment Power` | Essence Shaping T1 |
| `es_t2_l5_c` | Expert Work | `+15% Enchantment Power` | Essence Shaping T2 |
| `es_t2_l10_c` | Master Work | `+20% Enchantment Power` | Essence Shaping T2 |
| `es_t3_l5_c` | Divine Work | `+25% Enchantment Power` | Essence Shaping T3 |
| `es_t3_l10_c` | [ELITE] OMNI-WORK | `2x enchantment power` | Essence Shaping T3 |
| `ee_t1_l5_c` | Quality Work | `+5% Enchantment Power` | Elemental Evocation T1 |
| `ee_t1_l10_c` | Superior Work | `+10% Enchantment Power` | Elemental Evocation T1 |
| `ee_t2_l5_c` | Expert Work | `+15% Enchantment Power` | Elemental Evocation T2 |
| `ee_t2_l10_c` | Master Work | `+20% Enchantment Power` | Elemental Evocation T2 |
| `ee_t3_l5_c` | Divine Work | `+25% Enchantment Power` | Elemental Evocation T3 |
| `ee_t3_l10_c` | [ELITE] OMNI-POWER | `2x enchantment power` | Elemental Evocation T3 |
### Effect Type in Skill Evolution
All these perks use the effect structure:
```typescript
{ type: 'multiplier', stat: 'enchantPower', value: <decimal_value> }
```
### Problem: `enchantPower` Stat Not Handled in Effects System
In `src/lib/game/upgrade-effects.ts`, the `computeEffects` function has a switch statement for multiplier effects (lines 295-320) but **does NOT have a case for `enchantPower`**:
```typescript
switch (effect.stat) {
case 'maxMana':
effects.maxManaMultiplier *= effect.value;
break;
case 'regen':
effects.regenMultiplier *= effect.value;
break;
// ... other cases ...
// NO CASE FOR 'enchantPower'!
}
```
Similarly, the `ComputedEffects` interface (lines 16-48) does NOT include an `enchantPower` or `enchantmentPowerMultiplier` field.
### StatsTab.tsx Attempts to Read `enchantPower`
In `src/components/game/tabs/StatsTab.tsx` (lines 161-178), there's a placeholder that tries to read `enchantPower`:
```typescript
{upgradeEffects && 'enchantPower' in upgradeEffects
? `${(upgradeEffects as Record<string, number>).enchantPower.toFixed(2)}×`
: '1.0×'}
```
This is a type-safe workaround since `enchantPower` is not in the `ComputedEffects` interface.
---
## Stub Location in EquipmentTab
**File:** `/home/user/repos/Mana-Loop/src/components/game/tabs/EquipmentTab.tsx`
**Lines 516-531:**
```typescript
{/* Enchantment Power (placeholder for Task 5) */}
<GameCard className="mt-4">
<div className="pb-2">
<h3 className="text-sm font-semibold text-[var(--text-primary)] flex items-center gap-2">
Enchantment Power
</h3>
</div>
<div>
<StatRow
label="Enchantment Power:"
value="1.0×"
highlight="info"
/>
<p className="text-xs text-[var(--text-muted)] mt-2">
Increases the power of all enchantments. Will be wired from Task 5 implementation.
</p>
</div>
</GameCard>
```
**Exact stub text:** "Increases the power of all enchantments. Will be wired from Task 5 implementation."
**Location:** Line 530 in EquipmentTab.tsx
---
## Other Unwired Stubs
### 1. AttunementsTab.tsx - Disenchanting TODO
**File:** `/home/user/repos/Mana-Loop/src/components/game/tabs/AttunementsTab.tsx`
**Line:** 198
**Content:**
```typescript
{cap === 'disenchanting' && '🔄 Disenchant'} {/* TODO: Remove after bug 13 complete */}
```
**Description:** TODO comment indicating disenchanting cap should be removed after bug 13 is complete.
### 2. AttunementsTab.tsx - Research TODO
**File:** `/home/user/repos/Mana-Loop/src/components/game/tabs/AttunementsTab.tsx`
**Line:** 249
**Content:**
```typescript
{cat === 'research' && '🔮 Research'} {/* TODO: Remove after Bug 12 - research moved to mana */}
```
**Description:** TODO comment indicating research category should be removed after Bug 12 (research moved to mana).
### 3. AttunementsTab.tsx.backup - Disenchanting TODO (backup file)
**File:** `/home/user/repos/Mana-Loop/src/components/game/tabs/AttunementsTab.tsx.backup`
**Line:** 198
**Content:**
```typescript
{cap === 'disenchanting' && '🔄 Disenchant'} // TODO: Remove after bug 13 complete
```
**Description:** Same as #1 but in backup file (can likely be ignored).
### 4. AttunementsTab.tsx.backup - Research TODO (backup file)
**File:** `/home/user/repos/Mana-Loop/src/components/game/tabs/AttunementsTab.tsx.backup`
**Line:** 249
**Content:**
```typescript
{cat === 'research' && '🔮 Research'} // TODO: Remove after Bug 12 - research moved to mana
```
**Description:** Same as #2 but in backup file (can likely be ignored).
### 5. skill-evolution.ts - Attunement Requirement Placeholder
**File:** `/home/user/repos/Mana-Loop/src/lib/game/skill-evolution.ts`
**Line:** 2218
**Content:**
```typescript
// Check attunement requirement (placeholder - would need actual attunement check)
```
**Description:** Placeholder comment indicating attunement requirement check is not implemented.
### 6. StatsTab.tsx - Enchantment Power (Wired but Non-functional)
**File:** `/home/user/repos/Mana-Loop/src/components/game/tabs/StatsTab.tsx`
**Lines:** 161-178
**Content:**
```typescript
{/* Enchantment Power (placeholder for Task 5) */}
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader className="pb-2">
<CardTitle className="text-blue-400 game-panel-title text-xs flex items-center gap-2">
Enchantment Power
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex justify-between text-sm">
<span className="text-gray-400">Enchantment Power:</span>
<span className="text-blue-300 font-[var(--font-mono)]">
{upgradeEffects && 'enchantPower' in upgradeEffects
? `${(upgradeEffects as Record<string, number>).enchantPower.toFixed(2)}×`
: '1.0×'}
</span>
</div>
<p className="text-xs text-gray-500 mt-2">
Increases the power of all enchantments. Wired from Task 5 implementation.
</p>
</CardContent>
</Card>
```
**Description:** This is labeled "Wired from Task 5 implementation" but the underlying `enchantPower` stat is not actually computed in `upgrade-effects.ts`. The display uses a type cast workaround.
---
## Effects System Overview
### How Effects Are Applied
The effects system is implemented across two main files:
#### 1. `src/lib/game/upgrade-effects.ts` - Skill Upgrade Effects
- **Interface:** `ComputedEffects` (lines 16-48)
- **Function:** `computeEffects()` (lines 260-330)
- Processes skill upgrade effects from `skillUpgrades` and `skillTiers`
- Handles three effect types:
- `multiplier` - multiplies a stat (e.g., `maxMana`, `regen`, `clickMana`)
- `bonus` - adds to a stat (e.g., `maxMana`, `regen`, `baseDamage`)
- `special` - adds a special effect ID to the `specials` set
#### 2. `src/lib/game/effects.ts` - Unified Effects (Skill + Equipment)
- **Function:** `computeEquipmentEffects()` (lines 20-78)
- Processes equipped item enchantments
- Returns `bonuses`, `multipliers`, and `specials`
- For each enchantment:
- `bonus` type: adds `effect.value * ench.stacks` to `bonuses[effect.stat]`
- `multiplier` type: multiplies `multipliers[effect.stat]` by `effect.value` for each stack
- `special` type: adds `effect.specialId` to `specials` set
- **Function:** `computeAllEffects()` (lines 91-137)
- Merges skill upgrade effects with equipment effects
- Merging strategy:
- Bonuses: ADD together
- Multipliers: MULTIPLY together
- Specials: UNION of sets
### Where Enchantment Power Multiplier Would Go
The `enchantmentPower` (or `enchantPower`) multiplier should:
1. **Be added to `ComputedEffects` interface** in `upgrade-effects.ts`:
```typescript
enchantmentPowerMultiplier: number; // defaults to 1
```
2. **Be handled in `computeEffects()` switch statement** in `upgrade-effects.ts`:
```typescript
case 'enchantPower':
effects.enchantmentPowerMultiplier *= effect.value;
break;
```
3. **Be applied in `computeEquipmentEffects()` or `computeAllEffects()`** in `effects.ts`:
- Option A: Apply to `effect.value` when processing each enchantment
- Option B: Apply as an additional multiplier in `computeAllEffects()`
The most logical place is in `computeEquipmentEffects()` where enchantment values are calculated:
```typescript
// When processing bonus effects:
bonuses[effect.stat] = (bonuses[effect.stat] || 0) + effect.value * ench.stacks * enchantmentPowerMultiplier;
// When processing multiplier effects:
// Each stack applies the multiplier, also modified by enchantmentPowerMultiplier
for (let i = 0; i < ench.stacks; i++) {
multipliers[key] *= (effect.value - 1) * enchantmentPowerMultiplier + 1;
// OR simpler: just multiply the final multiplier by enchantmentPowerMultiplier
}
```
### Current Multiplier Application (from effects.ts lines 48-57):
```typescript
} else if (effect.type === 'multiplier' && effect.stat && effect.value) {
// Multiplier effects multiply together
const key = effect.stat;
if (!multipliers[key]) {
multipliers[key] = 1;
}
// Each stack applies the multiplier
for (let i = 0; i < ench.stacks; i++) {
multipliers[key] *= effect.value;
}
}
```
**Note:** The `enchantmentPower` multiplier would need to be passed into `computeEquipmentEffects()` or applied after the fact in `computeAllEffects()`.
---
## Summary of Required Changes for Task 5 (Enchantment Power)
1. Add `enchantmentPowerMultiplier` field to `ComputedEffects` interface
2. Handle `enchantPower` stat in `computeEffects()` switch statement
3. Pass `enchantmentPowerMultiplier` to `computeEquipmentEffects()` or apply in `computeAllEffects()`
4. Update EquipmentTab.tsx stub to display actual value
5. Update StatsTab.tsx to use proper type-safe access for `enchantmentPowerMultiplier`
---
## Results (Task 18 Implementation)
### Implemented Changes
1. **Added `enchantmentPowerMultiplier` to `ComputedEffects` interface** in `src/lib/game/upgrade-effects.ts`:
- Added field `enchantmentPowerMultiplier: number;` to the interface
- Initialized to `1` in the `computeEffects()` function
2. **Handled `enchantPower` stat in `computeEffects()` switch statement** in `src/lib/game/upgrade-effects.ts`:
- Added case for `enchantPower` in the multiplier effects switch statement
- Multiplier is applied as: `effects.enchantmentPowerMultiplier *= effect.value;`
3. **Updated `computeEquipmentEffects()` to apply `enchantmentPowerMultiplier`** in `src/lib/game/effects.ts`:
- Added optional parameter `enchantmentPowerMultiplier: number = 1.0`
- Applied multiplier to both bonus and multiplier effect values:
- `const adjustedValue = effect.value * enchantmentPowerMultiplier;`
- Used `adjustedValue` instead of `effect.value` when computing enchantment effects
4. **Updated `computeAllEffects()` to pass the multiplier** in `src/lib/game/effects.ts`:
- Now passes `upgradeEffects.enchantmentPowerMultiplier` to `computeEquipmentEffects()`
5. **Replaced stub in EquipmentTab.tsx**:
- Changed from: "Increases the power of all enchantments. Will be wired from Task 5 implementation."
- Changed to: "Increases the power of all enchantments by X%. Multiplier applied to all enchantment effects."
- Now displays actual `enchantmentPowerMultiplier` value from `getUnifiedEffects(store)`
- Added `getUnifiedEffects` import from `@/lib/game/effects`
6. **Updated StatsTab.tsx to use type-safe access**:
- Changed from type cast workaround: `(upgradeEffects as Record<string, number>).enchantPower`
- Changed to proper access: `upgradeEffects?.enchantmentPowerMultiplier`
- Now displays the actual multiplier value and percentage
### Audit of Other Unwired Stubs
1. **AttunementsTab.tsx - Disenchanting TODO (Line 198)**: Logged in `docs/task5.md` under "Known Gaps" - waiting for Bug 13
2. **AttunementsTab.tsx - Research TODO (Line 249)**: Logged in `docs/task5.md` under "Known Gaps" - waiting for Bug 12
3. **AttunementsTab.tsx.backup - TODOs**: Backup file - ignored
4. **skill-evolution.ts - Attunement Requirement Placeholder (Line 2218)**: Logged in `docs/task5.md` under "Known Gaps" - placeholder for future implementation
5. **StatsTab.tsx - Enchantment Power**: ✅ Fixed (was already labeled "Wired" but now properly implemented)
### Files Modified
- `src/lib/game/upgrade-effects.ts` - Added `enchantmentPowerMultiplier` field and handler
- `src/lib/game/effects.ts` - Updated `computeEquipmentEffects()` and `computeAllEffects()` to apply multiplier
- `src/components/game/tabs/EquipmentTab.tsx` - Replaced stub, added import, displays actual value
- `src/components/game/tabs/StatsTab.tsx` - Updated to use type-safe access for `enchantmentPowerMultiplier`
- `docs/task5.md` - Added "Known Gaps" section documenting unwired stubs
### Testing Notes
- The `enchantmentPowerMultiplier` defaults to `1.0` (no effect)
- Skill perks that use `{ type: 'multiplier', stat: 'enchantPower', value: <decimal> }` will now properly affect enchantment power
- All enchantment effect values (both bonus and multiplier types) are multiplied by `enchantmentPowerMultiplier`
- The multiplier is applied per stack (each stack's effect value is multiplied)
### Status
✅ All tasks completed successfully