Docs: collision-fidelity pass record + MeshCollider Read/Write gotcha + guardian harness pattern
Session log Part C (execution + validation evidence), roadmap stabilize #2 ticked, CLAUDE.md gains the MeshCollider-bakes-only-if-Read/Write gotcha (38.4 KB, in budget), validation-harness.md gains the EditorApplication.update guardian + EditorPrefs handoff pattern. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -63,6 +63,12 @@ DOES propagate into parented children's `LocalToWorld` (verified live on 6.5.0).
|
|||||||
and tears down the room.
|
and tears down the room.
|
||||||
- Therefore: **capture evidence in the SAME `execute_code` call that first detects the condition** (e.g.
|
- Therefore: **capture evidence in the SAME `execute_code` call that first detects the condition** (e.g.
|
||||||
`enemies>0`) — a separate "then screenshot" round-trip loses the window.
|
`enemies>0`) — a separate "then screenshot" round-trip loses the window.
|
||||||
|
- **Multi-sample observations (movement deltas, before/after) that can't fit one call: install an
|
||||||
|
`EditorApplication.update` guardian delegate** (proven 2026-07-09, enemy-backstop smoke). The closure runs every
|
||||||
|
editor frame: it can out-race damage (`Health.Current = Max` per frame — beats the respawn-reset trap above),
|
||||||
|
park the player, take timed snapshots, and stash results in `EditorPrefs` (survives across `execute_code`
|
||||||
|
calls — statics do NOT). Always: wrap the body in try/catch that UNSUBSCRIBES on error, add a hard timeout
|
||||||
|
unsubscribe (~90 s), self-unsubscribe when done, and delete the `EditorPrefs` keys after reading them.
|
||||||
- Prefer the server-inject harness above whenever the question doesn't actually require a live run.
|
- Prefer the server-inject harness above whenever the question doesn't actually require a live run.
|
||||||
|
|
||||||
## Visual/asset verification limits
|
## Visual/asset verification limits
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ Long-form originals + the milestone each came from: `Docs/Vault/_Meta/CLAUDE_Bui
|
|||||||
- **Frontend world lifecycle (menu → on-demand worlds) ★:** use `CreateClientWorld`/`CreateServerWorld` (they register the `ServerWorld`/`ClientWorld` statics the UI reads; `CreateLocalWorld` was internal pre-6.5, PUBLIC on 6.5.0); menu world via `DefaultWorldInitialization.Initialize(name, false)`. **Never dispose/create worlds inside an ECS system** — do it on a frame-boundary coroutine (`SessionRunner`, `DontDestroyOnLoad`). The gameplay subscene streams in ONLY if a netcode world is the `DefaultGameObjectInjectionWorld` at `LoadScene` time. See [[DR-019_Frontend_Menu_Settings_Saves_Build]].
|
- **Frontend world lifecycle (menu → on-demand worlds) ★:** use `CreateClientWorld`/`CreateServerWorld` (they register the `ServerWorld`/`ClientWorld` statics the UI reads; `CreateLocalWorld` was internal pre-6.5, PUBLIC on 6.5.0); menu world via `DefaultWorldInitialization.Initialize(name, false)`. **Never dispose/create worlds inside an ECS system** — do it on a frame-boundary coroutine (`SessionRunner`, `DontDestroyOnLoad`). The gameplay subscene streams in ONLY if a netcode world is the `DefaultGameObjectInjectionWorld` at `LoadScene` time. See [[DR-019_Frontend_Menu_Settings_Saves_Build]].
|
||||||
|
|
||||||
### Physics & character controller
|
### Physics & character controller
|
||||||
- **Unity Physics 1.x bakes built-in `UnityEngine` colliders + `Rigidbody`** (the Physics-0.x `PhysicsShapeAuthoring`/`PhysicsBodyAuthoring` are gone). Static collider (no Rigidbody) → baked into the subscene PhysicsWorld, deterministic, no replication. `Rigidbody.FreezeRotation` is **NOT** honored by the baker — zero angular velocity + write rotation each tick, or set `PhysicsMass.InverseInertia = float3.zero`.
|
- **Unity Physics 1.x bakes built-in `UnityEngine` colliders + `Rigidbody`** (the Physics-0.x `PhysicsShapeAuthoring`/`PhysicsBodyAuthoring` are gone). Static collider (no Rigidbody) → baked into the subscene PhysicsWorld, deterministic, no replication. `Rigidbody.FreezeRotation` is **NOT** honored by the baker — zero angular velocity + write rotation each tick, or set `PhysicsMass.InverseInertia = float3.zero`. **A `MeshCollider` bakes ONLY if the mesh has Read/Write enabled** — else `InvalidOperationException` per bake and NO baked shape (classic scene view still shows the collider; only a baked-`CollisionWorld` probe catches it); flip the ModelImporter `isReadable`. Env-collider fidelity is tool-driven: `ColliderFitTools` (audit/apply) refits subscene walls/cover/landmarks to the Game.unity visuals.
|
||||||
- **The player is a Unity Character Controller kinematic character** (NOT a dynamic Rigidbody; M5's `PlayerMoveSystem`/`PlayerPlanarConstraintSystem` deleted, predicted-physics infra kept). `PlayerControlSystem` maps input → `CharacterControl`; `CharacterProcessor` collide-and-slides in the relocated `KinematicCharacterPhysicsUpdateGroup`. CC 1.4.2 API = `IKinematicCharacterProcessor<T>` + `KinematicCharacterDataAccess` + static `KinematicCharacterUtilities.Update_*` (verify with `unity_reflect`).
|
- **The player is a Unity Character Controller kinematic character** (NOT a dynamic Rigidbody; M5's `PlayerMoveSystem`/`PlayerPlanarConstraintSystem` deleted, predicted-physics infra kept). `PlayerControlSystem` maps input → `CharacterControl`; `CharacterProcessor` collide-and-slides in the relocated `KinematicCharacterPhysicsUpdateGroup`. CC 1.4.2 API = `IKinematicCharacterProcessor<T>` + `KinematicCharacterDataAccess` + static `KinematicCharacterUtilities.Update_*` (verify with `unity_reflect`).
|
||||||
- **`KinematicCharacterUtilities.BakeCharacter` aborts with a `Rigidbody`** and needs uniform (1,1,1) scale. **`CharacterInterpolation` must be PredictedClient-only** (a `DefaultVariantSystemBase` strips it from server + interpolated prefabs) — else double-interp on remotes. **Do NOT copy the CC sample's global `LocalTransform → DontSerializeVariant`** (project-wide; breaks non-character ghosts that rely on stock `LocalTransform` replication).
|
- **`KinematicCharacterUtilities.BakeCharacter` aborts with a `Rigidbody`** and needs uniform (1,1,1) scale. **`CharacterInterpolation` must be PredictedClient-only** (a `DefaultVariantSystemBase` strips it from server + interpolated prefabs) — else double-interp on remotes. **Do NOT copy the CC sample's global `LocalTransform → DontSerializeVariant`** (project-wide; breaks non-character ghosts that rely on stock `LocalTransform` replication).
|
||||||
- **Top-down CC config:** `SnapToGround=false`, `InterpolateRotation=false` (rotation owned by `PlayerAimSystem`), `SimulateDynamicBody=false`; gravity handled by feeding `float3.zero` to `Update_GroundPushing`.
|
- **Top-down CC config:** `SnapToGround=false`, `InterpolateRotation=false` (rotation owned by `PlayerAimSystem`), `SimulateDynamicBody=false`; gravity handled by feeding `float3.zero` to `Update_GroundPushing`.
|
||||||
|
|||||||
@@ -117,12 +117,14 @@ attacks/animations/effects**. Art direction deliberately UNDECIDED — lighting
|
|||||||
`[RuntimeInitializeOnLoadMethod]` attribute** off `WorldFeelConfig.ResetDefaults` → `Enabled=false` → the WHOLE
|
`[RuntimeInitializeOnLoadMethod]` attribute** off `WorldFeelConfig.ResetDefaults` → `Enabled=false` → the WHOLE
|
||||||
feedback slice (shrink/pop + chips + SFX + micro-punch) silently dead. One-line restore; verified on-screen +
|
feedback slice (shrink/pop + chips + SFX + micro-punch) silently dead. One-line restore; verified on-screen +
|
||||||
numerically on a live server-spawned node; 455/455. Operator still eyeballs a real harvest in the next playtest.
|
numerically on a live server-spawned node; 455/455. Operator still eyeballs a real harvest in the next playtest.
|
||||||
2. **Collision precision pass — SCOPED (2026-07-07 operator): environment collider FIDELITY.** Collision shapes
|
2. ~~Collision precision pass~~ **DONE (2026-07-09, gate-approved incl. missing-collider adds).**
|
||||||
don't match the visual meshes (cover rocks etc.) — invisible walls / visual clipping. TODO: audit every
|
`ColliderFitTools` (Editor, audit/apply) refit everything to the Game.unity visuals: rings rebuilt
|
||||||
Environment-layer collider (boundary rim, landmark rocks, in-room cover props) and fit them to the render mesh
|
16/24/24→54/82/82 fine segments fitted to torso-band cliff vertices; cover = convex MeshColliders of the
|
||||||
(tightened primitives or convex mesh colliders); verify against the baked subscene PhysicsWorld (that's where
|
actual rock meshes (needed Read/Write on 2 PNB meshes — new CLAUDE.md gotcha); landmarks hint-matched OBB
|
||||||
they live — classic-GameObject views lie). Re-validate the enemy stuck-fix backstop after any shape change
|
fits; 11 solid-prop colliders added (tree/turbine/crates/dish/solar). Verified in the baked CollisionWorld
|
||||||
(Depenetrate/tangent-slide was tuned on the old shapes).
|
(ring closure, cover 8/8 solid, server==client parity) + enemy backstop re-validated live (embedded enemy
|
||||||
|
depenetrates out of a cover hull and keeps moving). Operator feel-lap still pending. See
|
||||||
|
[[2026-07-09_B4d_Tail_Collision_Grounding]].
|
||||||
|
|
||||||
### Short-term wins (asset/scene/client layer)
|
### Short-term wins (asset/scene/client layer)
|
||||||
|
|
||||||
|
|||||||
@@ -64,11 +64,51 @@ RPC / ordering surface**). Validation ladder: baked `CollisionWorld` raycast sam
|
|||||||
enemy backstop re-validation (spawned Husks near refit cover keep moving — the Depenetrate/tangent-slide
|
enemy backstop re-validation (spawned Husks near refit cover keep moving — the Depenetrate/tangent-slide
|
||||||
was tuned on the OLD shapes) · suite + operator feel pass.
|
was tuned on the OLD shapes) · suite + operator feel pass.
|
||||||
|
|
||||||
|
## Part C — collision-fidelity pass EXECUTED (gate approved: full plan + large-solid-prop adds)
|
||||||
|
|
||||||
|
**Built `Assets/_Project/Scripts/Editor/ColliderFitTools.cs`** (menu + programmatic Audit/Apply; idempotent —
|
||||||
|
regenerates ring segments + prop adds from the current visuals each run) and applied it to the subscene:
|
||||||
|
|
||||||
|
- **Rings REBUILT at fine resolution**: 16/24/24 coarse segments → **54/82/82** (~3.5-4 u arcs), each segment's
|
||||||
|
inner face fitted to the innermost TORSO-band (y 0.9–2.5) cliff vertex in its arc. Two audit-driven corrections:
|
||||||
|
(1) the 0.2–3.0 walk band chased shin-high cliff *skirts* and pulled the base wall 30→24.75 flat, stranding
|
||||||
|
playable meadow; (2) at coarse arcs one jutting rock walled off a whole 12–14 u span — hence torso band + fine
|
||||||
|
arcs. Result: base wall tracks 22.1–29.7 (avg 25.1), expedition 44.5–51.2 (avg 47.6), zero clamps/no-samples.
|
||||||
|
- **Cover rocks**: 8 uniform boxes (4.2×4.2, axis-aligned) → **convex `MeshCollider`s of the actual
|
||||||
|
`CoverRock_*` render meshes** at the visuals' exact TRS.
|
||||||
|
- **Landmarks**: hint-matched claim-once OBB fits (first audit's nearest-largest heuristic double-claimed the
|
||||||
|
cabin for `LM_WaterWheel` and gave `LM_Sign` a tent). Cabin 6×6→5.8×8.1, Tent 4×4→4.5×4.5 (walk-into-building
|
||||||
|
fixed); Well 3×3→1.9×2.0, Sign 2×2→0.6×0.5, Artefact 3×3→2.4×1.5 (invisible walls removed); Warpgate
|
||||||
|
8×2.5→8.3×6.8.
|
||||||
|
- **Adds (approved fork)**: 11 colliders on previously walk-through solid props gated by the LOCAL fitted wall
|
||||||
|
radius at each prop's angle — 1 meadow-tree trunk capsule + 2 sci-fi crates (base), wind-turbine poles ×2,
|
||||||
|
satellite dish, solar rig ×2 per survey camp (both expedition slots). 50 rim-decoration trees correctly
|
||||||
|
excluded (they stand in the cliff transition zone behind the fitted wall).
|
||||||
|
- **Spawn-safety pre-check**: player ring 2.5, wave ring 16, zone ring 14, room scatter ≤24, portal offset 5 —
|
||||||
|
all far inside every fitted wall; nothing gameplay-critical sits in the moved band.
|
||||||
|
|
||||||
|
**New build gotcha (now in CLAUDE.md): a `MeshCollider` bakes ONLY if the mesh has Read/Write enabled** — the
|
||||||
|
first Play after Apply threw `InvalidOperationException` per bake and produced NO cover shapes (0/6 solid in the
|
||||||
|
baked `CollisionWorld`) while the classic scene view showed the colliders fine. Fixed by flipping `isReadable`
|
||||||
|
on `SM_Env_Rocks_Spikey_03.fbx` + `SM_Env_Rock_06.fbx` (PNB_Arid_Desert) → 8/8 solid.
|
||||||
|
|
||||||
|
**Validation (all passed):**
|
||||||
|
- Baked-`CollisionWorld` probe (server): ring closure 32/32 rays per region inside the fitted band (expedition
|
||||||
|
44.1–50.6; base ≤28.5, short hits = Core/crate structures); cabin solid at its true footprint; well
|
||||||
|
1.7 u off-center FREE (old invisible wall gone); cover hulls 8/8 solid; **server==client static-body parity
|
||||||
|
(249 each)**.
|
||||||
|
- **Enemy stuck-fix backstop re-validated live**: an `EditorApplication.update` guardian delegate (new
|
||||||
|
harness pattern → validation-harness.md) kept the AFK player alive + parked across the room, embedded enemy
|
||||||
|
E5041 at the exact center of a cover hull, and took timed snapshots: E5041 was **depenetrated out of the hull
|
||||||
|
and moving** (993.00,6.00 → 991.26,5.80 in ~4 s), the other 4 enemies converged normally around cover to the
|
||||||
|
parked player. No freezes.
|
||||||
|
- EditMode suite green + console clean post-fix (bake exceptions gone).
|
||||||
|
|
||||||
## Next-session intent
|
## Next-session intent
|
||||||
|
|
||||||
Execute the collision-fidelity pass per the gate answer → lighting/atmosphere pass → art-look decision
|
Phase 1.5 continues: lighting/atmosphere pass → art-look decision gate (pixel filter ON/OFF side-by-sides).
|
||||||
gate (pixel filter ON/OFF side-by-sides). The B5 split-panels focused Play VISUAL smoke is still pending
|
Operator: eyeball the refit walls + cover rocks + new prop colliders in a real lap (fidelity is numeric-verified,
|
||||||
operator eyes (unfocused editor can't drive it).
|
feel is not), plus the still-pending B5 split-panels visual smoke.
|
||||||
|
|
||||||
Related: [[Iteration_2026-07_CoopHades]] · [[2026-07-07_Workflow_Consolidation]] ·
|
Related: [[Iteration_2026-07_CoopHades]] · [[2026-07-07_Workflow_Consolidation]] ·
|
||||||
[[2026-07-07_Expedition_Enemy_Stuck_Harvest_Feedback]]
|
[[2026-07-07_Expedition_Enemy_Stuck_Harvest_Feedback]]
|
||||||
|
|||||||
Reference in New Issue
Block a user