Files
Project-M/.claude/skills/dots-dev/SKILL.md
T
kronic 1e23246568 Docs: DR-022 animation pipeline + /dots-dev commit phase
DR-022 + session log for the Rukhanka/Synty player-animation slice; CLAUDE.md stack row + Animation (Rukhanka) build gotchas + client asmdef refs; add Phase 10 (operator-approved commit) to the dots-dev skill.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 18:18:14 -07:00

23 KiB
Raw Blame History


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-idquery-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.
  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.
  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.
  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) → 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.
  • 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>.

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 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-idquery-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_shaapply_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_testsget_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_editsstale_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.
  • 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