Docs: truth pass over CLAUDE.md, DRs and the MOCs (audit M13/M14/M15/M16/M19/L11/L12)

CLAUDE.md — it is loaded every session, so its errors cost the most:
- M13: it still said "No world code until the world-model spike passes
  its design review" while DR-049 has been `accepted` since 07-13 and the
  roadmap says PASSED. A hard contradiction between the two authority
  docs, with CLAUDE.md winning by being always-loaded — plausibly part of
  why Phase 2 never started. Now points at the build spec, warns it needs
  re-anchoring, and links the parked engine fork.
- Records the H2 hazard as a rule: a socket whose SparkId is missing from
  the baked AbilityDatabase silently reads Damage/Range/Cooldown 0.
- L12: the asmdef table was stale on all four rows; also notes the fifth
  compilation unit (Scripts/Editor has no asmdef) and that tests now
  reference Authoring.
- M19: per-machine setup — the machine-loss recovery checklist — was
  missing Blender + blendermcp (which the committed /art-dev skill
  hard-requires) and ctx7, and claimed a ${CLAUDE_PROJECT_DIR} in
  .mcp.json that isn't there.
- Structures / harvest / persistence / BefourStudios bullets rewritten:
  they described deleted subsystems.
- Net-zero rule honoured: the additions pushed it to 41,057 (over the
  40,960 hard limit), so two long art-pipeline bullets moved verbatim to
  the gotchas archive under a dated heading. 39,661 now — inside the
  file's own 39,936 soft ceiling.

- M14: DR-053 files the Bevy fork as PARKED. The guide was reachable from
  NOTHING — one file, zero inbound links, and its gating instruction
  lived only in machine-local memory, which CLAUDE.md explicitly forbids
  as a sole home. It now has a committed home and inbound links.
- DR-054 records this purge, including the three files that were in the
  delete set until their consumers were checked and turned out to be
  load-bearing.
- M15: 13 superseded DRs re-statused with `superseded_by`. Only DR-002
  carried the field before, though the project's own template prescribes
  it.
- M19: Home.md stated three wrong facts (latest DR, latest session, date)
  — refreshed. Pillars.md and Systems_Index.md now carry warning banners:
  both assert things the purges falsified, and Systems_Index still claims
  to be "the accurate map of what exists in code today".
- L11: the 4 genuinely-broken wikilinks fixed (typo'd DR filenames). Zero
  broken vault-internal links now.
- Session log written — the last three commits before today had none,
  breaking the protocol's own bookend rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-07 13:44:18 -07:00
parent e42760e7d0
commit c87dd04e87
21 changed files with 296 additions and 35 deletions
+14 -15
View File
@@ -34,12 +34,13 @@ Root namespace: **`ProjectM`**. Code lives under `Assets/_Project/Scripts/` in f
| Assembly | Namespace | Runs in | References |
|---|---|---|---|
| `ProjectM.Simulation` | `ProjectM.Simulation` | **client + server** worlds | Entities, **Unity.Transforms**, Collections, Mathematics, Burst, Unity.Physics, Unity.NetCode |
| `ProjectM.Client` | `ProjectM.Client` | client world only | + Simulation, Unity.Entities.Graphics, **Unity.InputSystem**, Unity.Transforms, Unity.NetCode, **Unity.Physics + Unity.CharacterController** (KinematicCharacterBody source-gen), **Rukhanka.Runtime** (animation) |
| `ProjectM.Server` | `ProjectM.Server` | server world only | + Simulation, **Unity.Transforms**, Unity.NetCode |
| `ProjectM.Authoring` | `ProjectM.Authoring` | bake time (+ scene runtime) | Simulation, Entities, **Unity.Entities.Hybrid**, Collections, Mathematics, Unity.NetCode |
| `ProjectM.Simulation` | `ProjectM.Simulation` | **client + server** worlds | Entities, **Unity.Transforms**, Collections, Mathematics, Burst, Unity.Physics, Unity.NetCode, Unity.CharacterController |
| `ProjectM.Client` | `ProjectM.Client` | client world only | + Simulation, Unity.Entities.Graphics, **Unity.InputSystem**, Unity.Transforms, Unity.NetCode, **Unity.Physics + Unity.CharacterController** (KinematicCharacterBody source-gen), **Rukhanka.Runtime** (animation), Unity.Networking.Transport, UnityEngine.UI, Rukhanka.Toolbox |
| `ProjectM.Server` | `ProjectM.Server` | server world only | + Simulation, **Unity.Transforms**, Unity.NetCode, Unity.Networking.Transport, Unity.Physics |
| `ProjectM.Authoring` | `ProjectM.Authoring` | bake time (+ scene runtime) | Simulation, Entities, **Unity.Entities.Hybrid**, Collections, Mathematics, Unity.NetCode, Unity.Physics, Unity.CharacterController |
- **Simulation** = components + systems shared by both worlds (most gameplay). **Client/Server** = world-specific. **Authoring** = `…Authoring` MonoBehaviours + `Baker<T>`.
- A **fifth** compilation unit exists by omission: `Scripts/Editor/` has NO asmdef, so it compiles into `Assembly-CSharp-Editor`. `ProjectM.Tests.EditMode` references all four asmdefs incl. **Authoring** (so bakers are testable).
- Other folders: `Assets/_Project/Subscenes/` (baked entity subscenes), `Assets/_Project/Prefabs/`, `Assets/_Project/Tests/EditMode/`.
- Feature folders added since (`Client/UI`, `Client/Settings`, `Server/Automation`, `Server/Persistence`, `Simulation/Automation`, `Simulation/Persistence`) live **inside the existing four asmdefs — no new assemblies**.
@@ -85,12 +86,11 @@ Long-form originals + the milestone each came from: `Docs/Vault/_Meta/CLAUDE_Bui
- **Hit/area tests must be SWEPT, not point checks** — a point check tunnels when the per-tick step exceeds the target radius (high speed *or* tick-batching); test the segment traversed this tick. **In a PLAIN `SimulationSystemGroup` system do NOT use `SystemAPI.Time.DeltaTime`** (wall-frame delta, not the fixed step) — store the per-tick step on the projectile (`Projectile.LastStep`, written in the fixed-step group) and rebuild the segment as `cur - dir*LastStep`. `ecb.DestroyEntity` **at-most-once** per tick (destroyed-bitset; double destroy throws at Playback). **TWO target types in one pass: UNIFY into one best-target loop + one shared bitset** (separate sweeps double-destroy a projectile overlapping both — DR-018). **A per-hit yield `(int)` cast that also gates despawn is an immortal-sink** (sub-1.0→0→no deposit, shot still consumed): guard `math.max(1,(int)yield)` + `[Min(1f)]` authoring.
### Build / structures / grid
- **Build-grid math must be deterministic + integer-stable:** corner-origin, center-returning, **half-open** cell bounds, `math.floor`. Lock `CellSize`/`PlotSize` as a coordinate space once (`BaseGridMath`) — changing them invalidates placed structures.
- **Structures:** only `Type` replicates (client derives `Cell`); **occupancy is DERIVED** from live ghosts, never baked. See [[DR-014_M6_Build_Structures_Automation_Foundation]].
- **Co-op placement atomicity:** commit `StorageMath.Withdraw` + cell-reservation **in-place in the RPC foreach** (only `Instantiate` via ECB) so two same-tick requests for one cell can't both pass. Ledger spends generally: afford→act else SOFT-FAIL (no cooldown-burn), read LIVE in-loop (no hoist); a Health-less entity silently drops OUT of an aggro snapshot (snapshot ABOVE the early-return).
- **DR-051 purge (07-15) ★:** siege/cycle/core/turret/automation + legacy `AbilityRef` path + onboarding **DELETED** (git = the archive). **Retired byte VALUES stay reserved, never renumbered** (`StructureType` 1-4, `ResourceId.Charge`, `DebugOp` 3/10/11, `TuningKnob` 20-23); `DebugOp.SpawnWave`/`EndSiege` RE-MEANT (force-wave / quiet-arena). **Waves UNGATED** — a baked `WaveDirectorAuthoring` decides by placement. Sockets are THE ability model (frame loadout seeded unconditionally at spawn); `CharacterId``FrameKind`. [[DR-051_Lantern_Realignment_Purge]].
- **Harvest:** in-run nodes→PERSONAL `InventorySlot` (`[GhostField] OwnerSendType.All`, spill→ledger); `G`=deposit at base. Inventory/equipment PAUSED → archive 2026-06-12 + [[DR-026_Inventory_Equipment_Progression_Foundation]].
- **Disk persistence (`SaveData`, single-slot atomic JSON, versioned) ★:** **born-correct load**`CycleDirectorSpawnSystem` (the ledger/RunInfo/meta host) applies the menu-staged `PendingSave` AT SPAWN; `BaseRestoreSystem` replays structures charge-free + HP. **v7 = a FRESH EPOCH: `MinLoadableVersion = CurrentVersion = 7`** (older saves rejected → New Game); additive again going forward. `RunDirectorSystem`'s terminal bank is the sole autosave trigger. See [[DR-019_Frontend_Menu_Settings_Saves_Build]] + [[DR-051_Lantern_Realignment_Purge]].
- **Grid math** (`BaseGridMath`, still live for spawn rings/respawn/lights): corner-origin, center-returning, **half-open** cell bounds, `math.floor`; lock cell size as a coordinate space once. Structures/placement themselves are deleted — recipe + atomicity rules in [[DR-014_M6_Build_Structures_Automation_Foundation]] if buildables return.
- **Ledger spends:** afford→act else SOFT-FAIL (no cooldown-burn), read LIVE in-loop (no hoist); a Health-less entity silently drops OUT of an aggro snapshot (snapshot ABOVE the early-return).
- **DR-051 purge (07-15) ★:** siege/cycle/core/turret/automation + legacy `AbilityRef` path + onboarding **DELETED** (git = the archive). **Retired byte VALUES stay reserved, never renumbered** (`StructureType` 1-4, `ResourceId.Charge`, `DebugOp` 3/10/11, `TuningKnob` 20-23); `DebugOp.SpawnWave`/`EndSiege` RE-MEANT (force-wave / quiet-arena). **Waves UNGATED** — a baked `WaveDirectorAuthoring` decides by placement. Sockets are THE ability model (frame loadout seeded unconditionally at spawn) — **the Spark defs must be in EVERY gameplay subscene's `AbilityDatabaseAuthoring`; a socket whose SparkId is missing from the baked blob silently reads Damage/Range/Cooldown 0** (audit H2, live-proven). `FrameKind` = Bathynaut(2)/Harpooner(3); `PlayerClass` is gone (FrameId is the single frame identity). [[DR-051_Lantern_Realignment_Purge]] · **2026-08-07 audit purge deleted the whole base/expedition shell** (run FSM, meta shop, prep, boons, build/structures, storage, inventory/equipment, enemy variants + boss): [[DR-054_Audit_Purge_2026-08]].
- **Harvest is single-sink** (→ the shared ledger, via `HarvestMath.DepositYield`). The personal-bag/equipment layer was deleted 2026-08-07; reintroduce LANTERN's carried-vs-banked split *inside HarvestMath*, not at its two call sites.
- **Disk persistence (`SaveData`, single-slot atomic JSON, versioned) ★:** **born-correct load**`CycleDirectorSpawnSystem` (now the ledger host only) applies the menu-staged `PendingSave` AT SPAWN. **v7 = a FRESH EPOCH: `MinLoadableVersion = CurrentVersion = 7`**; additive going forward — the save now carries only the ledger (structure/meta fields persist empty so v7 files still load). See [[DR-019_Frontend_Menu_Settings_Saves_Build]].
### Presentation / juice / VFX
- **All juice/HUD = client-only observe-only `SystemBase` in `PresentationSystemGroup`** (once/frame, no rollback double-fire), never mutates the sim. Read ECS via `SystemAPI.Query` + `EntityManager.CompleteDependencyBeforeRO<T>()` — NOT MonoBehaviour `LateUpdate` (job-safety throw). `Entity` = a stable client dict key per ghost lifetime — **prune the cache each frame** (a pruned ghost = a kill/loss → death VFX); **never `DestroyEntity` a ghost client-side** (`GhostDespawnSystem` owns despawn). Hit-stop = camera punch, **never `Time.timeScale`**.
@@ -100,7 +100,7 @@ Long-form originals + the milestone each came from: `Docs/Vault/_Meta/CLAUDE_Bui
- **HUD skin = build-safe `HudTheme` SO of serialized sprite refs** (runtime `Resources.Load` by name is build-stripped); tint MULTIPLIES, never set `unitySlice*` on 9-slices → archive 2026-07-06 + [[DR-024_HUD_Synty_Skin_Theme]].
### Art import (HDRP store packs → URP)
- BefourStudios HDRP art: convert via `EnvArtTools.cs`, never switch pipelines (HDRP breaks EG); Synty = URP-native → archive 2026-07-06.
- Synty = URP-native. (BefourStudios HDRP pack deleted 2026-08-07 — 4 reachable textures kept in `_Project/Textures/Env`.)
- **World = the LANTERN murk ★ (DR-051; Synty biomes deleted):** ONE look — `PostFX_Lantern.asset` (ACES; needs URP HDR grading) + `Env_SeabedKit.prefab` (ArtStaging-sourced) + unified RenderSettings (NO skybox; Exp² teal fog {0.02,0.10,0.12}; flat ambient {0.03,0.055,0.08}; density knob 0.035 play / 0.075 staging; camera clearFlags **SolidColor deep-water** — else no-skybox corners bleed blue). `ScenePolicy.IsGameplayScene()` gates the dynamic-look systems — never re-add `scene.name` string checks. `WorldAtmosphereSystem` = water-column murk.
- **A dark-lit screenshot MASKS material bugs — verify material *values*** (`GetPropertyType`-guard before `GetColor`/`GetFloat`; detail → archive 07-16).
- **EG per-instance tint (`URPMaterialPropertyBaseColor`) works ONLY on a Hybrid-Per-Instance `_BaseColor` graph** (AnimatedLitShader yes; stock Synty `Generic_Basic` = Unity-Per-Material → renders but silently no-ops) — check the graph first; else procedural decals. Detail → archive 07-16.
@@ -120,8 +120,7 @@ Full rationale: [[DR-022_Animation_Pipeline_Rukhanka_Synty]] · [[DR-023_Enemy_A
- **First Rukhanka bake is ~60 s, main-thread-synchronous** (editor freezes — not a hang; cached after).
- **The server runs Rukhanka unless you strip it** — its **deformation** systems are `[WorldSystemFilter(Default)]` (⊇ ServerSimulation). **`ServerStripAnimationSystem`** (server-only one-shot) disables every `Rukhanka.Runtime` system on the server (group-disable cascades; matched by assembly name → no type ref). *Only Play-validation caught this.*
- **Build the controller via the `AnimatorController` API** (`manage_animation` drops enum/Vector blend-tree fields). **Skeleton-root = walk up from a bone to the soldier's direct child**, NOT `SkinnedMeshRenderer.rootBone` (the *bounds* root — head SMR's is `Spine_03` → destroys the lower skeleton).
- **The rig pipeline is HUMANOID** (muscle clips retarget onto player + monster rigs; the old "Generic" note was WRONG). **Blender clips:** per-action FBX (Key All Bones + Force Start/End + FBX Units Scale; **5.1: +NLA-strips OFF or ZERO takes bake, silently**); import `CreateFromThisModel` (**CopyFromOther FAILS on Blender's extra `Armature` node**); bake root motion into pose. Optimize Game Objects **OFF**; root motion **OFF** (CC owns the transform).
- **★ Skinned ATTACHMENTS onto an existing rig (07-16 suit-kit recipe):** Blender rigid-skin (vgroup w=1 + armature modifier; **UNHIDE the armature before selection-export or the FBX is silently skinless**) → `PlayerRigTools.GraftSmr` REBASES on rebind (verts→rest-world; bindposes = inverse of **rigid scale-stripped** rest matrices — a Blender roundtrip imports cm bones/0.01 armature, raw bindpose reuse explodes ×100; **`RecalculateTangents()` or Rukhanka/BRG registration fails and the whole rig vanishes**). Hand-written deformation shaders: DOTS-instanced `_DeformedMeshIndex` block **BEFORE** the `ComputeDeformedVertex.hlsl` include + the property ALSO in the Properties block (the baker validates `HasProperty`). [[DR-052_SoD_Facing_Underwater_Feel]].
- **Skinned attachments (graft/rebase/bindpose) + the HUMANOID clip pipeline (Blender per-action FBX rules) → archive 2026-08-07** (long-form; also in the `/art-dev` cookbook). Rig type IS Humanoid; root motion OFF; Optimize Game Objects OFF.
- **ENEMIES reuse the player pipeline** — a Husk = ownerless interpolated ghost = a remote player, so `EnemyAnimationDriveSystem` mirrors the REMOTE path (`LocalTransform` delta velocity + prevPos cache; `IsAttacking = AttackWindup != 0`). **Drop `[RequireMatchingQueriesForUpdate]`** so the prune runs every frame (else a cache entry leaks per kill). Build enemy prefabs via **`EnemyRigTools`**, GUID-preserving (`DeleteAsset+CopyAsset` orphans subscene refs); `WaveSystem` uses `baked.WithPosition` (not `FromPosition` → Scale reset). See [[DR-023_Enemy_Animation_MonsterMash]].
### MCP / editor workflow ★
@@ -137,7 +136,7 @@ Full rationale: [[DR-022_Animation_Pipeline_Rukhanka_Synty]] · [[DR-023_Enemy_A
- `ProjectM.Simulation.GameBootstrap : ClientServerBootstrap` overrides `Initialize` with `AutoConnectPort = 0` (M4 — listen/connect is explicit via the `ConnectionConfig` singleton + per-world ConnectionControlSystems). **Editor default = instant-into-game + MPPM** (creates `ServerWorld` (`WorldFlags.GameServer`) + `ClientWorld` (`WorldFlags.GameClient`)); the `ProjectM/Boot Into Menu (Editor)` EditorPref flips the MAIN editor to the frontend path. **Player builds boot the UITK frontend menu** (`return false` → one menu world, no netcode worlds until a menu choice). See [[DR-019_Frontend_Menu_Settings_Saves_Build]].
- **Scenes (the DR-051 contract — exactly these four):** `MainMenu.unity` (build 0, UITK frontend) · `Game.unity` (build 1, the seabed arena; subscene `Gameplay.unity`) · `DevSandbox.unity` (renamed from Gym; dev tooling + subscene `GymSub.unity`; the `DebugOverlay`/F1-F2 dev scripts gate on this scene NAME) · `ArtStaging.unity` (art viewing, no player; the look's source of truth). All share the LANTERN look (see World bullet). The on-demand lifecycle (`WorldLauncher`/`SessionRunner`/`MainMenuController`) creates the right worlds per menu choice (Single/Host/Join), THEN `LoadScene(Game)` (subscene-streaming rule above).
- **Direction = LANTERN ★ — pivot LOCKED 2026-07-13 ([[DR-048_Lantern_Adoption_Full_Pivot]]).** Co-op action-RPG, *light is territory* (seed-pinned pocket-graph; SoD manual-aim skillshots; suit-frames + Sparks + wild mutations). Supersedes the Awakening-Engine fiction + the Co-op Hades iteration. Operative roadmap [[Roadmap_Lantern_Slice]]; **existing code (combat feel, ability/boon plumbing, run/hub lifecycle, save, regions/relevancy) is QUARRY, not foundation** — keep/rework/mothball per [[Lantern_Strip_Mothball_Inventory]]. **No world code until the ★review-first world-model spike ([[Lantern_World_Model_Spike]]) passes its design review.** The prior co-op-Hades core-loop (ready-check multi-room RUNS; `RunDirectorSystem`/`BossState`; DR-044/045/046) is salvage — invariants archived 07-13 in the gotchas archive. ★ **general gotcha kept: a serialized prefab bool ignores the C# initializer — flip the value in the prefab.**
- **Direction = LANTERN ★ — pivot LOCKED 2026-07-13 ([[DR-048_Lantern_Adoption_Full_Pivot]]).** Co-op action-RPG, *light is territory* (seed-pinned pocket-graph; SoD manual-aim skillshots; suit-frames + Sparks + wild mutations). Supersedes the Awakening-Engine fiction + the Co-op Hades iteration. Operative roadmap [[Roadmap_Lantern_Slice]]; **existing code (combat feel, ability/boon plumbing, run/hub lifecycle, save, regions/relevancy) is QUARRY, not foundation** — keep/rework/mothball per [[Lantern_Strip_Mothball_Inventory]]. World-model review **PASSED** 2026-07-13 ([[DR-049_Lantern_World_Model_Design]] `accepted`) → build against [[World_Model_Build_Spec]]; **re-anchor it first** (its step 1 assumes SaveData `MinLoadableVersion` < 7, which DR-051 already shipped, and its RegionTag→PocketTag line anchors have moved). **★ The engine fork ([[DR-053_Engine_Fork_Bevy_Parked]]) is open — surface it before starting world code.** The prior co-op-Hades core-loop was DELETED 2026-08-07 (audit H1), not mothballed; git is the archive. ★ **general gotcha kept: a serialized prefab bool ignores the C# initializer — flip the value in the prefab.**
## DOTS / ECS conventions (authoritative summary)
@@ -173,4 +172,4 @@ Full protocol + per-layer detail: [[Documentation_Protocol]] (`Docs/Vault/_Meta/
## Per-machine setup (NOT in git — redo on each machine)
`.mcp.json` is committed + portable (`${CLAUDE_PROJECT_DIR}`); the **`dots-dev` skill travels with the repo** (`.claude/skills/dots-dev/`). Each machine still needs: (1) `uv`/`uvx` + Obsidian app + `obsidian-cli` (machine-local, don't sync); (2) basic-memory registration — `uvx basic-memory project add gamevault "<repo>/Docs/Vault" --default` then `uvx basic-memory reindex --full --search --embeddings --project gamevault`; (3) Unity 6.5 open + the Unity-MCP bridge connected (`mcpforunity://editor/state``ready_for_tools`).
`.mcp.json` is committed (one server: `basic-memory`); the **`dots-dev` + `art-dev` skills travel with the repo** (`.claude/skills/dots-dev/`). Each machine still needs: (1) `uv`/`uvx` + Obsidian app + `obsidian-cli` (machine-local, don't sync); (2) basic-memory registration — `uvx basic-memory project add gamevault "<repo>/Docs/Vault" --default` then `uvx basic-memory reindex --full --search --embeddings --project gamevault`; (3) Unity 6.5 open + the Unity-MCP bridge connected (`mcpforunity://editor/state``ready_for_tools`); (4) **Blender 5.1 + the blendermcp addon** (socket 9876) — the committed `/art-dev` skill hard-requires it; (5) **`npx ctx7`** available (+ `CONTEXT7_API_KEY` for higher limits).
+6 -4
View File
@@ -2,7 +2,7 @@
tags:
- moc
- home
updated: 2026-07-13
updated: 2026-08-07
permalink: gamevault/00-home/home
---
@@ -13,15 +13,17 @@ Multiplayer game on **Unity DOTS** (Entities) + **Netcode for Entities** (server
> **Current direction: LANTERN** (locked 2026-07-13, [[DR-048_Lantern_Adoption_Full_Pivot]]) — a co-op
> action-RPG where **your territory is light**: what you light stays, what stays dark rerolls. SoD-grade
> skillshot combat + modular Spark kits + a seed-pinned pocket-graph world. Design: [[Identity_Lantern]];
> roadmap: [[Roadmap_Lantern_Slice]]. Prior directions (Awakening Engine, Co-op Hades) are kept as history.
> roadmap: [[Roadmap_Lantern_Slice]]. Prior directions (Awakening Engine, Co-op Hades) are kept as history — their CODE was deleted 2026-08-07
> ([[DR-054_Audit_Purge_2026-08]]); git is the archive. The engine fork is parked, not adopted
> ([[DR-053_Engine_Fork_Bevy_Parked]]).
## Map of Content
- **Vision** → [[Pillars]] — design pillars & locked decisions · [[Identity_Lantern]] — the fiction (light-as-territory abyssal co-op) · [[Art_Direction_Lantern]] — style bible & material decision · [[Theme_Direction_Candidates]] — the exploration behind the pivot
- **Game Design** → [[Systems_Index]] — per-system design docs
- **Roadmap** → **[[Roadmap_Lantern_Slice]]** (operative) · [[Lantern_Strip_Mothball_Inventory]] (salvage map) · [[Lantern_World_Model_Spike]] (★review-first) · [[Backlog]] / [[Path_to_Fun]] / [[Milestones]] / [[Iteration_2026-07_CoopHades]] (history).
- **Sessions** → `07_Sessions/2026/` — dated work logs (latest: [[2026-07-13_Lantern_Phase0_Design_Pass_B]] · [[2026-07-13_Lantern_Phase0_Adoption_Pivot]])
- **Decisions** → `07_Sessions/_Decisions/` — decision records DR-001 … DR-050 · [[DR-001_Netcode_Test_Harness]] · latest [[DR-050_Lantern_Phase1_Combat_Design]] (Phase 1 combat, review-hardened) · [[DR-049_Lantern_World_Model_Design]] · [[DR-048_Lantern_Adoption_Full_Pivot]]
- **Sessions** → `07_Sessions/2026/` — dated work logs (latest: [[2026-08-07_Audit_Remediation]])
- **Decisions** → `07_Sessions/_Decisions/` — decision records DR-001 … DR-054 · latest [[DR-054_Audit_Purge_2026-08]] (the base/expedition shell deleted) · [[DR-053_Engine_Fork_Bevy_Parked]] · [[DR-052_SoD_Facing_Underwater_Feel]] · [[DR-051_Lantern_Realignment_Purge]] · [[DR-048_Lantern_Adoption_Full_Pivot]]. Superseded DRs now carry `status: superseded` + `superseded_by`.
- **Meta** → [[Documentation_Protocol]] · [[Tags]]
- **Templates** → [[Session_Log_Template]] · [[Decision_Record_Template]]
+7
View File
@@ -7,6 +7,13 @@ updated: 2026-05-29
permalink: gamevault/01-vision/pillars
---
> [!warning] **AUDIT NOTE 2026-08-07 — parts of this page are stale and self-contradictory.**
> The 2026-08-06 audit found: the automation/persistent-base claims and the turret pillar describe a
> direction deleted by [[DR-051_Lantern_Realignment_Purge]] and [[DR-054_Audit_Purge_2026-08]]; and the
> page locks **soft auto-target in-arc** in one place and **soft auto-target CUT** in another. The CUT lock
> is the current one ([[DR-052_SoD_Facing_Underwater_Feel]] — manual aim is the SoD pillar). Treat
> [[Identity_Lantern]] as the live design and this page as pillars-plus-history until it is rewritten.
# Design Pillars & Locked Decisions
> The few non-negotiables every system must serve. Keep this short; promote only decisions that are truly locked.
@@ -6,6 +6,12 @@ updated: 2026-06-08
permalink: gamevault/02-game-design/systems-index
---
> [!warning] **AUDIT NOTE 2026-08-07 — this index is NOT the accurate map of current code.**
> Last genuinely updated 2026-06-08. Since then DR-051 and [[DR-054_Audit_Purge_2026-08]] deleted the M7
> automation chain, the run/room lifecycle, meta shop, boons, build/structures, storage,
> inventory/equipment, the enemy variants and the boss; and the LANTERN socket/Spark/relevancy systems it
> never mentions are the live combat model. **Read the code, or [[DR-054_Audit_Purge_2026-08]], not this.**
# Systems Design — Index
> [!info] LANTERN pivot (2026-07-13, [[DR-048_Lantern_Adoption_Full_Pivot]]).
@@ -0,0 +1,90 @@
# 2026-08-07 — Full-stack audit + remediation
**The ask** (operator): *"Do a comprehensive audit of the current state of the project at multiple layers… then
produce a concise report… Be unbiased, concise, and above all accurate. Don't make assumptions if you can verify."*
Then: *"Go through and fix ALL issues… Be complete and thorough."*
## The audit
8 parallel dimension auditors (code, netcode, tests, docs, process, design, art, infra), each adversarially
re-verified by an independent agent — 16 agents, 0 errors — plus my own live Play-mode verification across all three
player-facing scenes. **46 findings**: 1 critical, 6 high, 20 medium, 19 low. Report + full evidence:
`scratchpad/AUDIT_2026-08-06.md`, published as an artifact.
**The headline, found by playing the game rather than reading it:** the LANTERN pivot (locked 07-13) had reached the
design docs and combat internals and almost nothing a player touches.
- `MainMenu` said **"PROJECT M — Frontier colony — co-op"** (the Awakening-Engine tagline, two directions stale) with
Warrior/Ranger buttons and a "Replay Tutorial" button arming a system DR-051 deleted.
- `Game.unity` was the co-op-Hades expedition game: AT BASE, meta shop, prep loadout, `Tab BUILD`.
- **All four ability sockets in the shipping scene read `Damage=0 Range=0 Cooldown=0`** — the 5 Sparks were in
`GymSub.unity` and never in `Gameplay.unity`. Melee and dash were the only working verbs in the built game.
- Expedition rooms scattered **47 Synty desert props** (cacti, tumbleweeds) into the seabed murk.
- Enemy variety was **structurally inert** — Charger/Spitter/Swarmer authoring on ZERO prefabs, so ~272 lines of
Bursted AI, `BossAISystem` and the whole escalation curve could never match a chunk, while 734 lines of green
tests certified them.
## Three things I got wrong and corrected
Worth recording, because the pattern (verify, don't trust the report) is the point.
1. **"Server runs at 120 Hz"** — my own first measurement. It was a `NetworkTick.SerializedData` validity-bit
artifact (the field advances by 2 per tick). Real rate: **60.0**. Caught before it reached the report.
2. **"10 test files leak ECS Worlds"** — an agent finding, from counting `.Dispose()` tokens, which misses
`using (world)`. Measured empirically: `World.All` is 6 before the suite and 6 after. **Refuted.**
3. **"gitea lacks the LFS locking API, so backup completeness is unproven"** — the remote reports locking support;
`git lfs push --dry-run` returns **0 pending objects**. The 8.3 GB backup is genuinely complete. **Refuted.**
## Remediation — 8 commits, all green
| Batch | What |
|---|---|
| B0 | PAT stripped from `.git/config`; `lfs.allowincompletepush` unset; `*.glb`/`*.gltf`→LFS; deny-list widened to `git restore`/`checkout --`/`stash`; `settings.local.json` cleaned; pushed gitea; **LFS completeness proven** |
| B2+B3 | **~140 files deleted** — run FSM, meta shop, prep, boons, build/structures, storage, inventory/equipment, route/portal, ready-check, enemy variants, boss. Scripts 335→233, Tests 77→47 |
| B4 | 5 Sparks into `Gameplay.unity`; 6 orphaned authoring objects + `RoomDressing` removed; 4 dead prefabs; **Warrior/Ranger → Bathynaut/Harpooner** (93 sites, byte values pinned); menu re-titled LANTERN |
| B1 | Two systems timing INTERPOLATED ghosts on the PREDICTED tick, fixed; **terminal RPC reaper** + 3 regression tests; `Simulate` filter made unconditional |
| B5 | Tuning-invariant tests (knob round-trip, reserved indices, melee coupling); `ProjectM.Authoring` reachable from tests |
| B6 | `EmissiveGloam` DOTS instancing + DepthOnly pass; `EnemyRigTools` revived; 19 dead materials |
| B7 | **Assets 14 GB → 5.5 GB** — BefourStudios (4 reachable files of 8.2 GB), 92 vendor demo scenes, toon-shader pkg, Screenshots out of `Assets/`; MCP package pinned to a SHA |
| B8 | CLAUDE.md truth pass (back under its own budget); DR-053/054; 13 DRs re-statused; Home/Pillars/Systems_Index |
**304/304 EditMode green, 0 compile errors**, `Game.unity` plays with live socket stats and no leaked RPCs.
## Verified live, not inferred
- Ability sockets after the fix: Vortex 8dmg/6range/420cd · Blink 20range/1cd · Hook&Pull 15/25/120 · Light Zone 6/5/480.
- RPC leak reproduced *before* the fix (one `ReadyToggleRequest` in DevSandbox → pending count 0→1 permanently, with
the exact `MaxRpcAgeFrames` warning), and the reaper proven *after* (planted unconsumed request gone in frames).
- Server 59.6 ticks/s against 60 Hz; the tick-batching warnings are transient at subscene stream, not standing.
## New gotchas banked
- **A socket whose SparkId is missing from the baked `AbilityDatabase` silently reads Damage/Range/Cooldown 0.** No
error, no warning — the HUD even renders the slot as ready. Every gameplay subscene needs the full Spark set.
- **Netcode's stale-RPC warning `Consume()`s but never destroys, and is `#if UNITY_EDITOR`-gated** — so an unhandled
RPC is a *permanent entity leak*, and it is worst in a player build where the warning does not exist.
- **`script_apply_edits` multi-line regex anchors do not match reliably**, and its structured router can silently
truncate a line-range replacement. Single-line anchors are solid; for multi-line spans use `apply_text_edits` with
`precondition_sha256` and re-read the result. Twice today a "successful" edit left the file half-changed.
- **Removing `com.unity.ai.assistant`/`ai.inference` from the manifest crashed two AssetImportWorkers** (half the AI
Toolkit stays resolved in `Library/PackageCache`). Restored; not worth it for editor-only tooling.
## Still open — needs the operator
1. **Revoke the PAT** at github.com/settings/tokens. I removed it from the remote URL; revocation is the step that
actually matters, and only you can do it.
2. **A0 style-proof sign-off** (~20 min in ArtStaging: flicker-cadence, and "this game and no other game").
3. **Phase-1 fun gate** — now actually runnable: the kit works in the shipping scene for the first time.
4. **GitHub mirror** is 235 commits / 8 weeks stale. Before pushing, check that repo's visibility — it tracks
licensed Synty/Rukhanka content.
5. **Art decisions I deliberately did not make**: `MakeMat`'s per-pack Synty atlas vs the A0 palette keystone; the
poly budget (Player 10,178 tris vs 6k, Grindylow 4,330 vs 3k); stripping the 16-19 disabled Synty SMRs per
character prefab. All three change how things look — your call, not a mechanical fix.
**Next:** [[World_Model_Build_Spec]] steps 1-5 (re-anchor first — its step 1 assumes a SaveData version DR-051
already shipped past, and its RegionTag→PocketTag line anchors have moved).
## Related
[[DR-054_Audit_Purge_2026-08]] · [[DR-053_Engine_Fork_Bevy_Parked]] · [[Roadmap_Lantern_Slice]] ·
[[CLAUDE_Build_Gotchas_Archive]]
@@ -1,7 +1,8 @@
---
id: DR-014
title: M6 Stage 3/4 — generic build/structure foundation (automation-ready) + turret + ability tiers + goal; persistence deferred
status: accepted
status: superseded
superseded_by: DR-054
date: 2026-06-03
tags:
- decision
@@ -1,7 +1,8 @@
---
id: DR-015
title: The Awakening Engine — fiction reconciliation (Aether unifier + Sleeper/Echo/THEM spine), skin-only
status: accepted
status: superseded
superseded_by: DR-048
date: 2026-06-03
tags:
- decision
@@ -1,7 +1,8 @@
---
id: DR-020
title: M7 Automation — server-only deterministic production chains (Harvester → Conveyor → Fabricator) + SaveData v2 structure persistence
status: accepted
status: superseded
superseded_by: DR-051
date: 2026-06-05
tags:
- decision
@@ -1,7 +1,8 @@
---
id: DR-026
title: Inventory · Equipment · Progression foundation — data-driven ItemDatabase catalog + per-player replicated inventory, gear-tier progression, weapon-granted abilities (Phase 0 backbone)
status: accepted
status: superseded
superseded_by: DR-054
date: 2026-06-08
tags:
- decision
@@ -128,8 +129,8 @@ the HUD panel rendered the 4 carried items with names from the catalog — inclu
## Links
[[DR-004_Data_Driven_Abilities_Modifiers]] (StatModifier machinery reused for equipment) ·
[[DR-008_M5_HomeBase_BaseLayer]] (StorageEntry / RPC storage pattern) ·
[[DR-004_M3_DataDriven_Abilities_Modifiers]] (StatModifier machinery reused for equipment) ·
[[DR-008_M5_HomeBase_BaseLayer_Storage]] (StorageEntry / RPC storage pattern) ·
[[DR-014_M6_Build_Structures_Automation_Foundation]] (data-driven catalog pattern) ·
[[DR-018_World_Space_Cohesion_Pass]] (harvest sweep this reroutes) ·
[[DR-020_M7_Automation_Production_Chains]] (server-only economy, Fabricator) ·
@@ -1,7 +1,8 @@
---
id: DR-027
title: Equipment slots (Phase 1) — weapon-granted swappable abilities + gear stat mods via the existing AbilityRef/StatModifier machinery, event-driven server-only equip
status: accepted
status: superseded
superseded_by: DR-054
date: 2026-06-08
tags:
- decision
@@ -94,5 +95,5 @@ click-wires equippable rows. Shippable.
## Links
[[DR-026_Inventory_Equipment_Progression_Foundation]] (Phase 0) · [[DR-004_Data_Driven_Abilities_Modifiers]]
[[DR-026_Inventory_Equipment_Progression_Foundation]] (Phase 0) · [[DR-004_M3_DataDriven_Abilities_Modifiers]]
(StatModifier) · [[DR-016_Stage_G_Combat_Gameplay]] (TimedModifier strip helper reused).
@@ -1,7 +1,8 @@
---
id: DR-034
title: END-1 — a losable Engine Core (soft-loss base-integrity meter)
status: accepted
status: superseded
superseded_by: DR-051
date: 2026-06-12
tags:
- decision
@@ -1,7 +1,8 @@
---
id: DR-036
title: END-2 — the final siege + a latching win/lose (SL-3)
status: accepted
status: superseded
superseded_by: DR-051
date: 2026-06-13
tags:
- decision
@@ -1,7 +1,8 @@
---
id: DR-037
title: Procedural Expedition Spine + Two Classes + Persistent Meta (Mission-as-Sortie redirect)
status: accepted
status: superseded
superseded_by: DR-048
date: 2026-06-17
tags:
- decision
@@ -1,7 +1,8 @@
---
id: DR-042
title: Game-Loop Re-shape — Expedition-Driven Progression (retire the base-siege win)
status: accepted
status: superseded
superseded_by: DR-048
date: 2026-06-24
tags:
- decision
@@ -1,7 +1,8 @@
---
id: DR-043
title: First-Run Onboarding — contextual coach-marks + replayable How-to-Play card
status: accepted
status: superseded
superseded_by: DR-051
date: 2026-06-28
tags:
- decision
@@ -2,7 +2,8 @@
id: DR-044
title: Expedition Redesign SHIPPED (steps 114) + Demo-Readiness Polish Pass
date: 2026-07-04
status: locked
status: superseded
superseded_by: DR-048
tags:
- decision
- expedition
@@ -2,7 +2,8 @@
id: DR-045
title: Combat Demo-Readiness Pass — Real Boss Fight, Readable-but-Fair Threat, 2-Run Demo
date: 2026-07-04
status: locked
status: superseded
superseded_by: DR-048
tags:
- decision
- combat
@@ -2,7 +2,8 @@
id: DR-046
title: Base↔Expedition Ties — Portal-Gated Rooms, Class-at-Base, Per-Run Prep Spend
date: 2026-07-04
status: locked
status: superseded
superseded_by: DR-048
tags:
- decision
- combat
@@ -0,0 +1,64 @@
---
title: DR-053 — The engine fork (Bevy) is PARKED, not adopted; Unity stays the direction
date: 2026-08-07
status: accepted
tags: [decision, engine, bevy, unity, direction, lantern]
---
# DR-053 — Engine fork: PARKED
## Context
Between 2026-07-26 and 07-28 the project produced [[Lantern_Bevy_Greenfield_Guide]] — a 357-line architecture map
for rebuilding LANTERN on Rust/Bevy/Avian/lightyear. Then nothing was committed for nine days. The 2026-08-06 audit
found the reason this mattered was not the fork itself but where it lived:
- `grep -ril bevy Docs/Vault` returned **exactly one file — the guide itself**. Zero inbound wikilinks. No mention
in CLAUDE.md, the roadmap, any DR, or any session log.
- The gating instruction ("surface this BEFORE any Unity world code") existed **only in machine-local
`memory/MEMORY.md`**, which CLAUDE.md explicitly forbids as the sole home of a decision: *"durable truth → the
vault or this file (both committed); native `memory/` is local-only."*
- The last three commits had no session log either, breaking the protocol's bookend rule.
So the single most consequential open question in the project was unreachable from any committed authority doc. On
a second machine, or after a memory reset, Phase-2 world code would have started without the fork ever being raised.
## Decision
**Unity remains the direction. The Bevy fork is PARKED — recorded, linked, and re-openable — not adopted and not
discarded.** The operator confirmed this on 2026-08-07 ("Unity is the direction") when the audit forced the choice,
which is what unblocked the remediation work.
This DR is the committed home the guide never had. CLAUDE.md's direction bullet now links here.
## Rationale
The audit's diagnosis, kept because it is the part worth re-reading if the fork reopens:
Roughly **half** the friction the guide cites is genuinely Unity-attributable and would really go away —
`NetCodeTestWorld` being internal (so no in-process netcode tests), system-ordering cycles that are invisible to
EditMode tests and only throw at Play world-creation, Burst ICEs corrupting the incremental cache, and Rukhanka
exposing no runtime bone transforms (so attachments are rigid-skinned vertex surgery).
The **other half** — two operator gates open three weeks, three direction pivots in nine weeks, no CI, no player
build in two months — is process and bandwidth. It travels with you. The guide itself rates *"no editor for the
operator — eyes-on art/feel loop degrades"* as **High**, and that is precisely the loop the two open gates need.
The guide's risk ledger also omits the project's own base rate of direction change, which is the largest single
cost driver in its history.
## Consequences
- The guide stays as a **spike reference**, not a plan. Its `status` line already says so; it is now reachable.
- **If the fork reopens, the entry condition is: close the two open Unity gates first** (A0 style-proof sign-off,
Phase-1 fun gate). Otherwise the comparison is against a Unity build nobody has judged.
- Four remediation items were deliberately *not* deferred on fork grounds because they are cheap and correct either
way: the `EmissiveGloam` DOTS pragmas, the `EnemyRigTools` repair, the dead-material sweep, the vendor-pack
reclaim. Anything larger and Unity-specific (a palette-keystone migration, a decimate pass) waits.
- §1 of the guide — the tuning tables, the rollback/tick/swept-hit/one-press rules — is engine-agnostic and is the
most expensive-to-rediscover thing the project owns. It should be maintained regardless.
## Related
[[Lantern_Bevy_Greenfield_Guide]] · [[DR-048_Lantern_Adoption_Full_Pivot]] · [[DR-054_Audit_Purge_2026-08]] ·
[[Roadmap_Lantern_Slice]] · [[World_Model_Build_Spec]]
@@ -0,0 +1,70 @@
---
title: DR-054 — Delete the superseded base/expedition shell (2026-08 audit remediation)
date: 2026-08-07
status: accepted
tags: [decision, purge, lantern, audit, direction]
---
# DR-054 — The audit purge: delete rather than freeze
## Context
The 2026-08-06 full-stack audit (8 dimensions, adversarially verified, plus live Play-mode verification) found that
the LANTERN pivot — locked 2026-07-13 — had reached the design docs and the combat internals and **almost nothing a
player touches**:
- `Game.unity` (build index 1) was still the co-op-Hades expedition game: *AT BASE — build defenses, buy upgrades,
READY UP to launch*, a meta shop, a prep loadout, `Tab BUILD`, Warrior/Ranger.
- The menu said **"PROJECT M — Frontier colony — co-op"**: the Awakening-Engine tagline, two directions stale.
- **All four ability sockets in the shipping scene were dead** — live server read: `Damage=0 Range=0 Cooldown=0`.
The 5 LANTERN Sparks had been added to `GymSub.unity` and never to `Gameplay.unity`. Melee and dash were the only
working combat verbs in the built game.
- Enemy variety was **structurally inert**: Charger/Spitter/Swarmer authoring was on ZERO prefabs, so ~272 lines of
Bursted AI, `BossAISystem`, and the whole wave-escalation curve could not match a chunk — while 734 lines of green
tests certified them.
- ~8,300 of 33,100 runtime lines were live code for the abandoned direction; 143 of 335 files were untouched since
the pivot.
## Decision
Operator call, 2026-08-07: **"Delete/Remove as well — everything is saved in source control if needed. I want the
project to be clean."** Deletion over freezing.
Deleted: the run/room lifecycle FSM, meta shop, prep loadout, boons (including `KillRewardSystem` and
`DashTrailDamageSystem`, which existed only to serve boon flags), build palette + structures, shared storage,
inventory/equipment, route/portal, ready-check, onboarding remnants, the enemy variants and the boss — code,
authoring, HUD panels, subscene objects, prefabs and tests. ~140 source files; Scripts 335→233, Tests 77→47.
## What was deliberately KEPT
Four things sat in the delete set until their consumers were checked, and three of them turned out to be
load-bearing. This is the part worth remembering: **the file-level manifest was wrong about them.**
- **`BaseGridMath` + `BaseAnchor`** — eight surviving systems call `PlotCenter` for spawn rings, respawn and
dynamic light.
- **`StorageEntry` + `StorageMath`** — these *are* the resource ledger, not base-storage.
- **The save system** and **region/relevancy** (becomes PocketTag in Phase 2).
## Consequences
- The shipping scene is now the LANTERN gym: melee + dash + four **working** Sparks in seabed murk, with waves.
There is no run structure — which is exactly what Phase 1 specifies ("no world, no lanterns — a gym").
- `FrameKind` is Bathynaut/Harpooner; `PlayerClass` is gone (audit M5 — it was a second server-only copy of the byte
`FrameId` already replicates, existing only so the meta shop could key on it).
- Save files stay v7-loadable: `SaveData` keeps its structure/meta fields and writes them empty.
- **Retired byte values stay reserved** as always (`StructureType` 1-4, `TuningKnob` 20-23, `DebugOp` 3/10/11) — now
pinned by a test, not just a convention.
- Test count 430 → 304. The drop is honest: 29 test files went with the subsystems they certified, and several of
those were the false-confidence cases the audit named.
## Also fixed in the same pass
RPC leak (a terminal reaper — receivers gated on `RequireForUpdate` never ran in a scene missing the singleton, and
Netcode's own warning consumes but never destroys, and is compiled out of player builds); two systems timing
INTERPOLATED ghosts against the PREDICTED tick; `EmissiveGloam` missing DOTS instancing on a baked ghost;
`EnemyRigTools` dead at every entry point; 8.5 GB of unreachable vendor content.
## Related
[[DR-051_Lantern_Realignment_Purge]] (the first purge) · [[DR-048_Lantern_Adoption_Full_Pivot]] ·
[[DR-053_Engine_Fork_Bevy_Parked]] · [[Lantern_Strip_Mothball_Inventory]] · [[Roadmap_Lantern_Slice]]
@@ -502,3 +502,13 @@ Condensed from CLAUDE.md 07-16; the inline bullets keep the operational core, ve
4. Hand-written Rukhanka deformation shader: `UNITY_DOTS_INSTANCING_START` block with `_DeformedMeshIndex` must precede the `ComputeDeformedVertex.hlsl` include (macro expands at include time; else "undeclared identifier `_DeformedMeshIndex_DOTSInstancingOverrideMode`" in the DOTS_INSTANCING_ON variant = magenta), and `_DeformedMeshIndex` must also exist in the Properties block (SkinnedMeshBaker validates `material.HasProperty`).
5. Synty variant containers hold both genders' heads — graft by exact name, purge wrong-variant children for idempotency.
6. `manage_asset rename` half-failed (moved the asset to `Assets/` root, extensionless, while reporting an error) — verify on disk; plain file copy + `refresh_unity force` is the reliable fallback.
## 2026-08-07 — condensation to pay for the audit-purge edits (CLAUDE.md net-zero rule)
Moved out of CLAUDE.md verbatim to buy budget for the 2026-08-06 audit corrections (world-gate, asmdef table,
per-machine setup, the H2 socket/AbilityDatabase rule). Both are art-pipeline long-form and are also carried by
the `/art-dev` cookbook; CLAUDE.md keeps a one-line pointer.
- **★ Skinned ATTACHMENTS onto an existing rig (07-16 suit-kit recipe):** Blender rigid-skin (vgroup w=1 + armature modifier; **UNHIDE the armature before selection-export or the FBX is silently skinless**) → `PlayerRigTools.GraftSmr` REBASES on rebind (verts→rest-world; bindposes = inverse of **rigid scale-stripped** rest matrices — a Blender roundtrip imports cm bones/0.01 armature, raw bindpose reuse explodes ×100; **`RecalculateTangents()` or Rukhanka/BRG registration fails and the whole rig vanishes**). Hand-written deformation shaders: DOTS-instanced `_DeformedMeshIndex` block **BEFORE** the `ComputeDeformedVertex.hlsl` include + the property ALSO in the Properties block (the baker validates `HasProperty`). [[DR-052_SoD_Facing_Underwater_Feel]].
- **The rig pipeline is HUMANOID** (muscle clips retarget onto player + monster rigs; the old "Generic" note was WRONG). **Blender clips:** per-action FBX (Key All Bones + Force Start/End + FBX Units Scale; **5.1: +NLA-strips OFF or ZERO takes bake, silently**); import `CreateFromThisModel` (**CopyFromOther FAILS on Blender's extra `Armature` node**); bake root motion into pose. Optimize Game Objects **OFF**; root motion **OFF** (CC owns the transform).