Release 1.1.2 — the default path works end to end

Fix release for 1.1.1: the minimal path end to end, engine commands that
run on Godot, Unity and Unreal, hook warnings you can see, and verdicts
that say when they could not check. Details in CHANGELOG.md; upgrade
steps in UPGRADING.md (v1.1.1 → v1.1.2).

Fixes #67
Fixes #131

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
This commit is contained in:
Donchitos
2026-09-29 21:32:19 +10:00
co-authored by Claude Opus 5.5
parent 7ed2c3e9c4
commit b21fa0f7f2
383 changed files with 22888 additions and 10618 deletions
@@ -3,7 +3,6 @@
## Agent Summary
Domain: ECS architecture (IComponentData, ISystem, SystemAPI), Jobs system (IJob, IJobEntity, Burst), Burst compiler constraints, DOTS gameplay systems, and hybrid renderer.
Does NOT own: MonoBehaviour gameplay code (gameplay-programmer), UI implementation (unity-ui-specialist).
Model tier: Sonnet (default).
No gate IDs assigned.
---
@@ -11,8 +10,8 @@ No gate IDs assigned.
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references ECS / Jobs / Burst / IComponentData)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] `tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is `sonnet` — frontmatter `model:` reads exactly `sonnet` (tiers: `.claude/docs/model-tiers.md`)
- [ ] Agent definition does not claim authority over MonoBehaviour gameplay or UI systems
---
@@ -25,10 +24,10 @@ No gate IDs assigned.
- Produces:
- `PlayerMovementData : IComponentData` struct with velocity, speed, and input vector fields
- `PlayerMovementSystem : ISystem` with `OnUpdate()` using `SystemAPI.Query<>` or `IJobEntity`
- Bakes the player's initial state from an authoring MonoBehaviour via `IBaker`
- Bakes the player's initial state from an authoring MonoBehaviour via a `Baker<T>` subclass (the pattern in `docs/engine-reference/unity/plugins/dots-entities.md`)
- Uses `RefRW<LocalTransform>` for position updates (not deprecated `Translation`)
- Marks the job `[BurstCompile]` and notes what must be unmanaged for Burst compatibility
- Does NOT modify the input polling system — reads from an existing `PlayerInputData` component
- Keeps one concern per system: the movement system reads input from a component (e.g. `PlayerInputData`) that a separate input system writes, rather than polling input itself, and asks before creating or changing that input side
### Case 2: MonoBehaviour push-back
**Input:** "Just use MonoBehaviour for the player movement — it's simpler."
@@ -36,7 +35,7 @@ No gate IDs assigned.
- Acknowledges the simplicity argument
- Explains the DOTS trade-off: more setup upfront, but the ECS/Burst approach provides the performance characteristics documented in the project's ADR or requirements
- Does NOT implement a MonoBehaviour version if the project has committed to DOTS
- If no commitment exists, flags the architecture decision to `lead-programmer` / `technical-director` for resolution
- If no commitment exists, routes the MonoBehaviour-vs-DOTS decision to `unity-specialist` (its named contact for overall Unity architecture), with `technical-director` as the escalation for an unresolved technical conflict
- Does not make the MonoBehaviour vs. DOTS decision unilaterally
### Case 3: Burst-incompatible managed memory
@@ -45,27 +44,26 @@ No gate IDs assigned.
- Flags `List<T>` as a managed type that is incompatible with Burst compilation
- Does NOT approve the Burst job with managed memory access
- Provides the correct replacement: `NativeArray<EnemyData>`, `NativeList<EnemyData>`, or `NativeHashMap<>` depending on the use case
- Notes that `NativeArray` must be disposed explicitly or via `[DeallocateOnJobCompletion]`
- Notes that the native container must be disposed, with the allocator chosen by lifetime (`Allocator.TempJob` for frame-scoped, `Allocator.Persistent` for long-lived) and capacity pre-allocated when the size is known
- Produces the corrected job using unmanaged native containers
### Case 4: Hybrid access — DOTS system needs MonoBehaviour data
**Input:** "The DOTS movement system needs to read the camera transform managed by a MonoBehaviour CameraController."
**Expected behavior:**
- Identifies this as a hybrid access scenario
- Provides the correct hybrid pattern: store the camera transform in a singleton `IComponentData` (updated from the MonoBehaviour side each frame via `EntityManager.SetComponentData`)
- Alternatively suggests the `CompanionComponent` / managed component approach
- Does NOT access the MonoBehaviour from inside a Burst job — flags that as unsafe
- Provides the bridge code on both the MonoBehaviour side (writing to ECS) and the DOTS system side (reading from ECS)
- Does NOT put the `Transform` or the MonoBehaviour itself into a component — components hold no references to managed objects
- Carries the camera data across the boundary as unmanaged values (`Unity.Mathematics` types) in an `IComponentData`, written at one explicit hand-off point on the MonoBehaviour side and read by the system — not reached for per entity
- Does NOT access the MonoBehaviour from inside a Burst job — flags managed access in Burst code as a compile error
### Case 5: Context pass — performance targets
**Input:** Technical preferences from context: 60fps target, max 2ms CPU script budget per frame. Request: "Design the ECS chunk layout for 10,000 enemy entities."
**Expected behavior:**
- References the 2ms CPU budget explicitly in the design rationale
- Designs the `IComponentData` chunk layout for cache efficiency:
- Groups frequently-queried together components in the same archetype
- Separates rarely-used data into separate components to keep hot data compact
- Estimates entity iteration time against the 2ms budget
- Provides memory layout analysis (bytes per entity, entities per chunk at 16KB chunk size)
- Splits components by system access pattern, not by game concept — no "god component"
- Keeps hot components small, with rarely-used data in separate components
- Uses tag components for filtering, avoids `ISharedComponentData` that would fragment archetypes, and uses `IEnableableComponent` instead of structural changes for toggled state
- Names how the budget will be verified — Entities Profiler system timings and per-archetype memory — instead of presenting unmeasured timings as fact
- Does NOT design a layout that will obviously exceed the stated 2ms budget without flagging it
---
@@ -74,14 +72,15 @@ No gate IDs assigned.
- [ ] Stays within declared domain (ECS, Jobs, Burst, DOTS gameplay systems)
- [ ] Redirects MonoBehaviour-only gameplay to gameplay-programmer
- [ ] Returns structured output (IComponentData structs, ISystem implementations, IBaker authoring classes)
- [ ] Returns structured output (IComponentData structs, ISystem implementations, `Baker<T>` authoring classes)
- [ ] Flags managed memory access in Burst jobs as a compile error and provides unmanaged alternatives
- [ ] Provides hybrid access patterns when DOTS systems need to interact with MonoBehaviour systems
- [ ] Designs chunk layouts against provided performance budgets
- [ ] Designs chunk layouts against provided performance budgets, and names the profiling step that verifies them
- [ ] Asks "May I write this to [filepath]?" naming the file before writing
---
## Coverage Notes
- ECS conversion (Case 1) must include a unit test using the ECS test framework (`World`, `EntityManager`)
- ECS conversion (Case 1) must include a unit test using the ECS test framework (`World`, `EntityManager`) under `Assets/Tests/EditMode/`
- Burst incompatibility (Case 3) is safety-critical — the agent must catch this before the code is written
- Chunk layout (Case 5) verifies the agent applies quantitative performance reasoning to architecture decisions
- Chunk layout (Case 5) verifies the agent designs against a stated budget and says how it will be measured, rather than asserting unmeasured numbers