Compare commits
3 Commits
69a1d87169
...
ae780e1bbc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae780e1bbc | ||
|
|
c5dbd0606a | ||
|
|
4f474dbcf3 |
@@ -1 +1 @@
|
||||
563
|
||||
562
|
||||
|
||||
927
docs/GAME_BRIEFING.md
Normal file
927
docs/GAME_BRIEFING.md
Normal file
@@ -0,0 +1,927 @@
|
||||
# Mana-Loop: Comprehensive Game Briefing Document
|
||||
|
||||
**Document Version:** 1.0
|
||||
**Generated:** Game Systems Analysis
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Executive Summary](#executive-summary)
|
||||
2. [Core Game Loop](#core-game-loop)
|
||||
3. [Mana System](#mana-system)
|
||||
4. [Time & Incursion System](#time--incursion-system)
|
||||
5. [Spire & Floor System](#spire--floor-system)
|
||||
6. [Combat System](#combat-system)
|
||||
7. [Guardian & Pact System](#guardian--pact-system)
|
||||
8. [Attunement System](#attunement-system)
|
||||
9. [Skill System](#skill-system)
|
||||
10. [Equipment & Enchantment System](#equipment--enchantment-system)
|
||||
11. [Golemancy System](#golemancy-system)
|
||||
12. [Prestige/Loop System](#prestigeloop-system)
|
||||
13. [Achievement System](#achievement-system)
|
||||
14. [Formulas & Calculations](#formulas--calculations)
|
||||
15. [System Interactions](#system-interactions)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Mana-Loop** is a browser-based incremental/idle game with a 30-day time loop mechanic. Players gather mana, study skills, climb a 100-floor spire, defeat guardians, sign pacts, enchant equipment, and prestige for permanent progression.
|
||||
|
||||
**Key Differentiators:**
|
||||
- 3-class Attunement system (Enchanter, Invoker, Fabricator)
|
||||
- Equipment-based spell system (spells come from enchanted gear)
|
||||
- 5-tier skill evolution with milestone upgrade choices
|
||||
- Time pressure through incursion mechanic
|
||||
- Guardian pacts provide permanent multipliers
|
||||
|
||||
---
|
||||
|
||||
## Core Game Loop
|
||||
|
||||
### Primary Loop (Within Each Run)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ TIME LOOP (30 Days) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────┐ ┌──────────┐ ┌───────────┐ ┌───────┐ │
|
||||
│ │ GATHER │───▶│ STUDY │───▶│ CLIMB │───▶│ CRAFT │ │
|
||||
│ │ MANA │ │ SKILLS │ │ SPIRE │ │ GEAR │ │
|
||||
│ └─────────┘ └──────────┘ └───────────┘ └───────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ▼ ▼ ▼ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ DEFEAT GUARDIANS → SIGN PACTS │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ DAY 30: LOOP ENDS → GAIN INSIGHT │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Game Actions
|
||||
|
||||
| Action | Effect | Time Cost |
|
||||
|--------|--------|-----------|
|
||||
| **Meditate** | Regen mana with meditation bonus multiplier | Passive |
|
||||
| **Climb** | Progress through spire floors, cast spells | Active combat |
|
||||
| **Study** | Learn skills/spells, requires mana cost | Hours per level |
|
||||
| **Craft** | Create/enchant equipment | Hours per stage |
|
||||
| **Convert** | Auto-convert raw mana to elements | Per tick |
|
||||
| **Design** | Create enchantment designs | Hours |
|
||||
| **Prepare** | Ready equipment for enchanting | Hours + mana |
|
||||
| **Enchant** | Apply enchantment to equipment | Hours + mana |
|
||||
|
||||
---
|
||||
|
||||
## Mana System
|
||||
|
||||
### Mana Types Hierarchy
|
||||
|
||||
```
|
||||
Raw Mana (Base Resource)
|
||||
│
|
||||
├──▶ Base Elements (7) ─────────────────────────────────────┐
|
||||
│ Fire, Water, Air, Earth, Light, Dark, Death │
|
||||
│ │
|
||||
├──▶ Utility Element (1) ───────────────────────────────────┤
|
||||
│ Transference (Enchanter attunement) │
|
||||
│ │
|
||||
├──▶ Compound Elements (3) ── Created from 2 base ──────────┤
|
||||
│ Metal = Fire + Earth │
|
||||
│ Sand = Earth + Water │
|
||||
│ Lightning = Fire + Air │
|
||||
│ │
|
||||
└──▶ Exotic Elements (3) ── Created from advanced recipes ──┤
|
||||
Crystal = Sand + Sand + Light │
|
||||
Stellar = Fire + Fire + Light │
|
||||
Void = Dark + Dark + Death │
|
||||
```
|
||||
|
||||
### Mana Formulas
|
||||
|
||||
**Maximum Raw Mana:**
|
||||
```
|
||||
maxMana = (100 + (manaWellLevel × 100) + (prestigeManaWell × 500) + equipmentBonuses) × maxManaMultiplier
|
||||
```
|
||||
|
||||
**Maximum Elemental Mana:**
|
||||
```
|
||||
elementMax = (10 + (elemAttuneLevel × 50) + (prestigeElemAttune × 25)) × elementCapMultiplier
|
||||
```
|
||||
|
||||
**Base Regeneration (per hour):**
|
||||
```
|
||||
baseRegen = 2 + (manaFlowLevel × 1) + (manaSpringLevel × 2) + (prestigeManaFlow × 0.5)
|
||||
effectiveRegen = baseRegen × (1 - incursionStrength) × meditationMultiplier
|
||||
```
|
||||
|
||||
**Meditation Bonus:**
|
||||
```
|
||||
Base: 1 + min(hours/4, 0.5) = up to 1.5x after 4 hours
|
||||
With Meditation Focus skill: 2.5x after 4 hours
|
||||
With Deep Trance skill: 3.0x after 6 hours
|
||||
With Void Meditation skill: 5.0x after 8 hours
|
||||
```
|
||||
|
||||
**Attunement Mana Conversion:**
|
||||
- Enchanter: Raw → Transference at 0.2/hour base (scales with level)
|
||||
- Fabricator: Raw → Earth at 0.25/hour base (scales with level)
|
||||
|
||||
### Mana Conversion Cost
|
||||
- **100 Raw Mana = 1 Elemental Mana** (for base elements)
|
||||
- Compound/Exotic elements are crafted, not converted
|
||||
|
||||
---
|
||||
|
||||
## Time & Incursion System
|
||||
|
||||
### Time Constants
|
||||
|
||||
| Constant | Value | Description |
|
||||
|----------|-------|-------------|
|
||||
| `TICK_MS` | 200ms | Real time per game tick |
|
||||
| `HOURS_PER_TICK` | 0.04 | Game hours per tick |
|
||||
| `MAX_DAY` | 30 | Days per loop |
|
||||
| `INCURSION_START_DAY` | 20 | When incursion begins |
|
||||
|
||||
### Time Progression
|
||||
- 1 real second = 5 game hours (at 5 ticks/second)
|
||||
- 1 game day = 24 game hours = 4.8 real seconds
|
||||
- Full 30-day loop ≈ 2.4 real minutes
|
||||
|
||||
### Incursion Mechanic
|
||||
|
||||
**Incursion Strength Formula:**
|
||||
```
|
||||
if (day < 20): incursionStrength = 0
|
||||
else: incursionStrength = min(0.95, (totalHours / maxHours) × 0.95)
|
||||
```
|
||||
|
||||
**Effects:**
|
||||
- Reduces mana regeneration by `(1 - incursionStrength)`
|
||||
- Starts at 0% on Day 20, reaches 95% by Day 30
|
||||
- Creates urgency to complete objectives before loop ends
|
||||
|
||||
---
|
||||
|
||||
## Spire & Floor System
|
||||
|
||||
### Floor Generation
|
||||
|
||||
**Floor Element Cycle:**
|
||||
```javascript
|
||||
FLOOR_ELEM_CYCLE = ["fire", "water", "air", "earth", "light", "dark", "death"]
|
||||
element = FLOOR_ELEM_CYCLE[(floor - 1) % 7]
|
||||
```
|
||||
|
||||
**Floor HP Formula:**
|
||||
```
|
||||
normalFloorHP = floor(100 + floor × 50 + floor^1.7)
|
||||
guardianFloorHP = GUARDIANS[floor].hp // Fixed values
|
||||
```
|
||||
|
||||
**Guardian Floors:** 10, 20, 30, 40, 50, 60, 80, 90, 100
|
||||
|
||||
### Room Types
|
||||
|
||||
| Room Type | Chance | Description |
|
||||
|-----------|--------|-------------|
|
||||
| **Combat** | Default | Single enemy, normal combat |
|
||||
| **Guardian** | Fixed | Boss floor, always on guardian floors |
|
||||
| **Swarm** | 15% | 3-6 enemies with 40% HP each |
|
||||
| **Speed** | 10% | Enemy with dodge chance (25% base + 0.5%/floor) |
|
||||
| **Puzzle** | 20% on puzzle floors | Progress-based, faster with relevant attunement |
|
||||
|
||||
### Swarm Room Configuration
|
||||
```javascript
|
||||
SWARM_CONFIG = {
|
||||
minEnemies: 3,
|
||||
maxEnemies: 6,
|
||||
hpMultiplier: 0.4, // Each enemy has 40% of normal HP
|
||||
armorBase: 0,
|
||||
armorPerFloor: 0.01 // +1% armor per 10 floors
|
||||
}
|
||||
```
|
||||
|
||||
### Speed Room Configuration
|
||||
```javascript
|
||||
SPEED_ROOM_CONFIG = {
|
||||
baseDodgeChance: 0.25, // 25% base
|
||||
dodgePerFloor: 0.005, // +0.5% per floor
|
||||
maxDodge: 0.50 // Cap at 50%
|
||||
}
|
||||
```
|
||||
|
||||
### Armor Scaling
|
||||
```javascript
|
||||
FLOOR_ARMOR_CONFIG = {
|
||||
baseChance: 0, // No armor before floor 10
|
||||
chancePerFloor: 0.01, // +1% chance per floor after 10
|
||||
maxArmorChance: 0.5, // Max 50% of floors have armor
|
||||
minArmor: 0.05, // Min 5% damage reduction
|
||||
maxArmor: 0.25 // Max 25% on non-guardians
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Combat System
|
||||
|
||||
### Spell Casting Mechanics
|
||||
|
||||
**Cast Progress:**
|
||||
```
|
||||
progressPerTick = HOURS_PER_TICK × spellCastSpeed × totalAttackSpeed
|
||||
```
|
||||
|
||||
**Spell Cast Speed:**
|
||||
- Each spell has a `castSpeed` value (casts per hour)
|
||||
- Higher = faster casting
|
||||
- Lightning spells get +30% effective cast speed
|
||||
|
||||
**Damage Calculation:**
|
||||
```
|
||||
baseDamage = spellDamage + (combatTrainLevel × 5)
|
||||
pctBonus = 1 + (arcaneFuryLevel × 0.1)
|
||||
elemMastery = 1 + (elementalMasteryLevel × 0.15)
|
||||
pactMultiplier = product of all signed pact multipliers
|
||||
elementalBonus = getElementalBonus(spellElement, floorElement)
|
||||
|
||||
finalDamage = baseDamage × pctBonus × pactMultiplier × elemMastery × elementalBonus
|
||||
```
|
||||
|
||||
### Elemental Effectiveness
|
||||
|
||||
| Condition | Multiplier |
|
||||
|-----------|------------|
|
||||
| Spell same element as floor | 1.25x (25% bonus) |
|
||||
| Spell is opposite of floor element | 1.50x (Super Effective) |
|
||||
| Spell's opposite matches floor | 0.75x (Not Very Effective) |
|
||||
| Raw mana spells | 1.00x (No bonus) |
|
||||
|
||||
**Element Opposites:**
|
||||
```
|
||||
Fire ↔ Water
|
||||
Air ↔ Earth
|
||||
Light ↔ Dark
|
||||
Lightning ↔ (none, but has armor pierce)
|
||||
```
|
||||
|
||||
### Armor & Damage Reduction
|
||||
|
||||
**Effective Damage:**
|
||||
```
|
||||
effectiveArmor = max(0, enemyArmor - armorPierce)
|
||||
damageDealt = damage × (1 - effectiveArmor)
|
||||
```
|
||||
|
||||
**Armor Pierce Sources:**
|
||||
- Lightning spells: 20-50% pierce
|
||||
- Metal spells: 25-60% pierce
|
||||
- Golems: 15-60% pierce
|
||||
|
||||
### Critical Hits
|
||||
|
||||
```
|
||||
critChance = precisionLevel × 0.05
|
||||
critMultiplier = 1.5 (base)
|
||||
```
|
||||
|
||||
### AOE Mechanics
|
||||
|
||||
```
|
||||
aoeDamage = baseDamage × (1 - 0.1 × (numTargets - 1))
|
||||
// 10% less damage per additional target
|
||||
```
|
||||
|
||||
### Special Combat Effects
|
||||
|
||||
| Effect | Description |
|
||||
|--------|-------------|
|
||||
| **Burn** | Damage over time |
|
||||
| **Freeze** | Prevents dodge (100% freeze = no dodge) |
|
||||
| **Stun** | Temporary disable |
|
||||
| **Pierce** | Ignores percentage of armor |
|
||||
| **Chain** | Hits multiple targets |
|
||||
| **AOE** | Area damage |
|
||||
| **Buff** | Damage multiplier |
|
||||
|
||||
---
|
||||
|
||||
## Guardian & Pact System
|
||||
|
||||
### Guardian Floors & Stats
|
||||
|
||||
| Floor | Guardian | Element | HP | Pact Mult | Armor | Unique Perk |
|
||||
|-------|----------|---------|-----|-----------|-------|-------------|
|
||||
| 10 | Ignis Prime | Fire | 5,000 | 1.5x | 10% | Fire spells cast 10% faster |
|
||||
| 20 | Aqua Regia | Water | 15,000 | 1.75x | 15% | Water spells +15% damage |
|
||||
| 30 | Ventus Rex | Air | 30,000 | 2.0x | 18% | Air spells 15% crit chance |
|
||||
| 40 | Terra Firma | Earth | 50,000 | 2.25x | 25% | Earth spells +25% vs guardians |
|
||||
| 50 | Lux Aeterna | Light | 80,000 | 2.5x | 20% | Light spells reveal weaknesses (+20% dmg) |
|
||||
| 60 | Umbra Mortis | Dark | 120,000 | 2.75x | 22% | Dark spells +25% vs armored |
|
||||
| 80 | Mors Ultima | Death | 250,000 | 3.25x | 25% | Death spells execute <20% HP |
|
||||
| 90 | Primordialis | Void | 400,000 | 4.0x | 30% | Void spells ignore 30% resistance |
|
||||
| 100 | The Awakened One | Stellar | 1,000,000 | 5.0x | 35% | All spells +50% dmg, 25% faster |
|
||||
|
||||
### Guardian Boons
|
||||
|
||||
When a pact is signed, the guardian grants permanent boons:
|
||||
|
||||
| Boon Type | Effect | Example |
|
||||
|-----------|--------|---------|
|
||||
| `maxMana` | +Max raw mana | +50 to +500 |
|
||||
| `manaRegen` | +Regen/hour | +0.5 to +2 |
|
||||
| `castingSpeed` | +% cast speed | +5% |
|
||||
| `elementalDamage` | +% element damage | +5% to +20% |
|
||||
| `rawDamage` | +% all damage | +10% |
|
||||
| `critChance` | +% crit chance | N/A |
|
||||
| `critDamage` | +% crit multiplier | +15% |
|
||||
| `insightGain` | +% insight | +10% to +25% |
|
||||
|
||||
### Pact Ritual
|
||||
|
||||
**Pact Costs:**
|
||||
```javascript
|
||||
pactCost: 500 to 150,000 (raw mana)
|
||||
pactTime: 2 to 24 (hours for ritual)
|
||||
```
|
||||
|
||||
**Victory Condition:**
|
||||
- Defeat floor 100 guardian AND sign the pact
|
||||
- Awards 3x normal insight
|
||||
|
||||
---
|
||||
|
||||
## Attunement System
|
||||
|
||||
### Overview
|
||||
|
||||
Attunements are class-like specializations that grant unique capabilities and skill access.
|
||||
|
||||
### The Three Attunements
|
||||
|
||||
#### 1. Enchanter (Right Hand) ✅ Fully Implemented
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Slot** | Right Hand |
|
||||
| **Primary Mana** | Transference |
|
||||
| **Raw Regen** | +0.5/hour base |
|
||||
| **Conversion** | 0.2 raw→transference/hour |
|
||||
| **Unlock** | Starting attunement |
|
||||
|
||||
**Capabilities:**
|
||||
- Enchanting equipment
|
||||
- Disenchanting for mana recovery
|
||||
|
||||
**Skill Categories Unlocked:**
|
||||
- `enchant` - Enchanting efficiency
|
||||
- `effectResearch` - Unlock enchantment effects
|
||||
|
||||
---
|
||||
|
||||
#### 2. Invoker (Chest) ⚠️ Partially Implemented
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Slot** | Chest |
|
||||
| **Primary Mana** | None (gains from pacts) |
|
||||
| **Raw Regen** | +0.3/hour base |
|
||||
| **Conversion** | None |
|
||||
| **Unlock** | Defeat first guardian |
|
||||
|
||||
**Capabilities:**
|
||||
- Form pacts with guardians
|
||||
- Access guardian powers
|
||||
- Elemental mastery through pacts
|
||||
|
||||
**Skill Categories Unlocked:**
|
||||
- `invocation` - ⚠️ No skills defined
|
||||
- `pact` - ⚠️ No skills defined
|
||||
|
||||
---
|
||||
|
||||
#### 3. Fabricator (Left Hand) ✅ Implemented
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Slot** | Left Hand |
|
||||
| **Primary Mana** | Earth |
|
||||
| **Raw Regen** | +0.4/hour base |
|
||||
| **Conversion** | 0.25 raw→earth/hour |
|
||||
| **Unlock** | Prove crafting worth |
|
||||
|
||||
**Capabilities:**
|
||||
- Golem crafting
|
||||
- Gear crafting
|
||||
- Earth shaping
|
||||
|
||||
**Skill Categories Unlocked:**
|
||||
- `fabrication` - Crafting efficiency
|
||||
- `golemancy` - Golem control
|
||||
|
||||
### Attunement Leveling
|
||||
|
||||
**XP Formula:**
|
||||
```
|
||||
Level 2: 1,000 XP
|
||||
Level 3: 2,500 XP
|
||||
Level 4: 5,000 XP
|
||||
Level 5: 10,000 XP
|
||||
Each level: 2× previous (approximately)
|
||||
Max Level: 10
|
||||
```
|
||||
|
||||
**Level Scaling:**
|
||||
```
|
||||
regenMultiplier = 1.5^(level - 1)
|
||||
conversionRate = baseRate × 1.5^(level - 1)
|
||||
```
|
||||
|
||||
**XP Sources:**
|
||||
- Enchanting: 1 XP per 10 capacity used
|
||||
|
||||
---
|
||||
|
||||
## Skill System
|
||||
|
||||
### Skill Categories
|
||||
|
||||
| Category | Attunement | Description |
|
||||
|----------|------------|-------------|
|
||||
| `mana` | Core | Max mana, regen, element cap |
|
||||
| `study` | Core | Study speed, cost reduction |
|
||||
| `research` | Core | Click bonuses, advanced meditation |
|
||||
| `ascension` | Core | Insight, guardian damage |
|
||||
| `enchant` | Enchanter | Enchanting efficiency |
|
||||
| `effectResearch` | Enchanter | Unlock enchantment effects |
|
||||
| `invocation` | Invoker | ⚠️ Not implemented |
|
||||
| `pact` | Invoker | ⚠️ Not implemented |
|
||||
| `fabrication` | Fabricator | Crafting speed |
|
||||
| `golemancy` | Fabricator | Golem control |
|
||||
| `craft` | Legacy | Basic crafting |
|
||||
|
||||
### Core Skills
|
||||
|
||||
| Skill | Max | Effect | Study Time |
|
||||
|-------|-----|--------|------------|
|
||||
| Mana Well | 10 | +100 max mana/level | 4h |
|
||||
| Mana Flow | 10 | +1 regen/level | 5h |
|
||||
| Elem. Attunement | 10 | +50 element cap/level | 4h |
|
||||
| Mana Overflow | 5 | +25% click mana/level | 6h |
|
||||
| Quick Learner | 10 | +10% study speed/level | 4h |
|
||||
| Focused Mind | 10 | -5% study cost/level | 5h |
|
||||
| Meditation Focus | 1 | 2.5x regen after 4h | 6h |
|
||||
|
||||
### Skill Tier Evolution
|
||||
|
||||
**5-Tier System:**
|
||||
```
|
||||
Tier 1: Base skill (multiplier ×1)
|
||||
Tier 2: Enhanced (multiplier ×10)
|
||||
Tier 3: Master (multiplier ×100)
|
||||
Tier 4: Legendary (multiplier ×1,000)
|
||||
Tier 5: Mythic (multiplier ×10,000)
|
||||
```
|
||||
|
||||
**Tier Up:**
|
||||
- Requires max level (10) in current tier
|
||||
- Unlocks new skill ID (e.g., `manaWell_t2`)
|
||||
|
||||
### Milestone Upgrades
|
||||
|
||||
**At Level 5 and Level 10:**
|
||||
- Choose 2 upgrades from 4+ options
|
||||
- Upgrades can be stat multipliers, bonuses, or special effects
|
||||
- Some upgrades have upgrade paths
|
||||
|
||||
**Example Mana Well Tier 1 Upgrades:**
|
||||
| Level | Upgrade | Effect |
|
||||
|-------|---------|--------|
|
||||
| 5 | Expanded Capacity | +25% max mana |
|
||||
| 5 | Natural Spring | +0.5 regen |
|
||||
| 5 | Mana Threshold | +30% max, -10% regen |
|
||||
| 10 | Deep Reservoir | +50% max (replaces Expanded) |
|
||||
| 10 | Deep Wellspring | +50% meditation efficiency |
|
||||
|
||||
### Enchanter Skills
|
||||
|
||||
| Skill | Max | Requirement | Effect |
|
||||
|-------|-----|-------------|--------|
|
||||
| Enchanting | 10 | Enchanter 1 | Unlocks enchantment design |
|
||||
| Efficient Enchant | 5 | Enchanter 2, Enchanting 3 | -5% capacity cost/level |
|
||||
| Disenchanting | 3 | Enchanter 1, Enchanting 2 | +20% mana recovery/level |
|
||||
| Enchant Speed | 5 | Enchanter 1, Enchanting 2 | -10% time/level |
|
||||
| Scroll Crafting | 3 | Enchanter 3, Enchanting 5 | ⚠️ Not implemented |
|
||||
| Essence Refining | 5 | Enchanter 2, Enchanting 4 | +10% effect power/level |
|
||||
|
||||
### Golemancy Skills
|
||||
|
||||
| Skill | Max | Requirement | Effect |
|
||||
|-------|-----|-------------|--------|
|
||||
| Golem Mastery | 5 | Fabricator 2 | +10% golem damage/level |
|
||||
| Golem Efficiency | 5 | Fabricator 2 | +5% attack speed/level |
|
||||
| Golem Longevity | 3 | Fabricator 3 | +1 floor duration/level |
|
||||
| Golem Siphon | 3 | Fabricator 3 | -10% maintenance/level |
|
||||
| Advanced Golemancy | 1 | Fabricator 5, Mastery 3 | Unlock hybrid golems |
|
||||
|
||||
---
|
||||
|
||||
## Equipment & Enchantment System
|
||||
|
||||
### Equipment Slots
|
||||
|
||||
```
|
||||
mainHand - Staves, Wands, Swords
|
||||
offHand - Shields, Catalysts
|
||||
head - Hoods, Hats, Helms
|
||||
body - Robes, Armor
|
||||
hands - Gloves, Gauntlets
|
||||
feet - Boots, Shoes
|
||||
accessory1 - Rings, Amulets
|
||||
accessory2 - Rings, Amulets
|
||||
```
|
||||
|
||||
### Equipment Categories
|
||||
|
||||
| Category | Slots | Description |
|
||||
|----------|-------|-------------|
|
||||
| Caster | Main Hand | Staves and wands for spellcasting |
|
||||
| Sword | Main Hand | Magic swords with weapon enchants |
|
||||
| Catalyst | Main Hand | Amplifies magical effects |
|
||||
| Shield | Off Hand | Defensive equipment |
|
||||
| Head/Body/Hands/Feet | Respective | Armor pieces |
|
||||
| Accessory | Accessory1/2 | Rings and amulets |
|
||||
|
||||
### Equipment Instance Structure
|
||||
|
||||
```typescript
|
||||
interface EquipmentInstance {
|
||||
instanceId: string; // Unique ID
|
||||
typeId: string; // Reference to EquipmentType
|
||||
name: string;
|
||||
enchantments: AppliedEnchantment[];
|
||||
usedCapacity: number; // Current capacity used
|
||||
totalCapacity: number; // Max capacity
|
||||
rarity: 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary' | 'mythic';
|
||||
quality: number; // 0-100
|
||||
}
|
||||
```
|
||||
|
||||
### Enchantment Process (3 Stages)
|
||||
|
||||
#### Stage 1: Design
|
||||
- Create enchantment design
|
||||
- Select effects from unlocked pool
|
||||
- Calculate capacity cost
|
||||
- Time: Base 1h + 0.5h per effect stack
|
||||
|
||||
**Capacity Cost Formula:**
|
||||
```
|
||||
totalCost = Σ(effect.baseCost × (1 + 0.2 × stackIndex) × (1 - efficiencyBonus))
|
||||
```
|
||||
|
||||
#### Stage 2: Prepare
|
||||
- Prepare equipment for enchanting
|
||||
- Mana cost: capacity × 10
|
||||
- Time: 2h + 1h per 50 capacity
|
||||
|
||||
#### Stage 3: Apply
|
||||
- Apply enchantment design
|
||||
- Mana per hour: 20 + 5 per effect stack
|
||||
- Time: 2h + 1h per effect stack
|
||||
- Grants Enchanter XP: 1 XP per 10 capacity
|
||||
|
||||
### Enchantment Effect Categories
|
||||
|
||||
| Category | Description | Equipment Types |
|
||||
|----------|-------------|-----------------|
|
||||
| **Spell** | Grants spell ability | Casters only |
|
||||
| **Mana** | Max/regen/click bonuses | Casters, Catalysts, Head, Body, Accessories |
|
||||
| **Combat** | Damage, crit, speed | Casters, Hands |
|
||||
| **Utility** | Study, meditation, insight | Most equipment |
|
||||
| **Special** | Unique effects | Various |
|
||||
| **Elemental** | Weapon enchantments | Swords, Casters |
|
||||
|
||||
### Starting Equipment
|
||||
|
||||
| Slot | Item | Enchantment | Capacity |
|
||||
|------|------|-------------|----------|
|
||||
| Main Hand | Basic Staff | Mana Bolt spell | 50/50 |
|
||||
| Body | Civilian Shirt | None | 0/30 |
|
||||
| Feet | Civilian Shoes | None | 0/15 |
|
||||
|
||||
---
|
||||
|
||||
## Golemancy System
|
||||
|
||||
### Golem Slots
|
||||
|
||||
```
|
||||
Fabricator Level 2: 1 slot
|
||||
Fabricator Level 4: 2 slots
|
||||
Fabricator Level 6: 3 slots
|
||||
Fabricator Level 8: 4 slots
|
||||
Fabricator Level 10: 5 slots
|
||||
|
||||
slots = floor(fabricatorLevel / 2)
|
||||
```
|
||||
|
||||
### Golem Types
|
||||
|
||||
#### Base Golems
|
||||
|
||||
| Golem | Element | Damage | Speed | Armor Pierce | Unlock |
|
||||
|-------|---------|--------|-------|--------------|--------|
|
||||
| Earth Golem | Earth | 8 | 1.5/h | 15% | Fabricator 2 |
|
||||
|
||||
#### Elemental Variants
|
||||
|
||||
| Golem | Element | Damage | Speed | Pierce | Unlock |
|
||||
|-------|---------|--------|-------|--------|--------|
|
||||
| Steel Golem | Metal | 12 | 1.2/h | 35% | Metal mana unlocked |
|
||||
| Crystal Golem | Crystal | 18 | 1.0/h | 25% | Crystal mana unlocked |
|
||||
| Sand Golem | Sand | 6 | 2.0/h | 10% | Sand mana unlocked |
|
||||
|
||||
#### Advanced Hybrid Golems (Enchanter 5 + Fabricator 5)
|
||||
|
||||
| Golem | Elements | Damage | Speed | Pierce | Special |
|
||||
|-------|----------|--------|-------|--------|---------|
|
||||
| Lava Golem | Earth + Fire | 15 | 1.0/h | 20% | AOE 2 |
|
||||
| Galvanic Golem | Metal + Lightning | 10 | 3.5/h | 45% | Fast |
|
||||
| Obsidian Golem | Earth + Dark | 25 | 0.8/h | 50% | High damage |
|
||||
| Prism Golem | Crystal + Light | 20 | 1.5/h | 35% | AOE 3 |
|
||||
| Quicksilver Golem | Metal + Water | 8 | 4.0/h | 30% | Very fast |
|
||||
| Voidstone Golem | Earth + Void | 40 | 0.6/h | 60% | Ultimate |
|
||||
|
||||
### Golem Costs
|
||||
|
||||
**Summon Cost (one-time per floor):**
|
||||
```
|
||||
Earth Golem: 10 Earth
|
||||
Steel Golem: 8 Metal + 5 Earth
|
||||
Crystal Golem: 6 Crystal + 3 Earth
|
||||
```
|
||||
|
||||
**Maintenance Cost (per tick):**
|
||||
```
|
||||
Earth Golem: 0.5 Earth/hour
|
||||
Steel Golem: 0.6 Metal + 0.2 Earth/hour
|
||||
```
|
||||
|
||||
### Golem Duration
|
||||
|
||||
```
|
||||
baseDuration = 1 floor
|
||||
with Golem Longevity: +1 floor per level (max 4 floors)
|
||||
```
|
||||
|
||||
### Golem Combat
|
||||
|
||||
**Attack Progress:**
|
||||
```
|
||||
progressPerTick = HOURS_PER_TICK × attackSpeed × efficiencyBonus
|
||||
```
|
||||
|
||||
**Damage:**
|
||||
```
|
||||
damage = baseDamage × (1 + golemMastery × 0.1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prestige/Loop System
|
||||
|
||||
### Loop End Conditions
|
||||
|
||||
| Condition | Result |
|
||||
|-----------|--------|
|
||||
| Day 30 reached | Loop ends, gain insight |
|
||||
| Floor 100 + Pact 100 signed | Victory! 3× insight |
|
||||
|
||||
### Insight Formula
|
||||
|
||||
```
|
||||
baseInsight = floor(maxFloorReached × 15 + totalManaGathered / 500 + signedPacts.length × 150)
|
||||
finalInsight = floor(baseInsight × (1 + insightAmpLevel × 0.25) × skillBonus)
|
||||
```
|
||||
|
||||
### Prestige Upgrades
|
||||
|
||||
| Upgrade | Max | Cost | Effect |
|
||||
|---------|-----|------|--------|
|
||||
| Mana Well | 5 | 500 | +500 starting max mana |
|
||||
| Mana Flow | 10 | 750 | +0.5 permanent regen |
|
||||
| Deep Memory | 5 | 1000 | +1 memory slot |
|
||||
| Insight Amp | 4 | 1500 | +25% insight gain |
|
||||
| Spire Key | 5 | 4000 | Start at floor +2 |
|
||||
| Temporal Echo | 5 | 3000 | +10% mana generation |
|
||||
| Steady Hand | 5 | 1200 | -15% durability loss |
|
||||
| Ancient Knowledge | 5 | 2000 | Start with blueprint |
|
||||
| Elemental Attune | 10 | 600 | +25 element cap |
|
||||
| Spell Memory | 3 | 2500 | Start with random spell |
|
||||
| Guardian Pact | 5 | 3500 | +10% pact multiplier |
|
||||
| Quick Start | 3 | 400 | +100 starting mana |
|
||||
| Elem. Start | 3 | 800 | +5 each unlocked element |
|
||||
|
||||
### Memory System
|
||||
|
||||
- **Base slots:** 3
|
||||
- **Additional:** +1 per Deep Memory level
|
||||
- **Memories:** Spells or skills preserved across loops
|
||||
|
||||
---
|
||||
|
||||
## Achievement System
|
||||
|
||||
### Achievement Categories
|
||||
|
||||
| Category | Description |
|
||||
|----------|-------------|
|
||||
| `mana` | Mana gathering milestones |
|
||||
| `combat` | Combat achievements |
|
||||
| `progression` | Floor/guardian progression |
|
||||
| `crafting` | Equipment and enchanting |
|
||||
| `prestige` | Loop and insight milestones |
|
||||
|
||||
### Achievement Rewards
|
||||
|
||||
| Reward Type | Effect |
|
||||
|-------------|--------|
|
||||
| `insight` | One-time insight bonus |
|
||||
| `manaBonus` | Permanent max mana |
|
||||
| `damageBonus` | Permanent damage increase |
|
||||
| `regenBonus` | Permanent regen increase |
|
||||
| `title` | Cosmetic title |
|
||||
| `unlockEffect` | Unlocks enchantment effect |
|
||||
|
||||
---
|
||||
|
||||
## Formulas & Calculations
|
||||
|
||||
### Damage Calculation (Complete)
|
||||
|
||||
```javascript
|
||||
function calcDamage(state, spellId, floorElement) {
|
||||
const spell = SPELLS_DEF[spellId];
|
||||
|
||||
// Base damage
|
||||
let damage = spell.dmg + (state.skills.combatTrain || 0) * 5;
|
||||
|
||||
// Percentage multipliers
|
||||
damage *= 1 + (state.skills.arcaneFury || 0) * 0.1;
|
||||
|
||||
// Elemental mastery
|
||||
damage *= 1 + (state.skills.elementalMastery || 0) * 0.15;
|
||||
|
||||
// Guardian bane (vs guardians only)
|
||||
if (isGuardian) {
|
||||
damage *= 1 + (state.skills.guardianBane || 0) * 0.2;
|
||||
}
|
||||
|
||||
// Pact multiplier
|
||||
damage *= state.signedPacts.reduce((m, f) => m * GUARDIANS[f].pact, 1);
|
||||
|
||||
// Elemental effectiveness
|
||||
damage *= getElementalBonus(spell.elem, floorElement);
|
||||
|
||||
// Critical hit
|
||||
const critChance = (state.skills.precision || 0) * 0.05;
|
||||
if (Math.random() < critChance) {
|
||||
damage *= 1.5;
|
||||
}
|
||||
|
||||
// Equipment effects
|
||||
damage *= effects.baseDamageMultiplier;
|
||||
damage += effects.baseDamageBonus;
|
||||
|
||||
// Armor reduction
|
||||
const effectiveArmor = Math.max(0, enemyArmor - armorPierce);
|
||||
damage *= (1 - effectiveArmor);
|
||||
|
||||
return Math.floor(damage);
|
||||
}
|
||||
```
|
||||
|
||||
### Study Time Calculation
|
||||
|
||||
```javascript
|
||||
effectiveStudyTime = baseStudyTime × tier / studySpeedMultiplier
|
||||
|
||||
studySpeedMultiplier = 1 + (quickLearnerLevel × 0.1) + equipmentBonus
|
||||
```
|
||||
|
||||
### Study Cost Calculation
|
||||
|
||||
```javascript
|
||||
effectiveCost = floor(baseCost × (currentLevel + 1) × tier × costMultiplier)
|
||||
|
||||
costMultiplier = 1 - (focusedMindLevel × 0.05)
|
||||
```
|
||||
|
||||
### DPS Calculation
|
||||
|
||||
```javascript
|
||||
dps = (damage × castSpeed × attackSpeedMultiplier) / hour
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## System Interactions
|
||||
|
||||
### Primary Interaction Map
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ CORE SYSTEM INTERACTIONS │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ MANA │────────▶│ SKILLS │────────▶│ COMBAT │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ATTUNEMENT│────────▶│ENCHANTING│────────▶│ SPIRE │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │GOLEMANCY │ │EQUIPMENT │────────▶│ GUARDIAN │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ │
|
||||
│ │ PACT │ │
|
||||
│ └──────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ │
|
||||
│ │ PRESTIGE │ │
|
||||
│ └──────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Key System Dependencies
|
||||
|
||||
| System | Depends On | Unlocks/Enables |
|
||||
|--------|------------|-----------------|
|
||||
| **Skills** | Mana (cost) | All combat/crafting bonuses |
|
||||
| **Enchanting** | Enchanter attunement, Skills | Equipment spells, bonuses |
|
||||
| **Golemancy** | Fabricator attunement, Earth mana | Additional combat damage |
|
||||
| **Pacts** | Guardian defeat | Permanent multipliers, boons |
|
||||
| **Prestige** | Loop completion | Permanent upgrades, memories |
|
||||
| **Equipment** | Crafting/Blueprints | Spell access, stat bonuses |
|
||||
|
||||
### Progression Gates
|
||||
|
||||
1. **Early Game (Floors 1-10):**
|
||||
- Mana gathering and regen
|
||||
- Basic skills (mana, study categories)
|
||||
- Starting equipment
|
||||
|
||||
2. **Mid Game (Floors 10-40):**
|
||||
- First guardian pacts
|
||||
- Attunement unlocking
|
||||
- Equipment enchanting
|
||||
- Golemancy (Fabricator)
|
||||
|
||||
3. **Late Game (Floors 40-80):**
|
||||
- Compound/exotic elements
|
||||
- Hybrid golems
|
||||
- Skill tier evolution
|
||||
- Advanced enchantments
|
||||
|
||||
4. **End Game (Floors 80-100):**
|
||||
- Void/Stellar/Crystal spells
|
||||
- Ultimate golems
|
||||
- Victory preparation
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Known Issues
|
||||
|
||||
### Missing Implementations
|
||||
|
||||
1. **Invocation Skills** - Category defined but no skills
|
||||
2. **Pact Skills** - Category defined but no skills
|
||||
3. **Scroll Crafting** - Skill exists, no system
|
||||
4. **Field Repair** - Skill exists, no repair system
|
||||
|
||||
### Balance Concerns
|
||||
|
||||
1. Exotic elements require extreme mana investment
|
||||
2. Incursion creates hard time pressure without counterplay
|
||||
3. Equipment progression limited after starting gear
|
||||
|
||||
---
|
||||
|
||||
*End of Game Briefing Document*
|
||||
@@ -221,7 +221,8 @@ describe('computeRegen', () => {
|
||||
};
|
||||
const effects = { regenBonus: 0, regenMultiplier: 1, permanentRegenBonus: 0 };
|
||||
const result = computeRegen(state, effects);
|
||||
expect(result).toBe(2); // Base regen
|
||||
// Base regen is 2 (this test provides effects, so no attunement bonus)
|
||||
expect(result).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ export function getFloorMaxHP(floor: number): number {
|
||||
}
|
||||
|
||||
export function getFloorElement(floor: number): string {
|
||||
return FLOOR_ELEM_CYCLE[(floor - 1) % 8];
|
||||
return FLOOR_ELEM_CYCLE[(floor - 1) % FLOOR_ELEM_CYCLE.length];
|
||||
}
|
||||
|
||||
// ─── Equipment Spell Helper ─────────────────────────────────────────────────────
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -261,17 +261,17 @@ describe('SkillStore', () => {
|
||||
it('should not start studying without prerequisites', () => {
|
||||
useManaStore.getState().addRawMana(990, 1000);
|
||||
|
||||
// deepReservoir requires manaWell 5
|
||||
const result = useSkillStore.getState().startStudyingSkill('deepReservoir', 1000);
|
||||
// manaOverflow requires manaWell 3
|
||||
const result = useSkillStore.getState().startStudyingSkill('manaOverflow', 1000);
|
||||
|
||||
expect(result.started).toBe(false);
|
||||
});
|
||||
|
||||
it('should start studying with prerequisites met', () => {
|
||||
useManaStore.getState().addRawMana(990, 1000);
|
||||
useSkillStore.getState().setSkillLevel('manaWell', 5);
|
||||
useSkillStore.getState().setSkillLevel('manaWell', 3);
|
||||
|
||||
const result = useSkillStore.getState().startStudyingSkill('deepReservoir', 1000);
|
||||
const result = useSkillStore.getState().startStudyingSkill('manaOverflow', 1000);
|
||||
|
||||
expect(result.started).toBe(true);
|
||||
});
|
||||
|
||||
@@ -61,17 +61,17 @@ describe('SkillStore', () => {
|
||||
|
||||
it('should not start studying without prerequisites', () => {
|
||||
const skillStore = useSkillStore.getState();
|
||||
// deepReservoir requires manaWell level 5
|
||||
const result = skillStore.startStudyingSkill('deepReservoir', 1000);
|
||||
// manaOverflow requires manaWell level 3
|
||||
const result = skillStore.startStudyingSkill('manaOverflow', 1000);
|
||||
|
||||
expect(result.started).toBe(false);
|
||||
});
|
||||
|
||||
it('should start studying with prerequisites met', () => {
|
||||
useSkillStore.setState({ skills: { manaWell: 5 } });
|
||||
useSkillStore.setState({ skills: { manaWell: 3 } });
|
||||
|
||||
const skillStore = useSkillStore.getState();
|
||||
const result = skillStore.startStudyingSkill('deepReservoir', 1000);
|
||||
const result = skillStore.startStudyingSkill('manaOverflow', 1000);
|
||||
|
||||
expect(result.started).toBe(true);
|
||||
});
|
||||
@@ -271,36 +271,36 @@ describe('ManaStore', () => {
|
||||
|
||||
describe('craftComposite', () => {
|
||||
it('should craft composite element with correct ingredients', () => {
|
||||
// Set up ingredients for blood (life + water)
|
||||
// Set up ingredients for metal (fire + earth)
|
||||
useManaStore.setState({
|
||||
elements: {
|
||||
...useManaStore.getState().elements,
|
||||
life: { current: 5, max: 10, unlocked: true },
|
||||
water: { current: 5, max: 10, unlocked: true },
|
||||
fire: { current: 5, max: 10, unlocked: true },
|
||||
earth: { current: 5, max: 10, unlocked: true },
|
||||
}
|
||||
});
|
||||
|
||||
const result = useManaStore.getState().craftComposite('blood', ['life', 'water']);
|
||||
const result = useManaStore.getState().craftComposite('metal', ['fire', 'earth']);
|
||||
|
||||
expect(result).toBe(true);
|
||||
|
||||
const state = useManaStore.getState();
|
||||
expect(state.elements.life.current).toBe(4);
|
||||
expect(state.elements.water.current).toBe(4);
|
||||
expect(state.elements.blood.current).toBe(1);
|
||||
expect(state.elements.blood.unlocked).toBe(true);
|
||||
expect(state.elements.fire.current).toBe(4);
|
||||
expect(state.elements.earth.current).toBe(4);
|
||||
expect(state.elements.metal.current).toBe(1);
|
||||
expect(state.elements.metal.unlocked).toBe(true);
|
||||
});
|
||||
|
||||
it('should not craft without ingredients', () => {
|
||||
useManaStore.setState({
|
||||
elements: {
|
||||
...useManaStore.getState().elements,
|
||||
life: { current: 0, max: 10, unlocked: true },
|
||||
water: { current: 0, max: 10, unlocked: true },
|
||||
fire: { current: 0, max: 10, unlocked: true },
|
||||
earth: { current: 0, max: 10, unlocked: true },
|
||||
}
|
||||
});
|
||||
|
||||
const result = useManaStore.getState().craftComposite('blood', ['life', 'water']);
|
||||
const result = useManaStore.getState().craftComposite('metal', ['fire', 'earth']);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Comprehensive Store Tests
|
||||
*
|
||||
* Tests the split store architecture to ensure all stores work correctly together.
|
||||
* Updated for the new skill system with tiers and upgrade trees.
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach } from 'bun:test';
|
||||
@@ -89,8 +90,20 @@ function createMockState(overrides: Partial<GameState> = {}): GameState {
|
||||
autoSchedule: false,
|
||||
studyQueue: [],
|
||||
craftQueue: [],
|
||||
attunements: {
|
||||
enchanter: { id: 'enchanter', active: true, level: 1, experience: 0 },
|
||||
invoker: { id: 'invoker', active: false, level: 1, experience: 0 },
|
||||
fabricator: { id: 'fabricator', active: false, level: 1, experience: 0 },
|
||||
},
|
||||
golemancy: {
|
||||
enabledGolems: [],
|
||||
summonedGolems: [],
|
||||
lastSummonFloor: 0,
|
||||
},
|
||||
equippedInstances: { mainHand: null, offHand: null, head: null, body: null, hands: null, accessory1: null, accessory2: null },
|
||||
equipmentInstances: {},
|
||||
...overrides,
|
||||
};
|
||||
} as GameState;
|
||||
}
|
||||
|
||||
// ─── Utility Function Tests ─────────────────────────────────────────────────
|
||||
@@ -140,43 +153,42 @@ describe('Mana Calculations', () => {
|
||||
expect(computeMaxMana(state)).toBe(100 + 5 * 100);
|
||||
});
|
||||
|
||||
it('should add mana from deepReservoir skill', () => {
|
||||
const state = createMockState({ skills: { deepReservoir: 3 } });
|
||||
expect(computeMaxMana(state)).toBe(100 + 3 * 500);
|
||||
});
|
||||
|
||||
it('should add mana from prestige upgrades', () => {
|
||||
const state = createMockState({ prestigeUpgrades: { manaWell: 3 } });
|
||||
expect(computeMaxMana(state)).toBe(100 + 3 * 500);
|
||||
});
|
||||
|
||||
it('should stack all mana bonuses', () => {
|
||||
it('should stack manaWell skill and prestige', () => {
|
||||
const state = createMockState({
|
||||
skills: { manaWell: 5, deepReservoir: 2 },
|
||||
skills: { manaWell: 5 },
|
||||
prestigeUpgrades: { manaWell: 2 },
|
||||
});
|
||||
expect(computeMaxMana(state)).toBe(100 + 5 * 100 + 2 * 500 + 2 * 500);
|
||||
expect(computeMaxMana(state)).toBe(100 + 5 * 100 + 2 * 500);
|
||||
});
|
||||
});
|
||||
|
||||
describe('computeRegen', () => {
|
||||
it('should return base regen with no upgrades', () => {
|
||||
// Base regen is 2 (attunement regen is added separately in the store)
|
||||
const state = createMockState();
|
||||
expect(computeRegen(state)).toBe(2);
|
||||
});
|
||||
|
||||
it('should add regen from manaFlow skill', () => {
|
||||
// Base 2 + manaFlow 5
|
||||
const state = createMockState({ skills: { manaFlow: 5 } });
|
||||
expect(computeRegen(state)).toBe(2 + 5 * 1);
|
||||
});
|
||||
|
||||
it('should add regen from manaSpring skill', () => {
|
||||
// Base 2 + manaSpring 2
|
||||
const state = createMockState({ skills: { manaSpring: 1 } });
|
||||
expect(computeRegen(state)).toBe(2 + 2);
|
||||
});
|
||||
|
||||
it('should multiply by temporal echo prestige', () => {
|
||||
const state = createMockState({ prestigeUpgrades: { temporalEcho: 2 } });
|
||||
// Base 2 * 1.2 = 2.4
|
||||
expect(computeRegen(state)).toBe(2 * 1.2);
|
||||
});
|
||||
});
|
||||
@@ -231,19 +243,6 @@ describe('Combat Calculations', () => {
|
||||
expect(dmg).toBeGreaterThanOrEqual(5); // Base damage (can be higher with crit)
|
||||
});
|
||||
|
||||
it('should add damage from combatTrain skill', () => {
|
||||
const state = createMockState({ skills: { combatTrain: 5 } });
|
||||
const dmg = calcDamage(state, 'manaBolt');
|
||||
expect(dmg).toBeGreaterThanOrEqual(5 + 5 * 5); // 5 base + 25 from skill
|
||||
});
|
||||
|
||||
it('should multiply by arcaneFury skill', () => {
|
||||
const state = createMockState({ skills: { arcaneFury: 3 } });
|
||||
const dmg = calcDamage(state, 'manaBolt');
|
||||
// 5 * 1.3 = 6.5 minimum (without crit)
|
||||
expect(dmg).toBeGreaterThanOrEqual(5 * 1.3 * 0.8);
|
||||
});
|
||||
|
||||
it('should have elemental bonuses', () => {
|
||||
const state = createMockState({
|
||||
spells: {
|
||||
@@ -280,15 +279,22 @@ describe('Combat Calculations', () => {
|
||||
|
||||
describe('getFloorElement', () => {
|
||||
it('should cycle through elements in order', () => {
|
||||
// FLOOR_ELEM_CYCLE has 7 elements: fire, water, air, earth, light, dark, death
|
||||
expect(getFloorElement(1)).toBe('fire');
|
||||
expect(getFloorElement(2)).toBe('water');
|
||||
expect(getFloorElement(3)).toBe('air');
|
||||
expect(getFloorElement(4)).toBe('earth');
|
||||
expect(getFloorElement(5)).toBe('light');
|
||||
expect(getFloorElement(6)).toBe('dark');
|
||||
expect(getFloorElement(7)).toBe('death');
|
||||
});
|
||||
|
||||
it('should wrap around after 8 floors', () => {
|
||||
expect(getFloorElement(9)).toBe('fire');
|
||||
expect(getFloorElement(10)).toBe('water');
|
||||
it('should wrap around after 7 floors', () => {
|
||||
// Floor 8 should be fire (wraps around)
|
||||
expect(getFloorElement(8)).toBe('fire');
|
||||
expect(getFloorElement(9)).toBe('water');
|
||||
expect(getFloorElement(15)).toBe('fire'); // (15-1) % 7 = 0
|
||||
expect(getFloorElement(16)).toBe('water'); // (16-1) % 7 = 1
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -463,7 +469,8 @@ describe('Spell Cost System', () => {
|
||||
|
||||
describe('Skill Definitions', () => {
|
||||
it('all skills should have valid categories', () => {
|
||||
const validCategories = ['mana', 'combat', 'study', 'craft', 'research', 'ascension'];
|
||||
const validCategories = ['mana', 'study', 'research', 'ascension', 'enchant',
|
||||
'effectResearch', 'invocation', 'pact', 'fabrication', 'golemancy', 'craft'];
|
||||
Object.values(SKILLS_DEF).forEach(skill => {
|
||||
expect(validCategories).toContain(skill.cat);
|
||||
});
|
||||
@@ -531,15 +538,16 @@ describe('Prestige Upgrades', () => {
|
||||
// ─── Guardian Tests ──────────────────────────────────────────────────────
|
||||
|
||||
describe('Guardian Definitions', () => {
|
||||
it('should have guardians every 10 floors', () => {
|
||||
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100].forEach(floor => {
|
||||
it('should have guardians on expected floors (no floor 70)', () => {
|
||||
// Floor 70 was removed from the game
|
||||
[10, 20, 30, 40, 50, 60, 80, 90, 100].forEach(floor => {
|
||||
expect(GUARDIANS[floor]).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should have increasing HP', () => {
|
||||
let prevHP = 0;
|
||||
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100].forEach(floor => {
|
||||
[10, 20, 30, 40, 50, 60, 80, 90, 100].forEach(floor => {
|
||||
expect(GUARDIANS[floor].hp).toBeGreaterThan(prevHP);
|
||||
prevHP = GUARDIANS[floor].hp;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user