Docs: DR-052 SoD facing + underwater feel — build spec, session log, gotchas archive 07-16, skinned-kit cookbook recipe, CLAUDE.md facing contract (net-zero condensations)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 00:54:53 -07:00
parent 4fa2cb0de4
commit a083e77a9e
6 changed files with 207 additions and 9 deletions
@@ -482,3 +482,23 @@ The surviving invariants (ledger spend-in-place soft-fail; snapshot-above-early-
- **Automation (server-only):** catch-up `ProductionMath.CyclesDue` **lower-bound 0**; `RuntimePlacedTag`=player-built. [[DR-020_M7_Automation_Production_Chains]].
- (Persistence bullet, pre-v7 form): **born-correct load**`CycleDirectorSpawnSystem` stages `PendingSave` AT SPAWN; `BaseRestoreSystem` replays structures charge-free + REMAINING-tick cooldowns + HP. `SaveService.Load` = additive floor `[MinLoadableVersion=2, Current]` (old saves load; missing field 0-defaults).
- (Netcode bullet, pre-purge form): **Shared GLOBAL state (cycle phase, resource ledger, goal meter) rides an UNTAGGED ghost**, never a region-tagged one (`SetIsIrrelevant` would hide it cross-region). Resolve the ledger via its DISTINCT `ResourceLedger` tag (the multi-`StorageEntry` "multiple instances" rule — EB-2 line).
## 2026-07-16 — facing/underwater-feel session condensations (pays the SoD facing contract + the skinned-attachment recipe)
Condensed from CLAUDE.md 07-16; the inline bullets keep the operational core, verbose forms preserved here.
- **Old "Aim controls" bullet (pre-DR-052, superseded):** Client-derived aim on `PlayerInput.Aim`; scheme byte KBM=0/Gamepad=1; reticle re-raycasts inside `AimReticleSystem` → full detail: archive 2026-07-06 section + the source files. *(Superseded by the SoD facing model — [[DR-052_SoD_Facing_Underwater_Feel]]: PlayerFacing = body-yaw only; fire directions read `FacingMath.ResolveAim`.)*
- **Dark-lit screenshot / material values (full form):** `shader.GetPropertyType(idx)`-guard before `GetColor`/`GetFloat`/`GetTexture` (`S_General`'s `_BaseColorMultiply` is a float → `GetColor` returns black). Gate emission on the `_Emissive` flag + a fixture name; keep converted env metallic low (0.10.2).
- **EG per-instance tint (full form):** works only if the graph's `_BaseColor` is Hybrid-Per-Instance (ShaderGraph `overrideHLSLDeclaration:true`+`hlslDeclarationOverride:2`). `AnimatedLitShader` is DOTS-authored so enemies flash; a stock Synty prop graph (`Generic_Basic`) is Unity-Per-Material → the override renders but silently no-ops. Fallback = procedural decal quads (07-12 cover damage-cracks, Part P).
- **Asset-free presentation (full form):** runtime `ParticleSystem` pool uses Sprites/Default + HDR start color; ACES tonemapping needs URP color grading mode = HDR (`m_ColorGradingMode=1`).
- **New ghost prefab recipe (full form):** `manage_prefabs modify_contents` swaps the authoring MonoBehaviour (strip MeshFilter+MeshRenderer for an invisible state-holder); subscene wiring sequence `manage_scene load additive``set_active_scene Gameplay` → create+verify → `save``close_scene`.
- **Old condensation-history parentheticals:** 07-07b paid the attribute-swallow gotcha · 07-07c = game-state narrative → invariants+DR pointers (~3 KB freed, operator-ordered) · 07-13 = co-op-Hades core-loop bullet → LANTERN direction pointer ([[DR-048_Lantern_Adoption_Full_Pivot]]) · 07-15 = siege-era/automation/GoalProgress bullets retired with the DR-051 purge · 07-16 = this heading.
- **Stack-table trivia:** packages-lock reconcile 2026-06-17 pinned test-framework 1.7.0, ugui 2.5.0, multiplayer.center 1.0.1; `com.unity.ai.assistant` was removed 07-04 for console noise. serena MCP was removed 2026-07-07 (unused in practice + flaky on Unity).
### The 07-16 skinned-attachment session's full failure chain (for the record)
1. Hidden Blender armature → `select_set` no-op → FBX exported skinless (meshes imported as static MeshRenderers, no vgroups). Fix: `hide_set(False)` before selection-export.
2. Blender FBX roundtrip (both FBX_SCALE_UNITS and FBX_SCALE_ALL) imports cm bones under a 0.01-scale armature; Synty-native skeletons are meter-scale. Raw bindpose reuse on rebind → skin matrices ×100 (kit rendered 140 m in the air). Fix: rebase — verts baked to rest-world, bindposes = inverse of RIGID (scale-stripped) rest matrices.
3. Procedural skinned Mesh asset without tangents → Rukhanka/BRG `BatchMeshID not present` + assertion spam, the whole rig invisible. Fix: `RecalculateTangents()`.
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.