Files
Project-M/.claude/skills/dots-dev/SKILL.md
T
Luis Gonzalez a5af81c8a8 Commit dots-dev skill into repo for cross-machine portability
Move the dots-dev skill from machine-local ~/.claude/skills/ into the
repo at .claude/skills/dots-dev/ so it travels with a clone. Update the
CLAUDE.md per-machine setup note to reflect that the skill no longer
needs manual placement; unity-mcp-skill and native memory/ stay local.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 11:58:37 -07:00

211 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 <game>", "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 `<repo>/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 09 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 24 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 15: 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 (`<repo>/Docs/Vault/00_Home/Home.md`) and the latest session log under `07_Sessions/<year>/`.
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<T>`, 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 (35 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, 34 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 → `<repo>/Docs/Vault/07_Sessions/<year>/<YYYY-MM-DD>_<Topic>.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 — <Topic>
**Summary**: ≤4 sentences — goal, what was delivered, did it land cleanly.
**What changed**:
- Unity: <repo-relative path> — <one line> (repeat)
- Vault: <repo-relative path> — <one line> (repeat)
**Validation**: Tests <X/Y>, console clean, <netcode/determinism check result>.
**Suggested next step**: <one concrete next action, from the session log's Next-session intent>.
```
Stop. Do not auto-loop into a fresh session.
## 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<T>` + 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=[...])` | 10100× 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 25s 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__<name>")` then retry (tool-loading, not connection).
Escalate only after 13 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 `<repo>` / `${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.
- Auto-commit to git (the operator commits manually). 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.