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>
21 KiB
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-devFeature track is heavy by design.
Core principles (read first)
- 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. Seereferences/context7-libraries.md. - 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. Seereferences/dots-conventions.md. - Plan mode through approval. Phases up to operator approval are read-only. Code is written only after the operator approves and
ExitPlanModeis called. Self-police this — it is not harness-enforced. - 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. - Cross-platform. Discover the project root (cwd /
$CLAUDE_PROJECT_DIR). Reference the vault repo-relative as<repo>/Docs/Vault/. Never write/Users/...orC:\...into code, docs, or config — committed.mcp.jsonuses${CLAUDE_PROJECT_DIR}. - 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
- Foundation check (DOTS installed?). Read
Packages/packages-lock.json(ormanage_packages action=list). Ifcom.unity.entities/com.unity.netcodeare 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. - Unity ready? Read
mcpforunity://editor/state. Ifready_for_tools == falseor 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, readmcpforunity://instancesandset_active_instanceon the right one. - Memory stack reachable? Quick probe:
basic-memory(semantic recall) andserena(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 (orclaude-contextif installed) for this session. - Max-reasoning nudge (Feature track only, once): "Feature track benefits from max reasoning — raise the slider before approving the plan." Don't nag.
- Intake gate. If scope / surface / depth / output is unclear, bundle 2–4 ambiguities into a single
AskUserQuestionbefore 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):
CLAUDE.mdat repo root — authoritative project conventions + game design pointers.- Vault map of content (
<repo>/Docs/Vault/00_Home/Home.md) and the latest session log under07_Sessions/<year>/. - Open decision records (
_Decisions/withstatus: proposed) + roadmap/backlog. basic-memorysemantic recall on goal keywords; nativeMEMORY.md+memory/for machine-local facts/feedback.- 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, elseGlob/GreponAssets/_Project/**/*.cs+*.asmdef;manage_scene(action="get_hierarchy");unity_reflectfor goal-relevant types. - B — Knowledge state: obsidian-cli search +
basic-memoryrecall 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 inreferences/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/WebFetchallowed — 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 vsSystemBase), jobs, system groups/order, ECB usage, asmdef impact (which assembly: shared-simulation / client / server / authoring). MUST respectreferences/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 (3–5 agents)
- A — Script author:
create_script(new) /apply_text_editsafterget_sha(existing).validate_scriptnon-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_executefor 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, viaget_test_job(... include_failed_tests=True). For netcode work, aNetCodeTestWorldconnect/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>.mdvia 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-memorynote 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 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=[...]) |
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:
ReadMcpResourceTool(server="UnityMCP", uri="mcpforunity://instances")—instance_count >= 1⇒ connected (stop reporting down);== 0⇒ Unity not attached (operator opens Unity).ReadMcpResourceTool(server="UnityMCP", uri="mcpforunity://editor/state")—ready_for_tools==false/is_compiling==true⇒ transient busy, wait 2–5s and retry.manage_editor(action="telemetry_ping")— success ⇒ bridge alive.- If the call returns
InputValidationErrorclaiming the tool is unknown, the schema is deferred —ToolSearch(query="select:mcp__UnityMCP__<name>")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] privatedata carriers, coroutines for sim) where ECS is correct. - Author new
IAspecttypes (deprecated in Entities 1.4). - Store managed references in unmanaged
IComponentData. - Use wall-clock/
Time.deltaTimeorSystem.Randomin predicted/deterministic sim. - Do structural changes mid-job/mid-iteration instead of via
EntityCommandBuffer. - Edit
.metafiles directly, or read/writeLibrary/,Temp/,obj/,Logs/,UserSettings/. - Edit/commit
*.csproj/*.sln(Unity regenerates them). Edit.asmdef/manifest.jsoninstead. - Edit during Play Mode (check
play_statefirst). - 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-devin parallel.
References
references/dots-conventions.md— ECS/Netcode conventions this skill enforces.references/context7-libraries.md— seed library IDs + query playbook.references/agent-briefs.md— per-phase swarm brief templates.references/memory-protocol.md— vault / basic-memory / serena / native-memory usage + bookends.