--- name: dots-dev description: Run an adaptive Unity DOTS + Netcode for Entities dev session — sizes the task (trivial / small / feature), then orchestrates context7-led research, plan-mode-gated design, parallel agent swarms, DOTS-correct implementation, DOTS-aware validation, and a mandatory vault + memory update. Use when the operator types /dots-dev, "dots-dev", or opens a session on a Unity DOTS / ECS / Netcode-for-Entities project (anything like "let's work on ", "dots-dev: implement X", "design Y system", or other dev-session openings). Use as the default driver for any non-trivial DOTS work. Defaults all API/code research to context7. Detects a missing DOTS foundation and defers to the one-time project setup task rather than setting up inline. --- # /dots-dev — Adaptive Unity DOTS / Netcode Dev Session Orchestrator Drives an end-to-end Unity 6 development session for a **DOTS (Entities) + Netcode for Entities** game. The genre is project-specific (read it from `CLAUDE.md` + the vault); the constant is the tech stack: **data-oriented ECS, Burst, jobs, baking, server-authoritative netcode with client prediction**. This skill is **adaptive**: it sizes the task first, then runs only the phases that size needs. It is **reusable and path-portable** — it hardcodes no machine-specific absolute paths and works identically on macOS and Windows. It defaults every API / best-practice question to **context7** (Unity's DOTS APIs move fast). It keeps two things non-negotiable at every size: the **plan-approval gate** (`ExitPlanMode` before any state change) and the **doc + memory update** at session end. > **One-line reminder**: set max reasoning before invoking a Feature-track session. `/dots-dev` Feature track is heavy by design. ## Core principles (read first) 1. **context7-first for anything DOTS.** Any API name, signature, pattern, or "current best practice" for Entities / Netcode / Physics / Burst / Collections is resolved through **context7** (`resolve-library-id` → `query-docs`) before it is written, and cross-checked against the official ECS Samples repo. Do not trust training-data recall for these — they change between minor versions. See [`references/context7-libraries.md`](references/context7-libraries.md). 2. **DOTS-correct, not MonoBehaviour-correct.** The conventions are ECS conventions. `ISystem`+Burst by default, `IComponentData`/buffers/enableable, baking, jobs, `EntityCommandBuffer`, determinism. The classic-Unity rules (MonoBehaviour singletons, `[SerializeField] private`, coroutines) mostly do not apply. See [`references/dots-conventions.md`](references/dots-conventions.md). 3. **Plan mode through approval.** Phases up to operator approval are read-only. Code is written only after the operator approves and `ExitPlanMode` is called. Self-police this — it is not harness-enforced. 4. **Documentation Protocol bookends.** Every non-trivial session starts with a vault/memory scan and ends with a vault/memory update. See [`references/memory-protocol.md`](references/memory-protocol.md). 5. **Cross-platform.** Discover the project root (cwd / `$CLAUDE_PROJECT_DIR`). Reference the vault repo-relative as `/Docs/Vault/`. Never write `/Users/...` or `C:\...` into code, docs, or config — committed `.mcp.json` uses `${CLAUDE_PROJECT_DIR}`. 6. **Synthesize early.** After each swarm, write a tight summary; pass only the upstream summary downstream. Never carry raw agent dumps forward. ## When to use / not use **Use** for real DOTS work: a new system, component set, ghost/netcode surface, baking pipeline, refactor, balance pass, or design pass — on a project whose foundation already exists. **Do NOT use** for: one-shot questions (answer directly); mechanical edits the operator already designed (just do them); harness/tooling setup; **project setup / installing the DOTS stack** (that is the separate one-time setup task — see Pre-flight); non-DOTS work. ## Adaptive track selection (do this first) Size the goal, then run the matching track. Plan-approval and the doc/memory update are mandatory in **all** tracks. | Track | When | Phases run | |---|---|---| | **Trivial** | one-file edit, rename, a fix you already understand | inline: quick scan → do → `read_console` → one-line session-log append. No swarm, no research swarm. Still plan-gate if it mutates anything non-obvious. | | **Small** | a single system/component with clear design | Phase 0/0b (lite) → Phase 3 context7 research (1 agent) → Phase 4 plan → **approve** → Phase 6 implement → Phase 7 validate → Phase 8 doc. | | **Feature** | new mechanic, netcode surface, cross-cutting change, or anything >~30 min | full swarm, Phases 0–9 below. | When unsure, ask the operator with one `AskUserQuestion` ("Treat this as a quick edit or a full feature pass?") rather than guessing big. ## Phase 0 — Pre-flight + intake gate 1. **Foundation check (DOTS installed?).** Read `Packages/packages-lock.json` (or `manage_packages action=list`). If `com.unity.entities` / `com.unity.netcode` are **absent**, STOP: tell the operator the project foundation isn't set up and point them to the **one-time setup task** (installs the DOTS stack, asmdefs/bootstrap, vault, memory MCPs, `CLAUDE.md`). Do **not** install packages or scaffold inline — that is out of scope for this skill. 2. **Unity ready?** Read `mcpforunity://editor/state`. If `ready_for_tools == false` or no instance is connected, surface it and ask the operator to open the Unity project. Don't spawn swarms until ready. If multiple editors are open, read `mcpforunity://instances` and `set_active_instance` on the right one. 3. **Memory stack reachable?** Quick probe: `basic-memory` (semantic recall) and `serena` (`find_symbol`). If either is down, note it and fall back (obsidian-cli + Glob/Grep). Continue — the protocol works either way. If Serena's C# LSP stalls on the Unity solution, record it and use Glob/Grep (or `claude-context` if installed) for this session. 4. **Max-reasoning nudge** (Feature track only, once): *"Feature track benefits from max reasoning — raise the slider before approving the plan."* Don't nag. 5. **Intake gate.** If scope / surface / depth / output is unclear, bundle 2–4 ambiguities into a single `AskUserQuestion` before spawning anything. If the prompt is already specific, skip the gate. ## Phase 0b — Plan-mode entry + Documentation Protocol scan Declare plan mode active for phases 1–5: read-only only (`Read`, `Glob`, `Grep`, MCP resource reads, `unity_reflect`, `unity_docs`, `read_console`, context7, obsidian-cli reads, `basic-memory`, serena reads). No script writes, no `manage_gameobject` mutations, no vault writes, no `Edit`/`Write`, no state-mutating `Bash`. Scan, in order (via obsidian-cli unless the Obsidian REST MCP is present): 1. `CLAUDE.md` at repo root — authoritative project conventions + game design pointers. 2. Vault map of content (`/Docs/Vault/00_Home/Home.md`) and the latest session log under `07_Sessions//`. 3. Open decision records (`_Decisions/` with `status: proposed`) + roadmap/backlog. 4. `basic-memory` semantic recall on goal keywords; native `MEMORY.md` + `memory/` for machine-local facts/feedback. 5. Task-specific vault search for the goal's nouns. ## Phase 1 — Project & doc context swarm (≤3 agents, Explore) - **A — Code/asset graph**: Serena `find_symbol`/references over the relevant assemblies where it works, else `Glob`/`Grep` on `Assets/_Project/**/*.cs` + `*.asmdef`; `manage_scene(action="get_hierarchy")`; `unity_reflect` for goal-relevant types. - **B — Knowledge state**: obsidian-cli search + `basic-memory` recall for design/decisions touching the goal. - **C — Unity live state**: `mcpforunity://editor/state`, `project/info`, `instances`; `read_console(types=["error","warning"])`; `manage_packages(action="list")` (confirm installed Entities/Netcode versions for context7 version-pinning). Synthesize into a **≤400-word Project Brief**. Discard raw dumps. ## Phase 2 — Goal-understanding swarm (≤3 agents) Decompose the goal into a **Goal Spec**: *Deliverables* (each with a "done when"), *Assumptions* (validate at Phase 5), *Open ambiguities* (research in Phase 3 or ask). Inputs: operator's verbatim prompt + Phase 1 brief only. If the goal contradicts a locked decision in the vault/`CLAUDE.md`, halt and surface before Phase 3. ## Phase 3 — Research swarm (context7-FIRST) - **A — DOTS/Netcode implementation (context7, primary)**: for every API/pattern the goal needs, `resolve-library-id` (seeds in [`references/context7-libraries.md`](references/context7-libraries.md)) → `query-docs`. Pin to the **installed** package version. Cross-check the official ECS Samples repo for working patterns. - **B — Determinism/netcode correctness (context7 + samples)**: prediction loop, ghost replication, command/input, world bootstrap — confirm current API shapes, not remembered ones. - **C — Genre/design precedent (web, optional)**: only here is `WebSearch`/`WebFetch` allowed — how comparable games solve the *design* problem. Never use web for DOTS API shapes. Synthesize into a **≤500-word Research Digest**: *What to steal / What to avoid / Still unclear*, plus the exact context7 queries used (so Phase 6 can re-query precisely). If context7 reveals an API the plan depends on was removed/changed, halt and re-plan. ## Phase 4 — Design & plan swarm (≤3 agents, Plan) - **A — Code architect**: components (`IComponentData`/`IBufferElementData`/`IEnableableComponent`), systems (`ISystem`+Burst vs `SystemBase`), jobs, system groups/order, ECB usage, asmdef impact (which assembly: shared-simulation / client / server / authoring). MUST respect [`references/dots-conventions.md`](references/dots-conventions.md). - **B — Scene/subscene/baking architect**: authoring MonoBehaviours + `Baker`, subscene layout, ghost prefabs/authoring, what bakes where, URP/Entities-Graphics interactions. - **C — Vault doc architect**: which design docs get touched, whether a decision record is warranted, the session-log scaffold. Synthesize a **Unified Implementation Plan**: summary; exhaustive files-to-create/modify (Unity + vault paths, repo-relative); code skeletons (signatures only); build order with explicit "compile + `read_console`" checkpoints; **DOTS-aware test approach** (EditMode? PlayMode? `NetCodeTestWorld`? thin-client? play-tick determinism check?); vault updates; risks & open questions. ## Phase 5 — Operator review (plan-mode exit) Present the plan in full, highlight Risks & open questions. For any high-stakes ambiguity, `AskUserQuestion` with concrete options — do not proceed on assumptions. On approval, call **`ExitPlanMode`**. This is the hard boundary. **Do not start Phase 6 without explicit approval and `ExitPlanMode`.** ## Phase 6 — Implementation swarm (3–5 agents) - **A — Script author**: `create_script` (new) / `apply_text_edits` after `get_sha` (existing). `validate_script` non-trivial files before write. `read_console(types=["error"])` after **every** write. Re-query context7 for exact signatures when the digest left anything ambiguous. - **B — Scene/subscene/baking wirer**: authoring components, subscenes, ghost prefabs, ScriptableObject config assets, scene saves. `batch_execute` for bulk. - **C — Asmdef/package guardian** (conditional): new assemblies or references — keep the client/server/shared/authoring split clean; verify it compiles. - **D — Doc-skeleton author** (conditional): new vault docs get frontmatter skeletons now; bodies in Phase 8. Parallelize only where write surfaces don't overlap. Sequence across domain reloads (a component must compile before a system or baker can reference it). Quality bar: compiles clean, no new warnings, console clean, conventions honored, Burst-compatible where it should be, no managed refs in unmanaged components, deterministic sim code, no edits during Play Mode (`manage_editor(action="play_state")` first). ## Phase 7 — Validate swarm (DOTS-aware, 3–4 agents) - **A — Console/Burst/source-gen sweep**: `read_console(types=["error","warning","exception"], include_stacktrace=True)` vs the pre-Phase-6 baseline. Burst-compile and source-generator failures surface here, not in a plain build — any new one is a finding. - **B — Test runner**: `run_tests(mode="EditMode")` then PlayMode if applicable, via `get_test_job(... include_failed_tests=True)`. For netcode work, a `NetCodeTestWorld` connect/tick test or a thin-client check. - **C — Runtime/determinism spot-check**: brief Play Mode entry, step ticks, confirm predicted/interpolated ghosts behave; screenshots for visual work; verify plan-specified entities/components exist. "Compiles clean" is necessary, not sufficient — determinism desyncs, rollback bugs, structural-change invalidation, and sync-point stalls only appear at runtime under prediction. Loop ≤3 fix iterations on a finding via a tight fix sub-swarm; if iteration 3 still fails, halt and surface a clear "I can't resolve X without a decision." ## Phase 8 — Doc + memory update (never skip) - Session log → `/Docs/Vault/07_Sessions//_.md` via obsidian-cli (template in the vault). Same-day collision → `_A`, `_B`, … - Firm decisions → a decision record in `_Decisions/`, back-referenced from the session log. - Touched design docs → edited in place (wikilink, don't duplicate into the log). - Durable, cross-machine knowledge → a `basic-memory` note in the vault. - Machine-local facts/feedback/working-style → native `MEMORY.md` (+ a memory file if substantive). Remember native memory does **not** sync across your Mac/Windows machines — cross-machine truth belongs in the vault. If the operator says "skip the protocol", still write a one-line stub log so the gap is visible, and record the preference as a native feedback memory. ## Phase 9 — Final report ``` ## /dots-dev session complete — **Summary**: ≤4 sentences — goal, what was delivered, did it land cleanly. **What changed**: - Unity: (repeat) - Vault: (repeat) **Validation**: Tests , console clean, . **Suggested next step**: . ``` Then **offer to commit** the changes (Phase 10) — propose how, but do not commit unless asked. Do not auto-loop into a fresh session. ## Phase 10 — Commit (only after explicit operator approval) Committing is a state change, so it is **gated like the plan**: never auto-commit. In the Phase 9 report, **offer** to commit and propose the grouping; commit only when the operator explicitly says so (e.g. "commit", "commit it", "commit for me"). If they decline or don't mention it, **leave git untouched** and note the changes are uncommitted for their review. When approved: 1. **Review first.** `git status` + `git diff --stat` (and `git diff` on anything non-obvious) so the operator sees exactly what lands. **Stage explicit paths — never `git add -A` blindly.** Never commit generated/cache (`Library/`, `Temp/`, `obj/`, `Logs/`, `UserSettings/`), `.csproj`/`.sln`, or stray scratch files (debug screenshots, temp exports). 2. **Group logically** — one commit per concern, not one mega-commit: typically (a) the feature's `Assets/` code + assets, (b) tests, (c) `Docs/Vault/` + `CLAUDE.md`. Always keep a `.cs`/prefab/material/controller **with its `.meta`** in the same commit. 3. **Proper messages.** Read recent `git log --oneline` first and match the repo's style. Imperative subject (≤~72 chars) summarizing the change; a short body on the *what + why* with a back-reference to the DR / session log (e.g. "See DR-0NN"). End **every** message with the Co-Authored-By trailer the environment specifies. 4. **Branch + push policy.** Match the repo's convention (the `git log` reveals it — many solo DOTS projects commit straight to the default branch; if the history is *not* solo-commits-on-default, branch first). **Never push** unless the operator explicitly asks. 5. Report the commit hash(es) + a one-line summary of each, then stop. ## DOTS conventions (authoritative file) `CLAUDE.md` at the repo root is the project's source of truth; [`references/dots-conventions.md`](references/dots-conventions.md) is the reusable ECS/Netcode rule set this skill enforces. Treat any violation found in Phase 7 as a blocking finding. Quick reminders: `ISystem`+`[BurstCompile]` default; unmanaged `IComponentData`; `IEnableableComponent` over add/remove for frequently-toggled state; `Baker` + subscenes for authoring; `IJobEntity`/`IJobChunk` + correct `Allocator` + disposal; `EntityCommandBuffer` for structural changes; no wall-clock in predicted sim; server-authoritative, clients send input; `[GhostField]`/`GhostAuthoringComponent` for replication. **Aspects are deprecated (Entities 1.4) — do not author new ones.** Always confirm volatile APIs via context7 at code-time. ## MCP cheat sheet | Need | Tool / Resource | Note | |---|---|---| | Is Unity ready? | `mcpforunity://editor/state` | check `ready_for_tools`, `is_compiling` | | Installed package versions | `Packages/packages-lock.json` or `manage_packages(action="list")` | pin context7 to the installed version | | Current DOTS API/pattern | context7 `resolve-library-id` → `query-docs` | **primary** for all DOTS code | | What scenes/objects exist | `manage_scene(action="get_hierarchy")` + `find_gameobjects` | read before mutating | | New script | `create_script(path, contents)` → `read_console` | auto-import + compile | | Edit script | `get_sha` → `apply_text_edits` | prefer over raw `Edit` for `.cs` in Assets | | Validate before write | `validate_script` | catch errors pre-domain-reload | | Bulk ops | `batch_execute(commands=[...])` | 10–100× faster | | Run tests | `run_tests` → `get_test_job(... include_failed_tests=True)` | EditMode/PlayMode | | Symbol nav | serena `find_symbol` / references | falls back to Glob/Grep on Unity C# issues | | Read/search vault | obsidian-cli | REST MCP optional | | Semantic knowledge recall | `basic-memory` | over the same vault files | ## Error recovery | Symptom | Cause | Resolution | |---|---|---| | Tools "busy" / `is_compiling=true` | compiling | poll `editor/state` until `is_compiling==false` | | `apply_text_edits` → `stale_file` | SHA changed | re-`get_sha`, retry | | UnityMCP drops mid-phase | domain reload | wait ~5s, re-read `instances`, re-pin | | `create_script` then "component not found" | reload not done | poll `is_compiling==false`, retry | | Burst/source-gen error after a clean C# build | DOTS codegen failure | read the full console stack; fix the component/job; re-`read_console` | | Serena `find_symbol` stalls/times out | C# LSP / .sln issue on Unity | record it; use Glob/Grep (or claude-context) this session | | context7 version mismatch | installed pkg ≠ baked ID | re-`resolve-library-id`, prefer the installed version's docs | | Test job timeout | slow PlayMode/netcode test | re-poll `get_test_job(wait_timeout=120)`; don't re-trigger | ### UnityMCP "not connected" — diagnostic protocol (subagents MUST follow before reporting it down) A bare `mcp__UnityMCP__*` error is **not** proof the server is down. Before reporting "UnityMCP not connected", a subagent MUST run and quote results from: 1. `ReadMcpResourceTool(server="UnityMCP", uri="mcpforunity://instances")` — `instance_count >= 1` ⇒ connected (stop reporting down); `== 0` ⇒ Unity not attached (operator opens Unity). 2. `ReadMcpResourceTool(server="UnityMCP", uri="mcpforunity://editor/state")` — `ready_for_tools==false`/`is_compiling==true` ⇒ transient busy, wait 2–5s and retry. 3. `manage_editor(action="telemetry_ping")` — success ⇒ bridge alive. 4. If the call returns `InputValidationError` claiming the tool is unknown, the schema is deferred — `ToolSearch(query="select:mcp__UnityMCP__")` then retry (tool-loading, not connection). Escalate only after 1–3 fail or step 1 returns `instance_count == 0`. Quote the literal error from each probe. ## Boundary rules **MUST stop and consult the operator when**: intake goal too thin; the goal contradicts a locked vault/`CLAUDE.md` decision; a material design choice has no clear best answer; **Phase 5 always** (`ExitPlanMode` is the only authorized hand-off); 3 failed fix iterations on one finding; operator intent drifts from what's being built; a destructive op outside the approved plan is implied; **the DOTS foundation is missing** (defer to the setup task, don't improvise it). **MAY loop without consulting**: compile/Burst error → fix → recompile (≤3); test failure → fix → retest (≤3); vault write failure → re-read + retry (≤2). **MUST abort without writing partial state when**: Unity unreachable >60s mid-session; project broken (asmdefs missing, won't load); Phase 8 vault write fails repeatedly (write a local fallback note + tell the operator). ## Anti-patterns — things `/dots-dev` MUST NOT do - Trust training-data recall for a DOTS API instead of context7. - Author MonoBehaviour-world solutions (MonoBehaviour singletons, ScriptableObject "services" for runtime sim, `[SerializeField] private` data carriers, coroutines for sim) where ECS is correct. - Author new `IAspect` types (deprecated in Entities 1.4). - Store managed references in unmanaged `IComponentData`. - Use wall-clock/`Time.deltaTime` or `System.Random` in predicted/deterministic sim. - Do structural changes mid-job/mid-iteration instead of via `EntityCommandBuffer`. - Edit `.meta` files directly, or read/write `Library/`, `Temp/`, `obj/`, `Logs/`, `UserSettings/`. - Edit/commit `*.csproj` / `*.sln` (Unity regenerates them). Edit `.asmdef` / `manifest.json` instead. - Edit during Play Mode (check `play_state` first). - Write machine-specific absolute paths into the skill, code, docs, or `.mcp.json` (use `` / `${CLAUDE_PROJECT_DIR}`). - Install the DOTS stack / scaffold the project inline (that's the separate setup task). - Skip plan mode, start Phase 6 without `ExitPlanMode`, or skip the Phase 8 doc/memory update. - **Commit or push without explicit operator approval** — committing is gated like the plan (Phase 10): offer it in the report, commit only when the operator says so, group logically with proper messages, and **never push** unless asked. Run more than one `/dots-dev` in parallel. ## References - [`references/dots-conventions.md`](references/dots-conventions.md) — ECS/Netcode conventions this skill enforces. - [`references/context7-libraries.md`](references/context7-libraries.md) — seed library IDs + query playbook. - [`references/agent-briefs.md`](references/agent-briefs.md) — per-phase swarm brief templates. - [`references/memory-protocol.md`](references/memory-protocol.md) — vault / basic-memory / serena / native-memory usage + bookends.