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
@@ -0,0 +1,27 @@
---
title: DR-052 — Shape-of-Dreams facing model + underwater movement feel
date: 2026-07-16
status: locked
links: "[[2026-07-16_Facing_Underwater_Feel_Suit_Kit]], [[Facing_Underwater_Feel_Build_Spec]], [[DR-048_Lantern_Adoption_Full_Pivot]], [[DR-051_Lantern_Realignment_Purge]]"
---
# DR-052 — Shape-of-Dreams facing model + underwater movement feel
## Decisions (operator-locked 07-15/16)
1. **The facing model is SoD option (a)**: the body turns toward the MOVEMENT direction while moving; turns toward the AIM only during a cast window (melee swing / non-Movement socket fire, `CastFacingTicks`=13 ≈ the anim pulse); holds the last facing when idle. **The cursor is never passively tracked.** Twin-stick cursor-facing is dead.
2. **`PlayerFacing` is body-yaw/presentation ONLY.** Every gameplay direction (all four AbilityFireSystem archetypes, the auto-target seed, the melee cleave) reads `FacingMath.ResolveAim(PlayerInput.Aim, facing)` — raw replicated Aim, facing fallback for a resting gamepad stick, +Z last. Aim-consuming presentation (reticle ring, tether axis, local slash/cone cues) reads the SAME resolver so sim and FX cannot diverge; remote players' cues stay facing-based (Aim isn't replicated to non-owners).
3. **A Movement-archetype socket (blink) never counts as a cast**`TickWindowMath.SocketFireAndCone` skips it outright (facing AND animation paths; this also killed the latent cooldown-tail phantom IsFiring).
4. **Stationary dash/blink keep going toward the cursor** (fallback Move→Aim→facing) — cursor-dodge control kept deliberately over SoD purity.
5. **Underwater weight defaults**: `GroundedMovementSharpness` 6 (was 15), locomotion turn 360°/s (was 720), cast turn 1080°/s const; MoveSpeed unchanged (6). Locomotion gait ×0.85, idle⇄locomotion blends 0.25s. Footsteps are stride-distance (1.5m) deep thuds + silt puffs.
6. **Live tuning rides TuningKnob 2628 with a 0 = NO-OVERRIDE sentinel** (0 falls back to stat/const/authored; explicit ClampKnob ≥0 case). Extending `DebugTuningReport` is an accepted **dev-protocol bump** (stale standalone dev build ⇒ handshake refusal ⇒ rebuild both).
## Determinism/netcode contract (from review wf_a13d4395-1c7, confirmed)
- Wire-neutral apart from the dev report bump: no `[GhostField]`/RPC/input-struct changes; PlayerFacing stays the only replicated facing state.
- PlayerAimSystem stays **un-gated** (no `IsFirstTimeFullyPredictingTick`) — the rate-limited turn is an incremental integrator over the snapshot-restored ghost field and must re-integrate every predicted pass.
- `[UpdateAfter(MeleeComboSystem)]` on PlayerAimSystem is a **hygiene pin**, not a divergence fix — the sorter's tie-break is deterministic and cross-world-identical (confirmed by critic evidence; the "cross-world sort divergence" claim was refuted). Socket windows open 1 tick late by construction — cosmetic-only since damage is Aim-sourced.
## Suit attachment pipeline (the reusable recipe)
Blender kitbash attachments → rigid-skin (vgroup w=1 + armature modifier) → join per shader role → FBX (UNHIDE the armature first — hidden = silently skinless) → `PlayerRigTools.AttachBathynautKit`: bone-name rebind + **rebase** (verts to rest-world; bindposes = inverse of RIGID scale-stripped rest matrices; `RecalculateTangents`) → `Rebased_*.asset` meshes. Glow pieces ride `ProjectM/EmissiveGloamSkinned` (Rukhanka ComputeDeformedVertex; DOTS-instanced block BEFORE the include; `_DeformedMeshIndex` in Properties for the baker's validation).