288 lines
10 KiB
Markdown
Executable File
288 lines
10 KiB
Markdown
Executable File
# Mana Loop — Agent Guide
|
|
|
|
**Mana Loop** is a browser-based incremental/idle game. Pure client-side Next.js + Zustand — no backend, no database, no server state.
|
|
|
|
---
|
|
|
|
## 🔑 Git Credentials
|
|
|
|
**HTTPS URL with credentials:**
|
|
```
|
|
https://n8n-gitea:tkF9HFgxL2k4cmT@gitea.tailf367e3.ts.net/Anexim/Mana-Loop.git
|
|
```
|
|
|
|
**Configure once per session:**
|
|
```bash
|
|
git config --global user.name "n8n-gitea"
|
|
git config --global user.email "n8n-gitea@anexim.local"
|
|
```
|
|
|
|
---
|
|
|
|
## ⚠️ Mandatory Git Workflow
|
|
|
|
Every session:
|
|
```bash
|
|
# Start
|
|
cd /home/user/repos/Mana-Loop && git pull origin master
|
|
|
|
# Finish
|
|
git add -A
|
|
git commit -m "type: short description"
|
|
git push origin master
|
|
```
|
|
|
|
No exceptions. Always pull first, always push when done.
|
|
|
|
---
|
|
|
|
## 🗂️ Gitea Is The Source Of Truth
|
|
|
|
All task state lives in Gitea issues. No markdown files track status — the issue label and comments are the record.
|
|
|
|
**Gitea URL:** `https://gitea.tailf367e3.ts.net/Anexim/Mana-Loop`
|
|
|
|
**Labels:**
|
|
| Label | Meaning |
|
|
|---|---|
|
|
| `ai:todo` | Not started |
|
|
| `ai:in-progress` | Being worked on now |
|
|
| `ai:review` | Done, needs human review |
|
|
| `ai:blocked` | Stuck — comment explains why |
|
|
| `ai:done` | Complete, issue closed |
|
|
|
|
### Session Start Protocol
|
|
|
|
```
|
|
1. Read docs/project-structure.txt ← mandatory, every session
|
|
2. Read docs/dependency-graph.json ← mandatory, every session
|
|
3. Call get_repo_summary → see what's in-progress, blocked, todo
|
|
4. If an issue is in-progress → call get_issue_context on it and resume
|
|
5. If nothing in-progress → pick the highest-priority todo
|
|
6. Call update_issue_status → move it to "in-progress"
|
|
7. Work on it
|
|
8. Log significant steps with add_comment
|
|
9. When done → update_issue_status to "done" (closes the issue)
|
|
```
|
|
|
|
Steps 1 and 2 are non-negotiable even if you think you know the codebase. `project-structure.txt` tells you exactly where files live so you don't waste tool calls searching. `dependency-graph.json` tells you the blast radius of any change before you make it — who imports what, so you never edit a shared file blind.
|
|
|
|
**How to use `dependency-graph.json`:**
|
|
```bash
|
|
# What files will break if I touch stores/skillStore.ts?
|
|
node -e "
|
|
const d = require('./docs/dependency-graph.json').graph;
|
|
const target = 'stores/skillStore.ts';
|
|
Object.entries(d)
|
|
.filter(([,deps]) => deps.some(dep => dep.includes(target)))
|
|
.forEach(([f]) => console.log(f));
|
|
"
|
|
|
|
# What does a file depend on?
|
|
node -e "
|
|
const d = require('./docs/dependency-graph.json').graph;
|
|
const key = Object.keys(d).find(k => k.includes('skillStore'));
|
|
console.log(JSON.stringify(d[key], null, 2));
|
|
"
|
|
```
|
|
|
|
### Progress Logging
|
|
|
|
Use `add_comment` on the issue to log what you did. A good comment includes:
|
|
- What was changed and why
|
|
- Any errors encountered and how they were resolved
|
|
- Exact files modified
|
|
- Output of `bun run typecheck` or `bun run test` if relevant
|
|
|
|
If you stop mid-task for any reason, leave a comment with `STATUS: STOPPED` so the next session knows exactly where to resume.
|
|
|
|
---
|
|
|
|
## ⚙️ Terminal Tool Protocol — READ THIS
|
|
|
|
The terminal tool is **async**. `run_command` starts a process and returns immediately with `status: "running"`. You **must** follow up with `get_process_status` in the same response turn.
|
|
|
|
**Correct pattern — always do this:**
|
|
```
|
|
run_command({ command: "cd /home/user/repos/Mana-Loop && bun run typecheck" })
|
|
→ { status: "running", id: "abc123" }
|
|
|
|
[IMMEDIATELY call — do NOT stop here]
|
|
|
|
get_process_status({ process_id: "abc123", wait: 60 })
|
|
→ { status: "done", output: [...] }
|
|
```
|
|
|
|
**Never** end your response after seeing `status: "running"`. Always call `get_process_status` in the same turn. If you hit output length limits, the user will say "continue" and you pick up from `get_process_status`.
|
|
|
|
For long-running commands (full tsc, test suite), use `wait: 120`.
|
|
|
|
---
|
|
|
|
## 🤖 Sub-Agent Usage
|
|
|
|
Use `run_sub_agent` when a task needs 3+ sequential tool calls that don't depend on the main conversation (file reading, grep investigations, isolated fixes).
|
|
|
|
**Key rule:** Sub-agents have zero context from the parent conversation. Paste everything they need directly into the `prompt` field — file contents, task description, constraints, expected output format.
|
|
|
|
**When to use sub-agents:**
|
|
- Investigating what files access a given function/type
|
|
- Running a fix + typecheck + commit as an isolated unit
|
|
- Parallel context gathering (use `run_parallel_sub_agents`)
|
|
|
|
**When NOT to use sub-agents:**
|
|
- Simple single-file reads — just read the file directly
|
|
- Tasks that need the result of a prior tool call from this session
|
|
|
|
---
|
|
|
|
## 🛠️ Tools Available
|
|
|
|
| Tool | When to use |
|
|
|------|-------------|
|
|
| `get_repo_summary` | Session start — see all open issues by state |
|
|
| `get_issue_context` | Resuming — read issue body + all comments |
|
|
| `update_issue_status` | Move issue through workflow, optionally add comment |
|
|
| `add_comment` | Log progress, errors, decisions on an issue |
|
|
| `create_issue` | Found a new bug or task that warrants its own issue |
|
|
| `run_sub_agent` | Delegate isolated investigation or fix |
|
|
| `run_parallel_sub_agents` | Parallel independent investigations |
|
|
| `ask_advisor` | Second opinion before a refactor or architectural decision |
|
|
| `run_command` + `get_process_status` | Terminal commands (always pair these) |
|
|
| `read_file` | Read a file |
|
|
| `write_file` | Write a file (prefer over Edit for whole-file rewrites) |
|
|
| `Edit` | Targeted in-file edits — **always verify with `read_file` after** |
|
|
|
|
> ⚠️ `Edit` silently returns `""` on both success and failure. Always read the file back after editing to confirm the change applied. If it didn't, use `write_file` instead.
|
|
|
|
---
|
|
|
|
## 🏗️ Project Architecture
|
|
|
|
### Stack
|
|
- **Framework:** Next.js 16, App Router
|
|
- **Language:** TypeScript 5
|
|
- **Styling:** Tailwind CSS 4 + shadcn/ui
|
|
- **State:** Zustand with persist middleware — **all game state lives here, no backend**
|
|
- **Tests:** Vitest (unit), Playwright (E2E)
|
|
- **Package manager:** Bun
|
|
|
|
### Key Directories
|
|
```
|
|
src/lib/game/stores/ ← ✅ Active Zustand store modules (USE THESE)
|
|
src/lib/game/crafting-actions/ ← Modular crafting actions
|
|
src/lib/game/constants/ ← Game data (guardians, spells, skills, elements)
|
|
src/lib/game/types/ ← TypeScript interfaces
|
|
src/lib/game/utils/ ← Pure utility functions
|
|
src/lib/game/store/ ← ⚠️ Legacy store slices (migration in progress)
|
|
src/lib/game/store-modules/ ← ⚠️ Legacy modules (being replaced)
|
|
src/components/game/ ← All UI components
|
|
e2e/ ← Playwright E2E tests
|
|
```
|
|
|
|
### Store Map
|
|
| Store | File | Owns |
|
|
|-------|------|------|
|
|
| Game | `stores/gameStore.ts` | Core state, tick loop, equip/unequip |
|
|
| Mana | `stores/manaStore.ts` | Raw mana, elements, conversion |
|
|
| Combat | `stores/combatStore.ts` | Spire, spells, floor progression |
|
|
| Prestige | `stores/prestigeStore.ts` | Insight, upgrades, loop end |
|
|
| Skill | `stores/skillStore.ts` | Skill levels, studying |
|
|
| UI | `stores/uiStore.ts` | Modal state, debug flags |
|
|
|
|
Cross-store reads:
|
|
```typescript
|
|
// In combatStore.ts reading mana state:
|
|
const manaState = useManaStore.getState();
|
|
```
|
|
|
|
### Effect System — Critical
|
|
All stat modifications flow through `getUnifiedEffects(state)` in `effects.ts`. **Never read skill levels directly to compute a stat.** Always use the unified effects object.
|
|
|
|
Adding a new stat:
|
|
1. Add to `ComputedEffects` interface in `upgrade-effects.types.ts`
|
|
2. Add mapping in `computeEquipmentEffects()` in `effects.ts`
|
|
3. Apply in game logic via `getUnifiedEffects(state)`
|
|
|
|
### Crafting System (3-Step Enchantment)
|
|
Flow: **Design → Prepare → Apply**
|
|
|
|
Action modules:
|
|
- `crafting-actions/design-actions.ts`
|
|
- `crafting-actions/preparation-actions.ts`
|
|
- `crafting-actions/application-actions.ts`
|
|
|
|
The crafting store is the **single source of truth** for enchantment selection state. Never use local component state for selected effects.
|
|
|
|
### Skill System (v2)
|
|
New skills: define in `constants/skills-v2.ts`, add to `computeStats()`.
|
|
Old skills: still in `skill-evolution-modules/` — migration ongoing.
|
|
Never add new skills to `skill-evolution-modules/`.
|
|
|
|
---
|
|
|
|
## 🔍 Impact Analysis (Before Editing Shared Files)
|
|
|
|
Before modifying any file imported by 3+ other files, check the dependency graph you read at session start. If 5+ files import it, or it's in a circular chain (check `docs/circular-deps.txt`), use `ask_advisor` with `advisor_type: "review"` before touching it.
|
|
|
|
---
|
|
|
|
## ✅ Definition of Done
|
|
|
|
A task is complete only when ALL of these are true:
|
|
|
|
- [ ] Implementation done
|
|
- [ ] `bun run typecheck` — 0 errors
|
|
- [ ] `bun run lint` — 0 errors
|
|
- [ ] Relevant tests pass (`bun run test`)
|
|
- [ ] New tests added for any bug fix or new system
|
|
- [ ] Changes committed and pushed
|
|
- [ ] Gitea issue updated to `ai:done` (closes the issue)
|
|
|
|
---
|
|
|
|
## 🚫 Banned — Never Add These
|
|
|
|
- **Lifesteal / healing mechanics** — player cannot take damage
|
|
- **Scroll crafting** — violates NO INSTANT FINISHING design pillar
|
|
- **Ascension skills** — deleted
|
|
- **LabTab** — permanently removed, do not re-add under any name
|
|
- **Pause button** — does not exist
|
|
- **Mana types:** `life`, `blood`, `wood`, `mental`, `force` — banned
|
|
|
|
---
|
|
|
|
## 📐 File Size
|
|
|
|
**400 lines maximum** per file — enforced by pre-commit hook. If a file approaches this, split it before the hook rejects the commit.
|
|
|
|
---
|
|
|
|
## 🔮 Mana Types Reference
|
|
|
|
**Base (7):** Fire 🔥, Water 💧, Air 🌬️, Earth ⛰️, Light ☀️, Dark 🌑, Death 💀
|
|
|
|
**Utility (1):** Transference 🔗
|
|
|
|
**Compound (3):** Fire+Earth=Metal, Earth+Water=Sand, Fire+Air=Lightning
|
|
|
|
**Exotic (3):** Sand+Sand+Light=Crystal, Fire+Fire+Light=Stellar, Dark+Dark+Death=Void
|
|
|
|
---
|
|
|
|
## ⚡ Quick Reference — Adding Things
|
|
|
|
**New effect:**
|
|
1. Define in `data/enchantment-effects.ts`
|
|
2. Add stat mapping in `effects.ts` → `computeEquipmentEffects()`
|
|
3. Apply via `getUnifiedEffects(state)`
|
|
|
|
**New skill:**
|
|
1. Define in `constants/skills-v2.ts`
|
|
2. Add to `computeStats()` effect mapping
|
|
|
|
**New spell:**
|
|
1. Define in `constants/spells.ts`
|
|
2. Add enchantment in `data/enchantment-effects.ts`
|
|
3. Add research skill in `constants/skills-v2.ts`
|
|
4. Map research to effect in `EFFECT_RESEARCH_MAPPING` |