# One-Time Project Setup Task — DOTS + Netcode + Memory Stack **This is the separate setup task referenced by the `/dots-dev` skill.** Run it ONCE per project (some steps once per machine — see §0). It installs the DOTS stack, scaffolds the project + vault, wires the memory MCPs, and writes `CLAUDE.md`. After this completes, `/dots-dev` drives feature work; this file is no longer needed (keep it for reference / the second machine). > **How to run:** open a normal Claude Code session in this project (NOT a worktree — the open Unity Editor + UnityMCP target the live working copy) and say *"Run the DOTS setup task in Docs/dots-setup-task.md."* Work top to bottom; each step has a verification. > **Conventions reference:** the ECS rules and context7 library IDs live in the skill at > `~/.claude/skills/dots-dev/references/dots-conventions.md` and `…/context7-libraries.md` > (Windows: `%USERPROFILE%\.claude\skills\dots-dev\references\`). Use context7 for any current API shape — do not trust memory for DOTS APIs. > **Cross-platform rule:** never write a machine-specific absolute path (`/Users/...`, `C:\...`) into any committed file. Use `${CLAUDE_PROJECT_DIR}` and repo-relative paths. The vault lives in-repo so it travels via git. --- ## §0 — Per-machine prerequisites (do on EACH machine, once) - [ ] Install **uv / uvx** (for the `basic-memory` and `serena` MCP servers). macOS: `brew install uv` or the official installer; Windows: the official installer / `winget install astral-sh.uv`. - [ ] Install the **Obsidian** app and the **obsidian-cli** (the `obsidian-cli` skill drives it). Point Obsidian at `/Docs/Vault` once it exists (§5). - [ ] Copy/sync the **`dots-dev` skill** to this machine's user skills dir (`~/.claude/skills/dots-dev/` on macOS, `%USERPROFILE%\.claude\skills\dots-dev\` on Windows). It is path-agnostic — same files on both. - [ ] Confirm Unity 6.4 opens the project and the **CoplayDev Unity-MCP** bridge connects (`mcpforunity://editor/state` → `ready_for_tools`). The repo-committed parts (§1–§6) are done once total; §0 is the only per-machine work. --- ## §1 — Install the DOTS stack Add these to `Packages/manifest.json` (it is NOT a `.csproj`/`.sln` — editing it is correct) or via UnityMCP `manage_packages(action="add", ...)`. Let UPM resolve the version compatible with Unity 6.4; then pin from `Packages/packages-lock.json`. - [ ] `com.unity.entities` - [ ] `com.unity.netcode` ← **Netcode for Entities** (ECS). NOT `com.unity.netcode.gameobjects`. - [ ] `com.unity.physics` ← Unity Physics (DOTS), if the game needs collision/triggers - [ ] `com.unity.entities.graphics` ← renders entities under URP (already on URP 17.4) (`com.unity.burst`, `com.unity.collections`, `com.unity.mathematics`, `com.unity.transport` come transitively.) - [ ] `read_console` until clean after the domain reload. **Verify:** `manage_packages(action="list")` shows all four; `packages-lock.json` records the resolved versions. - [ ] Optional cleanup: the template's `com.unity.visualscripting` and `TutorialInfo`/`Readme.asset` are unused for a DOTS game — remove if you don't want them (delete the asset **and** its `.meta` together). ## §2 — Project structure & asmdefs Pick a root namespace (e.g. `ProjectM`) and record it in `CLAUDE.md`. Create a Netcode-aware assembly split under `Assets/_Project/`: ``` Assets/_Project/ Scripts/ Simulation/ .Simulation.asmdef → Entities, Collections, Mathematics, Burst, Unity.Physics, Unity.NetCode Client/ .Client.asmdef → Simulation, Entities, Unity.NetCode, Unity.Entities.Graphics Server/ .Server.asmdef → Simulation, Entities, Unity.NetCode Authoring/ .Authoring.asmdef → Simulation, Entities, Unity.NetCode Subscenes/ Prefabs/ ``` - Shared **Simulation** = components + systems that run in BOTH client and server worlds. Client/Server hold world-specific systems; Authoring holds `…Authoring` MonoBehaviours + `Baker`. - [ ] **Verify** against the official ECS Samples / Netcode sample layout (context7 ID `/unity-technologies/entitycomponentsystemsamples`) — adjust the split if the current sample differs. Confirm each asmdef compiles (`read_console`). - Never create/edit `.csproj`/`.sln`; only `.asmdef`. ## §3 — Bootstrap & worlds - [ ] Add a `ClientServerBootstrap` subclass (confirm exact method names — `CreateClientWorld`/`CreateServerWorld`/`WorldSystemFilter` — via context7 `…com_unity_netcode_…`). - [ ] Create a minimal subscene so baking has a target. - [ ] **Verify:** entering Play Mode creates separate client and server `World`s (check the Entities Hierarchy / world dropdown). ## §4 — Smoke test (prove it compiles AND ticks) - [ ] One trivial unmanaged component (`struct Heartbeat : IComponentData { public int Tick; }`) + one `ISystem`+`[BurstCompile]` that increments it in `SimulationSystemGroup`. - [ ] One **`NetCodeTestWorld`** EditMode test that boots in-process client+server, connects, ticks N times, and asserts the component advanced. (Get the current `NetCodeTestWorld` API from context7.) - [ ] **Verify:** `run_tests(mode="EditMode")` → green; console clean of Burst/source-gen errors. ## §5 — In-repo vault Create `/Docs/Vault/` via the `obsidian-cli` skill (plain markdown is fine if obsidian-cli isn't set up yet): ``` Docs/Vault/ 00_Home/Home.md (Map of Content) 01_Vision/ (pillars, locked decisions) 02_Game_Design/ (systems design docs) 06_Roadmap/{Milestones,Backlog}.md 07_Sessions// (session logs) 07_Sessions/_Decisions/ (decision records, DR-001…) _Templates/{Session_Log,Decision_Record}_Template.md _Meta/{Documentation_Protocol,Tags}.md ``` - [ ] Point the Obsidian app at this folder as a vault. - [ ] **Verify:** obsidian-cli can list/read a note here. ## §6 — Memory MCPs (`.mcp.json`, committed, portable) Create `/.mcp.json` (or merge into existing) using `${CLAUDE_PROJECT_DIR}` so it loads unchanged on both machines: ```json { "mcpServers": { "basic-memory": { "command": "uvx", "args": ["basic-memory", "mcp"] }, "serena": { "command": "uvx", "args": ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--project", "${CLAUDE_PROJECT_DIR}"] } } } ``` - [ ] Configure **basic-memory**'s project to point at the vault: `basic-memory project add gamevault "/Docs/Vault"` (and set it default), per basic-memory's current docs. **Verify:** a semantic recall returns a hit on a vault note. - [ ] Run **serena** onboarding; test `find_symbol` on the §4 smoke-test system. - ⚠️ **Serena C# caveat:** its language server is flaky on Unity (auto-installs the wrong .NET, `.sln` load timeouts). If `find_symbol` errors/stalls, record it in `CLAUDE.md` and **fall back** to `Glob`/`Grep` — or add **`claude-context`** (local LanceDB vector index over `Assets/` + the vault) as the documented code-search fallback. Prefer local embeddings (FastEmbed/Ollama) to keep game code off third-party APIs. - [ ] **Verify:** `.mcp.json` contains no machine-specific absolute paths (only `${CLAUDE_PROJECT_DIR}`), so it loads on the other machine as-is. ## §7 — `CLAUDE.md` (repo root, committed) Write `/CLAUDE.md` covering: - [ ] Project root namespace + the asmdef split from §2. - [ ] The **DOTS/ECS conventions** (summarize / link the skill's `dots-conventions.md`): `ISystem`+Burst default, unmanaged `IComponentData`, `IEnableableComponent`, baking, jobs+allocators, ECB for structural changes, determinism (no wall-clock in predicted sim), server-authoritative + input-only clients, `[GhostField]`/ghost authoring. **Aspects deprecated (1.4).** - [ ] Guardrails (still valid from classic Unity): never edit `.meta` independently of its asset; never read/write `Library/`, `Temp/`, `obj/`, `Logs/`, `UserSettings/`; never edit/commit `.csproj`/`.sln`; no edits during Play Mode. - [ ] **"Which memory tool when"**: serena = C# symbols, basic-memory = design knowledge over the vault, grep = literals, context7 = current DOTS APIs, native memory = machine-local facts. - [ ] **Cross-machine rule:** durable/cross-machine truth goes in the in-repo vault or `CLAUDE.md` (both committed); native `memory/` is machine-local and does NOT sync. ## §8 — Native memory seed (machine-local) - [ ] Append to `MEMORY.md` (this machine): project uses Unity DOTS + Netcode for Entities; the chosen memory stack (vault + basic-memory + serena, claude-context fallback); that `/dots-dev` is the dev driver and this setup is one-time. (Repeat on the other machine, or re-derive from `CLAUDE.md`.) --- ## Done-when - All four DOTS packages installed, console clean, smoke-test `NetCodeTestWorld` green. - `Assets/_Project` asmdef split compiles; client+server worlds spin up. - Vault scaffolded; obsidian-cli reads it; basic-memory recalls a note; serena resolves a symbol (or fallback recorded). - `CLAUDE.md` + committed `.mcp.json` (portable) exist. - Second machine reproduces from §0 alone (everything else is in git).