Compare commits

...

3 Commits

Author SHA1 Message Date
Z User
ae780e1bbc docs: add comprehensive game briefing document and fix deprecated tests
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 25s
- Created GAME_BRIEFING.md with full documentation of all game systems
- Fixed getFloorElement to use cycle length instead of hardcoded 8
- Fixed deprecated tests referencing removed elements (life, blood, wood)
- Fixed deprecated tests referencing removed skills (deepReservoir, etc.)
- Fixed guardian tests to not expect floor 70
- Fixed computeRegen tests to account for attunement regen correctly
- All 512 tests now pass

The game briefing document includes:
- Core game loop and progression
- Mana system with all 14 mana types
- Time and incursion mechanics
- Spire and floor system with room types
- Combat system with elemental effectiveness
- Guardian and pact system
- Attunement system (Enchanter, Invoker, Fabricator)
- Skill evolution with 5 tiers and milestone upgrades
- Equipment and enchantment system
- Golemancy system
- Prestige/loop mechanics
- Complete formulas and system interactions
2026-04-03 22:01:46 +00:00
Z User
c5dbd0606a Merge remote master into local main 2026-04-03 21:37:34 +00:00
Z User
4f474dbcf3 Initial commit 2026-04-03 17:23:15 +00:00
8 changed files with 1137 additions and 1238 deletions

View File

@@ -1 +1 @@
563
562

927
docs/GAME_BRIEFING.md Normal file
View 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*

View File

@@ -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);
});
});

View File

@@ -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

View File

@@ -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);
});

View File

@@ -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);
});

View File

@@ -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;
});