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:
@@ -34,12 +34,13 @@ Root namespace: **`ProjectM`**. Code lives under `Assets/_Project/Scripts/` in f
|
|||||||
|
|
||||||
| Assembly | Namespace | Runs in | References |
|
| Assembly | Namespace | Runs in | References |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `ProjectM.Simulation` | `ProjectM.Simulation` | **client + server** worlds | Entities, **Unity.Transforms**, Collections, Mathematics, Burst, Unity.Physics, 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) |
|
| `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 |
|
| `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 |
|
| `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>`.
|
- **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/`.
|
- 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**.
|
- 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.
|
- **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 / 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.
|
- **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.
|
||||||
- **Structures:** only `Type` replicates (client derives `Cell`); **occupancy is DERIVED** from live ghosts, never baked. See [[DR-014_M6_Build_Structures_Automation_Foundation]].
|
- **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).
|
||||||
- **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) — **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]].
|
||||||
- **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 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.
|
||||||
- **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` (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]].
|
||||||
- **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]].
|
|
||||||
|
|
||||||
### Presentation / juice / VFX
|
### 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`**.
|
- **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]].
|
- **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)
|
### 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.
|
- **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).
|
- **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.
|
- **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).
|
- **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.*
|
- **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).
|
- **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 (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.
|
||||||
- **★ 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]].
|
|
||||||
- **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]].
|
- **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 ★
|
### 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]].
|
- `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).
|
- **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)
|
## 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)
|
## 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).
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
tags:
|
tags:
|
||||||
- moc
|
- moc
|
||||||
- home
|
- home
|
||||||
updated: 2026-07-13
|
updated: 2026-08-07
|
||||||
permalink: gamevault/00-home/home
|
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
|
> **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
|
> 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]];
|
> 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
|
## 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
|
- **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
|
- **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).
|
- **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]])
|
- **Sessions** → `07_Sessions/2026/` — dated work logs (latest: [[2026-08-07_Audit_Remediation]])
|
||||||
- **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]]
|
- **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]]
|
- **Meta** → [[Documentation_Protocol]] · [[Tags]]
|
||||||
- **Templates** → [[Session_Log_Template]] · [[Decision_Record_Template]]
|
- **Templates** → [[Session_Log_Template]] · [[Decision_Record_Template]]
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ updated: 2026-05-29
|
|||||||
permalink: gamevault/01-vision/pillars
|
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
|
# Design Pillars & Locked Decisions
|
||||||
|
|
||||||
> The few non-negotiables every system must serve. Keep this short; promote only decisions that are truly locked.
|
> 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
|
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
|
# Systems Design — Index
|
||||||
|
|
||||||
> [!info] LANTERN pivot (2026-07-13, [[DR-048_Lantern_Adoption_Full_Pivot]]).
|
> [!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]]
|
||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-014
|
id: DR-014
|
||||||
title: M6 Stage 3/4 — generic build/structure foundation (automation-ready) + turret + ability tiers + goal; persistence deferred
|
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
|
date: 2026-06-03
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-015
|
id: DR-015
|
||||||
title: The Awakening Engine — fiction reconciliation (Aether unifier + Sleeper/Echo/THEM spine), skin-only
|
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
|
date: 2026-06-03
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-020
|
id: DR-020
|
||||||
title: M7 Automation — server-only deterministic production chains (Harvester → Conveyor → Fabricator) + SaveData v2 structure persistence
|
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
|
date: 2026-06-05
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
+4
-3
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-026
|
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)
|
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
|
date: 2026-06-08
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
@@ -128,8 +129,8 @@ the HUD panel rendered the 4 carried items with names from the catalog — inclu
|
|||||||
|
|
||||||
## Links
|
## Links
|
||||||
|
|
||||||
[[DR-004_Data_Driven_Abilities_Modifiers]] (StatModifier machinery reused for equipment) ·
|
[[DR-004_M3_DataDriven_Abilities_Modifiers]] (StatModifier machinery reused for equipment) ·
|
||||||
[[DR-008_M5_HomeBase_BaseLayer]] (StorageEntry / RPC storage pattern) ·
|
[[DR-008_M5_HomeBase_BaseLayer_Storage]] (StorageEntry / RPC storage pattern) ·
|
||||||
[[DR-014_M6_Build_Structures_Automation_Foundation]] (data-driven catalog pattern) ·
|
[[DR-014_M6_Build_Structures_Automation_Foundation]] (data-driven catalog pattern) ·
|
||||||
[[DR-018_World_Space_Cohesion_Pass]] (harvest sweep this reroutes) ·
|
[[DR-018_World_Space_Cohesion_Pass]] (harvest sweep this reroutes) ·
|
||||||
[[DR-020_M7_Automation_Production_Chains]] (server-only economy, Fabricator) ·
|
[[DR-020_M7_Automation_Production_Chains]] (server-only economy, Fabricator) ·
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-027
|
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
|
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
|
date: 2026-06-08
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
@@ -94,5 +95,5 @@ click-wires equippable rows. Shippable.
|
|||||||
|
|
||||||
## Links
|
## 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).
|
(StatModifier) · [[DR-016_Stage_G_Combat_Gameplay]] (TimedModifier strip helper reused).
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-034
|
id: DR-034
|
||||||
title: END-1 — a losable Engine Core (soft-loss base-integrity meter)
|
title: END-1 — a losable Engine Core (soft-loss base-integrity meter)
|
||||||
status: accepted
|
status: superseded
|
||||||
|
superseded_by: DR-051
|
||||||
date: 2026-06-12
|
date: 2026-06-12
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-036
|
id: DR-036
|
||||||
title: END-2 — the final siege + a latching win/lose (SL-3)
|
title: END-2 — the final siege + a latching win/lose (SL-3)
|
||||||
status: accepted
|
status: superseded
|
||||||
|
superseded_by: DR-051
|
||||||
date: 2026-06-13
|
date: 2026-06-13
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-037
|
id: DR-037
|
||||||
title: Procedural Expedition Spine + Two Classes + Persistent Meta (Mission-as-Sortie redirect)
|
title: Procedural Expedition Spine + Two Classes + Persistent Meta (Mission-as-Sortie redirect)
|
||||||
status: accepted
|
status: superseded
|
||||||
|
superseded_by: DR-048
|
||||||
date: 2026-06-17
|
date: 2026-06-17
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-042
|
id: DR-042
|
||||||
title: Game-Loop Re-shape — Expedition-Driven Progression (retire the base-siege win)
|
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
|
date: 2026-06-24
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
id: DR-043
|
id: DR-043
|
||||||
title: First-Run Onboarding — contextual coach-marks + replayable How-to-Play card
|
title: First-Run Onboarding — contextual coach-marks + replayable How-to-Play card
|
||||||
status: accepted
|
status: superseded
|
||||||
|
superseded_by: DR-051
|
||||||
date: 2026-06-28
|
date: 2026-06-28
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
id: DR-044
|
id: DR-044
|
||||||
title: Expedition Redesign SHIPPED (steps 1–14) + Demo-Readiness Polish Pass
|
title: Expedition Redesign SHIPPED (steps 1–14) + Demo-Readiness Polish Pass
|
||||||
date: 2026-07-04
|
date: 2026-07-04
|
||||||
status: locked
|
status: superseded
|
||||||
|
superseded_by: DR-048
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
- expedition
|
- expedition
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
id: DR-045
|
id: DR-045
|
||||||
title: Combat Demo-Readiness Pass — Real Boss Fight, Readable-but-Fair Threat, 2-Run Demo
|
title: Combat Demo-Readiness Pass — Real Boss Fight, Readable-but-Fair Threat, 2-Run Demo
|
||||||
date: 2026-07-04
|
date: 2026-07-04
|
||||||
status: locked
|
status: superseded
|
||||||
|
superseded_by: DR-048
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
- combat
|
- combat
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
id: DR-046
|
id: DR-046
|
||||||
title: Base↔Expedition Ties — Portal-Gated Rooms, Class-at-Base, Per-Run Prep Spend
|
title: Base↔Expedition Ties — Portal-Gated Rooms, Class-at-Base, Per-Run Prep Spend
|
||||||
date: 2026-07-04
|
date: 2026-07-04
|
||||||
status: locked
|
status: superseded
|
||||||
|
superseded_by: DR-048
|
||||||
tags:
|
tags:
|
||||||
- decision
|
- decision
|
||||||
- combat
|
- 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`).
|
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.
|
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.
|
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).
|
||||||
|
|||||||
Reference in New Issue
Block a user