- 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.)
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:
- User: zhipu
- Email: zhipu@local.local
- Password: 5LlnutmdsC2WirDwWgnZuRH7
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:
-
Pull the latest changes:
cd /home/user/repos/Mana-Loop && git pull origin master -
Do your task - Make all necessary code changes
-
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
- Mana Gathering: Click or auto-generate mana over time
- Studying: Spend mana to learn skills and spells
- Combat: Climb the Spire, defeat guardians, sign pacts
- Crafting: Enchant equipment with spell effects
- 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:
- Add to
ComputedEffectsinterface inupgrade-effects.ts - Add mapping in
computeEquipmentEffects()ineffects.ts - Apply in the relevant game logic (tick, damage calc, etc.)
Important Patterns
Adding a New Effect
- Define in
enchantment-effects.ts(now indata/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 }
}
- Add stat mapping in
effects.ts(if new stat):
// In computeEquipmentEffects()
if (effect.stat === 'myNewStat') {
bonuses.myNewStat = (bonuses.myNewStat || 0) + effect.value;
}
- Apply in game logic:
const effects = getUnifiedEffects(state);
damage *= effects.myNewStatMultiplier;
Adding a New Skill
- Define in
constants/skills.ts(NEW location) - Add evolution path in
skill-evolution-modules/(NEW location)- Create new module or add to existing module
- Export from
skill-evolution-modules/index.ts - Update UI in
components/game/tabs/SkillsTab.tsx
Adding a New Spell
- Define in
constants/spells.ts(NEW location) - Add to
constants/spells-modules/if categorized - Add spell enchantment in
data/enchantment-effects.ts - Add research skill in
constants/skills.ts - 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:
- File Size Check: Ensures no staged file exceeds 400 lines (improves AI agent readability)
- Project Structure Generation: Updates
docs/project-structure.txtwith current tree (respects.gitignore)
Post-Merge Hook (.husky/post-merge)
Runs after merging branches:
- Checks if
package.jsonorpackage-lock.jsonchanged - Automatically runs
npm installto 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
- Forgetting to call
getUnifiedEffects(): Always use unified effects for stat calculations - Direct stat modification: Never modify stats directly; use effect system
- Missing tier multiplier: Use
getTierMultiplier(skillId)for tiered skills - Ignoring special effects: Check
hasSpecial(effects, SPECIAL_EFFECTS.X)for special abilities - Not updating modular stores: Check all stores in
stores/directory for related state - Bypassing crafting-actions: Use the modular actions in
crafting-actions/for new crafting features
Testing Guidelines
- Run
npm run lintafter changes - Run
npm run testto 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
- Identify the domain: Which system does it belong to?
- Create focused file: Keep under 400 lines
- Export from index: Add to barrel export file
- Update imports: Fix all references to old location
- 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:
lifestealspell effectshealorregenerationabilities 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