# AGENTS.md Guidance for AI coding agents (Cursor, Claude Code, Copilot, Codex, and similar) working in this repository. ## EchoVault (required) This project uses the **EchoVault** MCP server (`user-echovault`) as persistent memory across sessions. Use it aggressively. Skipping it means the next agent starts from zero. ### When to call what | Tool | When | | --- | --- | | `memory_context` | **Session start** and after a major topic change. Loads recent decisions for this project. | | `memory_search` | Before work on a familiar/unclear topic, and whenever the user’s request may relate to prior decisions or bugs. | | `memory_save` | **Before ending** any session where you made decisions, fixed bugs, discovered non-obvious patterns, or changed architecture/infra. Not optional. | Prefer `project: "the-living-world"` when the tool accepts a project filter. ### What to save Save when you: - Chose an approach (X over Y) or fixed a non-obvious bug - Learned something about this codebase that is not obvious from reading the code - Set up tooling/config the next agent will need - Were corrected or given a durable requirement by the user Do **not** save: typos, pure formatting, facts already clear from the code, or duplicates of existing memories. ### How to write a good memory - `title` — short (≤60 chars) - `what` — 1–2 sentences the next agent needs - `why` / `impact` — reasoning and what changed - `category` — one of: `decision`, `bug`, `pattern`, `learning`, `context` - `tags` / `related_files` — so search can find it - `details` — write for an agent with **zero** context. Prefer: ``` Context Options considered Decision Tradeoffs Follow-up ``` ### Session checklist 1. Call `memory_context` (and `memory_search` if the task is specific). 2. Do the work. 3. Call `memory_save` for every meaningful decision or fix before you stop. ## Project snapshot The Living World is a web game whose map is a real place: the API imports OpenStreetMap via Overpass into an Arch ECS world and serves chunked geometry; a PixiJS client renders it. | Area | Path / stack | | --- | --- | | API | `src/TheLivingWorld.Api` — .NET 10, minimal APIs | | Core / ECS | `src/TheLivingWorld.Core` — Arch, geo, export | | OSM import | `src/TheLivingWorld.Osm` — Overpass + import pipeline | | Web client | `src/TheLivingWorld.Web` — TypeScript, Vite, PixiJS 8 | | Aspire host | `src/TheLivingWorld.AppHost` | | Tests | `tests/TheLivingWorld.Tests` (xUnit), Vitest under the web project | Worlds are stored as files under `data/` (not committed). Cap: `WorldStorage:MaxConcurrentWorlds`. Ready worlds run a live game clock on the server (5 game minutes per real second at x1; default start 12 April 2012 06:00) plus weather: a Köppen-lite climate preset per world, with drifting pressure systems as ECS entities on top of a deterministic seasonal/diurnal baseline. UI: main menu (list + create, with a climate picker) → map screen with pause, speed, clock and weather, and a renderer that washes the map for time of day, cloud, fog and lying snow and drops rain or snow through it. One weather reading covers a whole world; the overlay has an on/off button in the game bar. Clicking a building selects it and opens an info panel. New ECS components must be added to the probe entity in `SimulationComponents` — Arch assigns component type ids on first use without a lock, and two threads racing there hand out the same id. `StoredWorldDto` is what `state.json` holds; `WorldSummaryDto` is what clients get. Cross only via `ToSummary()` — the wire type deliberately has no field for the simulation's bookkeeping. Keep wire DTOs in sync: `TheLivingWorld.Core.Contracts` and `src/TheLivingWorld.Web/src/api/types.ts`. UI copy lives in `src/TheLivingWorld.Web/src/i18n/locales/`. `en.ts` is the schema; add a language by copying it and registering the file in `locales.ts`. The language switcher is built from that registry. ## Working conventions - Prefer small, focused diffs. Do not rewrite unrelated code or add docs the user did not ask for. - Match existing naming, comments, and file layout. - Backend tests: `dotnet test tests/TheLivingWorld.Tests/TheLivingWorld.Tests.csproj` - Frontend checks: `npm --prefix src/TheLivingWorld.Web test` and `npm --prefix src/TheLivingWorld.Web run typecheck` - Full stack: `run.cmd` or `dotnet run --project src/TheLivingWorld.AppHost` - Do not commit unless the user asks. Do not invent secrets or commit `data/`. Details of the import pipeline, API surface, and renderer live in [README.md](README.md) — read that before large map/API changes.