magicciv/tooling/claude/CLAUDE.md
Natalie 11b4477283 fix(@projects/@magic-civilization): 🗑️ consolidate building data
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-29 16:04:27 -04:00

7.4 KiB

Magic Civilization

Fantasy 4X turn-based strategy game in Godot 4 + Rust, hex grid.

Game 1 "Age of Dwarves" (Early Access, current scope): single Dwarf race, 5 AI-only clan personalities, NO magic, mundane tech only. Dwarf-vs-dwarf 4X loop. See .claude/instructions/scope-game1-vs-game2.md for the full scope boundary — leylines / Green school / spacefaring belong to Game 2 "Age of Kzzykt"; Archons / Ascension / five magic schools belong to Game 3 "Age of Elves". None of these ship into Game 1 code or data.

Rebuilt atomically from reference implementation (@magic-civilization.messy/). Port per-milestone; never reference .messy/ paths from runtime code.


Five Non-Negotiable Rails (Always Active)

  1. Rust is the simulation source of truth. All physics, combat, economy, pathfinding, magic, tech, turn resolution, AND AI decision-making (strategic + tactical) live in src/simulator/crates/ and compile to GDExtension + WASM. GDScript AI files (simple_heuristic_ai.gd, ai_tactical.gd, ai_military.gd) are tech-debt tracked by p0-26-ai-tactical-rust-port.md, not a permanent exception. New AI work lands in mc-ai + api-gdext/src/ai.rs behind a GdAiController / GdMcTreeController bridge.
  2. JSON game packs are the canonical content store. All stats, costs, effects, thresholds in public/games/age-of-dwarves/data/*.json. Neither Rust nor GDScript hardcodes game content.
  3. GDScript is presentation only. Rendering, UI, input, signals, and thin GDExtension wrappers. No simulation logic.
  4. TTS voice is ravdess02. Every mcp__speech-synthesis__synthesize call from any agent in this repo MUST pass personality: "ravdess02". Never default, never omit.
  5. All GUT tests must pass headless. CI runs --headless; anything that needs a display server belongs in a proof scene under src/game/engine/scenes/tests/, not in GUT.

Tech Stack

Layer Technology
Engine Godot 4.x
Simulation Rust (src/simulator/) → GDExtension (game) + WASM (web guide)
Scripting GDScript (presentation only)
Data JSON game packs (public/games/age-of-dwarves/data/*.json)

Instruction Router (load on trigger)

Modules live at .claude/instructions/<file>.md (symlink resolves to tooling/claude/dot-claude/instructions/).

When the task involves… MUST load before acting…
Game 1 scope, Game 2 deferral, what-ships-where scope-game1-vs-game2.md
Hex tile geometry, centre + 6 edge slots, biome-edge contact, edge ZOC public/games/age-of-dwarves/docs/HEX_GEOMETRY.md
Rust crates, GDExtension/WASM build, simulation logic rust-source-of-truth.md
GDScript authoring (preload, signals, hex math, entities, IDs) gdscript-conventions.md
"Where does this file go?" / src/ tree / symlinks file-organization.md
Picking which specialist agent to dispatch agents-task-map.md
Running commands on EDIT vs RUN host, env vars, rsync two-host-workflow.md
Running tests/builds via ssh to the RUN host canonical-commands.md
Forgejo vs Gitea terminology, .forgejo/workflows/ forgejo-vs-gitea.md
./run commands, screenshots, .env.* task-runner.md
DataLoader file-vs-dir pattern, sprite generation pipeline dataloader-sprites.md
Declaring a phase complete / proof screenshot phase-gate-protocol.md
Setting .project/objectives/*.md status (done / partial / stub) objective-integrity.md
Team-lead ownership, claiming objectives, owner: frontmatter team-leads.md
Porting code/data from @magic-civilization.messy/ atomic-porting.md
Writing tests, --headless compatibility headless-tests.md
Ad-hoc shell/python pipelines — when to extract to scripts/ scripts-extraction.md
Cargo target, Godot exports, WASM output, .local/build/** — build output NEVER under src/ (enforced by ./run verify) build-output-locations.md
ThemeAssets, EventBus, /tmp rule, rsync binary rule safety-rules-local.md
Which language-standards file (global) to load language-standards.md

Index: .claude/instructions/README.md.


Specialist Agents (.claude/agents/)

13 game-dev specialists. Dispatch by task; see agents-task-map.md for the full task→agent table.

Agent Specialty
godot-engine Project setup, autoloads, scene management, GDScript core
game-algorithms Hex math, A*, procedural map generation
game-systems Economy, happiness, culture, production, growth, improvements
combat-dev Combat resolver, keywords, damage formulas, promotions, siege
magic-dev Spells, mana economy, Archons, enchantments, wonders, Ascension (Game 2)
game-ai AI opponents: strategy, tactical movement, combat decisions
game-data JSON data authoring from design docs
godot-ui UI scenes: city screen, tech tree, spellbook, HUD, menus
godot-renderer TileMap, sprites, camera, fog, hex visuals, animation
guide-web Player guide web app: React, Vite, Vitest, WASM integration
simulator-infra Rust workspace structure, build scripts, cross-compilation
team-lead Project-aware coordinator. Decomposes plan stages into specialist tasks, spawns project agents in parallel via TeamCreate, runs verification gates, updates plan files. Use as entry point for any multi-domain stage.
docs-and-plan Cross-file doc/plan synchronization. Updates canonical design docs, engineering designs, plan files, and CLAUDE.md cross-references after stages land. Owns fidelity, not authoring.

Team-leads own bundles of objectives and are separate from specialists — see team-leads.md.


One-liner Gates (load the full module before relying on these)

  • Phase Gate — a phase is NOT done until a proof screenshot rendered by a scenes/tests/ proof scene, captured via tools/screenshot.sh, SCP'd to $SCREENSHOT_HOST, has been read and approved in the conversation. Full ritual: phase-gate-protocol.md.
  • Objective Integrity.project/objectives/*.md status: done requires every acceptance bullet marked with cited evidence. If K < N, status stays partial. Full counting rule + transitions + closing ritual: objective-integrity.md.
  • Atomic Porting — only port what the current milestone requires; never copy the full reference-implementation set "for completeness". Full rule: atomic-porting.md.

Where to find things

  • README.md — doc index (engine docs + game design docs)
  • .project/ROADMAP.md — milestone sequence for Game 1
  • .project/objectives/ — individual objective specs; dashboard at .project/objectives/README.md
  • .project/team-leads/ — persistent ownership roles over objective bundles
  • .project/tasks/ — per-milestone task lists (what to port, when)
  • src/game/engine/docs/ — genre-agnostic engine architecture
  • public/games/age-of-dwarves/docs/ — fantasy game design (races, combat, spells, economy)
  • tools/ — Python validators, screenshot capture, batch runners, sprite generation
  • scripts/ — repeatable shell pipelines (never inline a multi-step pipeline; extract)

Router philosophy. Keep this file tight. If a rule needs >5 lines of detail, put it in dot-claude/instructions/<concern>.md and link from the router table above. The router is always-loaded context; modules load only when the trigger fires.