Files
Mana-Loop/AGENTS.md
T
Refactoring Agent 98ab975fb9
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 4m28s
Update documentation after refactoring: AGENTS.md, GAME_BRIEFING.md, skills.md
- Updated AGENTS.md to include store/ directory and clarify store architecture
- Updated GAME_BRIEFING.md Code Architecture section with store/ and legacy store info
- Updated skills.md with skill state management information
- Includes other refactoring changes (store hooks, component updates, etc.)
2026-05-04 09:49:13 +02:00

24 KiB
Executable File

Mana Loop - Project Architecture Guide

This document provides a comprehensive overview of the project architecture for AI agents working on this codebase.


🔑 Git Credentials (SAVE THESE)

Repository: git@gitea.tailf367e3.ts.net:Anexim/Mana-Loop.git

HTTPS URL with credentials:

https://zhipu:5LlnutmdsC2WirDwWgnZuRH7@gitea.tailf367e3.ts.net/Anexim/Mana-Loop.git

Credentials:

To configure git:

git config --global user.name "zhipu"
git config --global user.email "zhipu@local.local"

⚠️ MANDATORY GIT WORKFLOW - MUST BE FOLLOWED

Before starting ANY work, you MUST:

  1. Pull the latest changes:

    cd /home/user/repos/Mana-Loop && git pull origin master
    
  2. Do your task - Make all necessary code changes

  3. Before finishing, commit and push:

    cd /home/user/repos/Mana-Loop
    git add -A
    git commit -m "descriptive message about changes"
    git push origin master
    

This workflow is ENFORCED and NON-NEGOTIABLE. Every agent session must:

  • Start with git pull
  • End with git add, git commit, git push

Git Remote: git@gitea.tailf367e3.ts.net:Anexim/Mana-Loop.git


Project Overview

Mana Loop is an incremental/idle game built with:

  • Framework: Next.js 16 with App Router
  • Language: TypeScript 5
  • Styling: Tailwind CSS 4 with shadcn/ui components
  • State Management: Zustand with persist middleware (modular store architecture)
  • Database: Prisma ORM with SQLite (for persistence features)

Core Game Loop

  1. Mana Gathering: Click or auto-generate mana over time
  2. Studying: Spend mana to learn skills and spells
  3. Combat: Climb the Spire, defeat guardians, sign pacts
  4. Crafting: Enchant equipment with spell effects
  5. Prestige: Reset progress for permanent bonuses (Insight)

Directory Structure

src/
├── app/
│   ├── page.tsx          # Main game UI (~reduced via component extraction)
│   ├── layout.tsx        # Root layout with providers
│   ├── api/              # API routes (minimal use)
│   └── components/       # App-level components
│       ├── GameOverScreen.tsx
│       ├── LeftPanel.tsx
│       └── ...
├── components/
│   ├── ui/               # shadcn/ui components (auto-generated)
│   └── game/             # All game components (modular structure)
│       ├── index.ts       # Barrel exports
│       ├── GameContext.tsx
│       ├── ActionButtons.tsx
│       ├── CalendarDisplay.tsx
│       ├── CraftingProgress.tsx
│       ├── ManaDisplay.tsx
│       ├── TimeDisplay.tsx
│       ├── tabs/                # Tab-specific components
│       │   ├── index.ts
│       │   ├── AchievementsTab.tsx
│       │   ├── AttunementsTab.tsx
│       │   ├── CraftingTab.tsx
│       │   ├── DebugTab.tsx
│       │   ├── EquipmentTab.tsx
│       │   ├── GolemancyTab.tsx
│       │   ├── LabTab.tsx
│       │   ├── LootTab.tsx
│       │   ├── PrestigeTab.tsx
│       │   ├── SkillsTab.tsx
│       │   ├── SpellsTab.tsx
│       │   ├── SpireTab.tsx
│       │   ├── StatsTab.tsx
│       │   ├── EquipmentSlotGrid.tsx
│       │   ├── EquipmentControls.tsx
│       │   ├── EnchantmentsPanel.tsx
│       │   ├── EquipmentInventory.tsx
│       │   ├── SkillRow.tsx
│       │   ├── SkillCategoryHeader.tsx
│       │   ├── MilestoneProgress.tsx
│       │   ├── SkillMultipliers.tsx
│       │   ├── SpireHeader.tsx
│       │   ├── GuardianPanel.tsx
│       │   ├── RoomDisplay.tsx
│       │   ├── FloorControls.tsx
│       │   ├── CombatStatsPanel.tsx
│       │   └── ActivityLog.tsx
│       ├── crafting/           # Crafting-specific components
│       │   ├── index.tsx
│       │   ├── EnchantmentDesigner/
│       │   ├── EnchantmentApplier.tsx
│       │   ├── EnchantmentPreparer.tsx
│       │   └── EquipmentCrafter.tsx
│       ├── stats/              # Stats display components
│       │   ├── index.tsx
│       │   ├── CombatStatsSection.tsx
│       │   ├── ManaStatsSection.tsx
│       │   ├── ManaTypeBreakdown.tsx
│       │   ├── StudyStatsSection.tsx
│       │   └── UpgradeEffectsSection.tsx
│       ├── debug/              # Debug tools
│       │   ├── index.tsx
│       │   ├── SkillDebug.tsx
│       │   ├── ElementDebug.tsx
│       │   ├── AttunementDebug.tsx
│       │   ├── GolemDebug.tsx
│       │   ├── PactDebug.tsx
│       │   └── GameStateDebug.tsx
│       ├── shared/             # Shared sub-components
│       │   ├── MemorySlotPicker.tsx
│       │   ├── StudyProgress.tsx
│       │   └── UpgradeDialog.tsx
│       └── LootInventory/      # Loot display components
│           ├── index.tsx
│           ├── MaterialItem.tsx
│           ├── EssenceItem.tsx
│           ├── BlueprintsSection.tsx
│           ├── EquipmentItem.tsx
│           └── LootInventoryDisplay.tsx
└── lib/
    ├── game/
    │   ├── stores/                    # Modular Zustand stores (NEW)
    │   │   ├── index.ts              # Combined store exports
    │   │   ├── gameStore.ts          # Main store (~11KB, core state + tick)
    │   │   ├── manaStore.ts          # Mana state and actions (~9KB)
    │   │   ├── combatStore.ts        # Combat system (~9KB)
    │   │   ├── prestigeStore.ts      # Prestige/loop system (~8KB)
    │   │   ├── skillStore.ts         # Skill state and actions (~11KB)
    │   │   ├── uiStore.ts            # UI state (~2KB)
    │   │   ├── gameLoopActions.ts    # Game loop logic
    │   │   ├── gameActions.ts        # Generic game actions
    │   │   └── gameHooks.ts          # Store hooks
    │   ├── store/                    # Legacy store slices (migration in progress)
    │   │   ├── index.ts             # Re-exports from store.ts + computed utils
    │   │   ├── combatSlice.ts       # Combat state slice
    │   │   ├── manaSlice.ts         # Mana state slice
    │   │   ├── skillSlice.ts        # Skill state slice
    │   │   ├── craftingSlice.ts     # Crafting state slice
    │   │   └── computed.ts          # Computed stats
    │   ├── store-modules/             # Legacy store utilities
    │   ├── crafting-actions/          # Modular crafting system (NEW)
    │   │   ├── index.ts
    │   │   ├── application-actions.ts
    │   │   ├── design-actions.ts
    │   │   ├── preparation-actions.ts
    │   │   ├── equipment-actions.ts
    │   │   ├── crafting-equipment-actions.ts
    │   │   ├── disenchant-actions.ts
    │   │   └── computed-getters.ts
    │   ├── skill-evolution-modules/   # Modular skill evolution (NEW)
    │   │   ├── index.ts              # Main export (~11KB)
    │   │   ├── mana-well-flow.ts     # Mana Well/Flow skills (~15KB)
    │   │   ├── quick-learner.ts      # Quick Learner skill (~7KB)
    │   │   ├── focused-mind.ts       # Focused Mind skill (~6KB)
    │   │   ├── enchanting-skills.ts  # Enchanting skills (~15KB)
    │   │   ├── invocation-skills.ts  # Invocation skills (~15KB)
    │   │   ├── hybrid-skills.ts      # Hybrid skills (~22KB)
    │   │   ├── guardian-skills.ts    # Guardian-related skills (~4KB)
    │   │   ├── insight-harvest.ts    # Insight Harvest skill (~7KB)
    │   │   ├── mana-utility-skills.ts # Mana utility skills (~7KB)
    │   │   ├── elemental-attunement.ts # Elemental Attunement (~7KB)
    │   │   ├── knowledge-retention.ts  # Knowledge Retention (~4KB)
    │   │   ├── learning-skills.ts   # Learning skills (~1KB)
    │   │   ├── magic-skills.ts       # Magic skills (~1KB)
    │   │   ├── utils.ts             # Skill evolution utilities
    │   │   └── types.ts             # TypeScript interfaces
    │   ├── constants/                # Modular constants (NEW)
    │   │   ├── index.ts
    │   │   ├── core.ts              # Core game constants
    │   │   ├── elements.ts          # Element definitions
    │   │   ├── guardians.ts         # Guardian definitions
    │   │   ├── prestige.ts          # Prestige upgrade definitions
    │   │   ├── rooms.ts             # Room type definitions
    │   │   ├── skills.ts            # Skill definitions (~30KB)
    │   │   ├── spells.ts            # Spell definitions
    │   │   └── spells-modules/      # Spell sub-modules
    │   ├── data/                     # Game data definitions (NEW)
    │   │   ├── enchantment-effects.ts
    │   │   ├── enchantments/        # Enchantment definitions
    │   │   ├── equipment/           # Equipment definitions
    │   │   ├── golems/              # Golem definitions
    │   │   ├── achievements.ts
    │   │   ├── crafting-recipes.ts
    │   │   └── loot-drops.ts
    │   ├── crafting-slice.ts         # Legacy crafting (being modularized)
    │   ├── skill-evolution.ts        # Legacy skill evolution (reduced, ~1.5KB)
    │   ├── constants.ts              # Legacy constants (reduced, ~1KB)
    │   ├── store.ts                  # Legacy store (reduced, ~14KB)
    │   ├── computed-stats.ts         # Computed stats functions
    │   ├── navigation-slice.ts       # Floor navigation actions
    │   ├── study-slice.ts            # Study system actions
    │   ├── effects.ts                # Unified effect computation
    │   ├── upgrade-effects.ts        # Skill upgrade effect definitions
    │   ├── types.ts                  # TypeScript interfaces
    │   ├── formatting.ts             # Display formatters
    │   └── utils/                    # Utility functions
    └── utils.ts                      # General utilities (cn function)

Note: A complete, up-to-date project tree is automatically generated on each commit and saved to docs/project-structure.txt. This file is generated by the pre-commit hook using .husky/scripts/generate-project-tree.js and respects .gitignore rules.

Key Systems

1. State Management (Modular Store Architecture)

The game uses a modular Zustand store architecture with multiple specialized stores:

Store Modules (src/lib/game/stores/)

  • gameStore.ts: Core state, tick logic, and main actions (~11KB)
  • manaStore.ts: Mana gathering, elements, conversion (~9KB)
  • combatStore.ts: Combat system, spells, floor progression (~9KB)
  • prestigeStore.ts: Prestige/loop system, insight, upgrades (~8KB)
  • skillStore.ts: Skill state, studying, evolution (~11KB)
  • uiStore.ts: UI state, modals, debug settings (~2KB)

Legacy Store Files (Being Migrated)

  • store.ts: Reduced from ~2812 lines to ~14KB (core logic moved to stores/)
  • crafting-slice.ts: Reduced, being replaced by crafting-actions/

Store Interaction Pattern

// Each store can interact with other stores via get() and custom hooks
// Example from combatStore.ts:
import { useManaStore } from './manaStore';

// Access other store state
const manaState = useManaStore.getState();

2. Crafting System (Modular Architecture)

The crafting system has been split into focused action modules:

Crafting Action Modules (src/lib/game/crafting-actions/)

  • design-actions.ts: Enchantment design creation (~3KB)
  • preparation-actions.ts: Equipment preparation (~1KB)
  • application-actions.ts: Enchantment application (~2KB)
  • equipment-actions.ts: Equipment management (~2.5KB)
  • crafting-equipment-actions.ts: Equipment crafting (~2.5KB)
  • disenchant-actions.ts: Disenchanting logic (~1KB)
  • computed-getters.ts: Crafting computed values (~2KB)
  • index.ts: Barrel exports

3. Skill Evolution System (Modular Architecture)

The massive ~3400-line skill-evolution.ts has been split into focused modules:

Skill Evolution Modules (src/lib/game/skill-evolution-modules/)

  • index.ts: Main export combining all skill trees (~11KB)
  • mana-well-flow.ts: Mana Well and Mana Flow skills (~15KB)
  • quick-learner.ts: Quick Learner and related skills (~7KB)
  • focused-mind.ts: Focused Mind and study skills (~6KB)
  • enchanting-skills.ts: Enchanting skill tree (~15KB)
  • invocation-skills.ts: Invocation and Pact Mastery (~15KB)
  • hybrid-skills.ts: Cross-attunement hybrid skills (~22KB)
  • guardian-skills.ts: Guardian-related skills (~4KB)
  • insight-harvest.ts: Insight and prestige skills (~7KB)
  • mana-utility-skills.ts: Utility mana skills (~7KB)
  • elemental-attunement.ts: Elemental skills (~7KB)
  • knowledge-retention.ts: Knowledge retention skill (~4KB)
  • learning-skills.ts: Basic learning skills (~1KB)
  • magic-skills.ts: Magic-related skills (~1KB)
  • utils.ts: Shared utilities
  • types.ts: TypeScript interfaces

4. Constants System (Modular Architecture)

Game constants have been organized into domain-specific modules:

Constants Modules (src/lib/game/constants/)

  • core.ts: Core game constants (timing, limits)
  • elements.ts: Element definitions and hierarchies
  • guardians.ts: Guardian definitions and stats
  • prestige.ts: Prestige upgrade definitions
  • rooms.ts: Room type definitions
  • skills.ts: Complete skill definitions (~30KB)
  • spells.ts: Spell definitions
  • spells-modules/: Organized spell sub-modules
  • index.ts: Barrel exports

5. Game Data (New Structure)

Data Directory (src/lib/game/data/)

  • enchantment-effects.ts: Enchantment effect catalog
  • enchantments/: Enchantment definitions by category
  • equipment/: Equipment type definitions
  • golems/: Golem type definitions
  • achievements.ts: Achievement definitions
  • crafting-recipes.ts: Crafting recipe definitions
  • loot-drops.ts: Loot table definitions

Computed Stats (computed-stats.ts)

Extracted utility functions for stat calculations:

  • computeMaxMana(), computeRegen(), computeEffectiveRegen()
  • calcDamage(), calcInsight(), getElementalBonus()
  • getFloorMaxHP(), getFloorElement(), getMeditationBonus()
  • canAffordSpellCost(), deductSpellCost()
interface GameState {
  // Time
  day: number;
  hour: number;
  paused: boolean;
  
  // Mana (now in manaStore.ts)
  rawMana: number;
  elements: Record<string, ElementState>;
  
  // Combat (now in combatStore.ts)
  currentFloor: number;
  floorHP: number;
  activeSpell: string;
  castProgress: number;
  
  // Progression (now in skillStore.ts)
  skills: Record<string, number>;
  spells: Record<string, SpellState>;
  skillUpgrades: Record<string, string[]>;
  skillTiers: Record<string, number>;
  
  // Equipment
  equipmentInstances: Record<string, EquipmentInstance>;
  equippedInstances: Record<string, string | null>;
  enchantmentDesigns: EnchantmentDesign[];
  
  // Prestige (now in prestigeStore.ts)
  insight: number;
  prestigeUpgrades: Record<string, number>;
  signedPacts: number[];
}

Effect System (effects.ts)

CRITICAL: All stat modifications flow through the unified effect system.

// Effects come from two sources:
// 1. Skill Upgrades (milestone bonuses)
// 2. Equipment Enchantments (crafted bonuses)

getUnifiedEffects(state) => UnifiedEffects {
  maxManaBonus, maxManaMultiplier,
  regenBonus, regenMultiplier,
  clickManaBonus, clickManaMultiplier,
  baseDamageBonus, baseDamageMultiplier,
  attackSpeedMultiplier,
  critChanceBonus, critDamageMultiplier,
  studySpeedMultiplier,
  specials: Set<string>,  // Special effect IDs
}

When adding new stats:

  1. Add to ComputedEffects interface in upgrade-effects.ts
  2. Add mapping in computeEquipmentEffects() in effects.ts
  3. Apply in the relevant game logic (tick, damage calc, etc.)

Important Patterns

Adding a New Effect

  1. Define in enchantment-effects.ts (now in data/enchantment-effects.ts):
my_new_effect: {
  id: 'my_new_effect',
  name: 'Effect Name',
  description: '+10% something',
  category: 'combat',
  baseCapacityCost: 30,
  maxStacks: 3,
  allowedEquipmentCategories: ['caster', 'hands'],
  effect: { type: 'multiplier', stat: 'attackSpeed', value: 1.10 }
}
  1. Add stat mapping in effects.ts (if new stat):
// In computeEquipmentEffects()
if (effect.stat === 'myNewStat') {
  bonuses.myNewStat = (bonuses.myNewStat || 0) + effect.value;
}
  1. Apply in game logic:
const effects = getUnifiedEffects(state);
damage *= effects.myNewStatMultiplier;

Adding a New Skill

  1. Define in constants/skills.ts (NEW location)
  2. Add evolution path in skill-evolution-modules/ (NEW location)
    • Create new module or add to existing module
  3. Export from skill-evolution-modules/index.ts
  4. Update UI in components/game/tabs/SkillsTab.tsx

Adding a New Spell

  1. Define in constants/spells.ts (NEW location)
  2. Add to constants/spells-modules/ if categorized
  3. Add spell enchantment in data/enchantment-effects.ts
  4. Add research skill in constants/skills.ts
  5. Map research to effect in EFFECT_RESEARCH_MAPPING

Git Hooks (Husky)

This project uses Husky to manage git hooks for automated checks and agent assistance:

Pre-Commit Hook (.husky/pre-commit)

Runs automatically before each commit:

  1. File Size Check: Ensures no staged file exceeds 400 lines (improves AI agent readability)
  2. Project Structure Generation: Updates docs/project-structure.txt with current tree (respects .gitignore)

Post-Merge Hook (.husky/post-merge)

Runs after merging branches:

  • Checks if package.json or package-lock.json changed
  • Automatically runs npm install to sync dependencies

Implementation Files

  • Hook scripts: .husky/ directory
  • File size check: .husky/scripts/check-file-size.js
  • Tree generator: .husky/scripts/generate-project-tree.js

Common Pitfalls

  1. Forgetting to call getUnifiedEffects(): Always use unified effects for stat calculations
  2. Direct stat modification: Never modify stats directly; use effect system
  3. Missing tier multiplier: Use getTierMultiplier(skillId) for tiered skills
  4. Ignoring special effects: Check hasSpecial(effects, SPECIAL_EFFECTS.X) for special abilities
  5. Not updating modular stores: Check all stores in stores/ directory for related state
  6. Bypassing crafting-actions: Use the modular actions in crafting-actions/ for new crafting features

Testing Guidelines

  • Run npm run lint after changes
  • Run npm run test to execute unit tests
  • Check dev server logs
  • Test with fresh game state (clear localStorage)
  • New: Tests are organized alongside their modules (e.g., stores/__tests__/, store-tests/)

Modular Architecture Pattern

The codebase has been refactored from large monolithic files into focused, modular components. This improves:

  • Maintainability: Each module has a single responsibility
  • Readability: Files are under 400 lines (pre-commit hook enforces this)
  • AI Agent Efficiency: Smaller files are easier to understand and modify

Key Modular Directories

Directory Purpose Line Count Target
stores/ Zustand store modules < 400 lines each
crafting-actions/ Crafting system actions < 400 lines each
skill-evolution-modules/ Skill trees by category < 400 lines each
constants/ Game constants by domain < 400 lines each
data/ Game data definitions < 400 lines each
components/game/tabs/ UI tab components < 400 lines each
components/game/crafting/ Crafting UI components < 400 lines each
components/game/stats/ Stats display components < 400 lines each

Creating a New Module

  1. Identify the domain: Which system does it belong to?
  2. Create focused file: Keep under 400 lines
  3. Export from index: Add to barrel export file
  4. Update imports: Fix all references to old location
  5. Test: Run lint and tests before committing

File Size Guidelines

Current File Sizes (After Modular Refactoring)

File Lines Size (bytes) Notes
stores/gameStore.ts ~300 ~11KB Core state + tick logic
stores/manaStore.ts ~250 ~9KB Mana system
stores/combatStore.ts ~250 ~9KB Combat system
stores/prestigeStore.ts ~200 ~8KB Prestige system
stores/skillStore.ts ~300 ~11KB Skill system
stores/uiStore.ts ~50 ~2KB UI state
crafting-actions/*.ts ~50-150 ~1-3KB each Modular crafting
skill-evolution-modules/*.ts ~100-600 ~4-22KB each Modular skills
constants/*.ts ~50-1000 ~1-30KB each Modular constants
page.tsx ~100 ~4KB Main UI (heavily reduced)
components/game/tabs/*.tsx ~50-400 ~2-15KB each Tab components

Guidelines

  • 400 lines maximum per file (enforced by pre-commit hook)
  • Extract to modules when approaching 300 lines
  • Use barrel exports (index.ts) for clean imports
  • Keep related functionality together in modules
  • Modular architecture is now the standard - all new code should follow this pattern

Automated File Size Check

A pre-commit hook automatically checks all staged files. Files exceeding 400 lines will be rejected. The hook runs via Husky and uses .husky/scripts/check-file-size.js. If your file is too large, refactor it into smaller modules before committing.


🚫 BANNED CONTENT - NEVER ADD THESE

Lifesteal and Healing are BANNED

DO NOT add lifesteal or healing mechanics to player abilities.

This includes:

  • lifesteal spell effects
  • heal or regeneration abilities for the player
  • Any mechanic that restores player HP or mana based on damage dealt
  • Life-stealing weapons or enchantments

Rationale: The game's core design is that the player cannot take damage - only floors can. Healing/lifesteal mechanics are unnecessary and would create confusing gameplay.

Banned Mana Types

The following mana types have been removed and should never be re-added:

  • life - Healing/lifesteal themed (banned)
  • blood - Life + Water compound (banned due to lifesteal theme)
  • wood - Life + Earth compound (banned due to life connection)
  • mental - Mind/psionic themed (removed for design consistency)
  • force - Telekinetic themed (removed for design consistency)

🔮 Mana Types Overview

Base Mana Types (7)

Element Symbol Color Theme
Fire 🔥 #FF6B35 Destruction, burn damage
Water 💧 #4ECDC4 Flow, freeze effects
Air 🌬️ #00D4FF Speed, wind damage
Earth ⛰️ #F4A261 Stability, armor pierce
Light ☀️ #FFD700 Radiance, holy damage
Dark 🌑 #9B59B6 Shadows, void damage
Death 💀 #778CA3 Decay, rot damage

Utility Mana Types (1)

Element Symbol Color Theme
Transference 🔗 #1ABC9C Mana transfer, Enchanter attunement

Compound Mana Types (3)

Element Recipe Theme
Metal Fire + Earth Armor piercing, forged weapons
Sand Earth + Water AOE damage, desert winds
Lightning Fire + Air Fast damage, armor pierce, chain effects

Exotic Mana Types (3)

Element Recipe Theme
Crystal Sand + Sand + Light Prismatic, high damage
Stellar Fire + Fire + Light Cosmic, ultimate fire/light
Void Dark + Dark + Death Oblivion, ultimate dark/death

Mana Type Hierarchy

Base Elements (7) → Compound (3) → Exotic (3)
                      ↓
              Utility (1) ← Special attunement-based