Body Stage 1 collapse root-caused + fixed: NaN in torso servo math (GetAngle = 2*acos(W) at W=1.0000001), not solver stacking

- BodyMath.RotationError: atan2-based shortest-arc error (no NaN, no GetAxis gain collapse
  inside 0.16 deg); used by PhysicsTorso orientation servo and PhysicsHands rotation lock
- BodyMath.ResetIfNonFinite escape hatch on torso + hands
- PhysicsHands.Drive extracted (static) so spikes run the real hand chase
- CollapseSpike: deterministic repro (slow yaw drift across a parked chest, 7/40 NaN on old
  code) + solver-stacking scenarios (seated chest in table, two-hand-welded 50 kg anvil,
  real PropShop) — 49/49 clean after fix, x3; all other spikes PASS x3
- Failure brief RESOLUTION section; HANDOFF/AGENTS updated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
FoxyzandClaude Opus 5.5 committed 2026-10-01 23:55:46 +03:00
1 parent ce1e0e3b0c
commit cb518999e5
9 files changed
+466 -47

No files matched your search

+22 -26
View File
@@ -120,10 +120,8 @@ TERMINOLOGY (owner-corrected — use precisely):
grab/teleport; `IsPanelCollider(node)` identifies interactive colliders for lasers.
- **TeleportMarker.cs** — `scenes/teleport_marker.tscn`: disc + beam + Label3D, group
"teleport_marker", StaticBody pick box. `SetNear` hides visuals, `SetHighlighted` swaps colors.
- **PhysicsTorso.cs** — the player's PHYSICAL CHEST (body-physics Stage 1). **Implemented
2026-10-01; FAILED first in-headset playtest (seated chest-vs-table overlap + two-handed
50 kg anvil weld → NaN transform flood) — see §5 known issues +**
**`research/body-stage1-failure-brief.md` before touching anything here.**
- **PhysicsTorso.cs** — the player's PHYSICAL CHEST (body-physics Stage 1). Implemented
2026-10-01; the first playtest's NaN collapse is root-caused + fixed (servo math, see §5).
One RigidBody3D box (0.22×0.5×0.13, 30 kg, gravity off, CCD, contact monitor), chase-driven
toward an HMD-derived target: target = head − 6 cm back + torso-yaw basis·(0, −0.42, +0.06)
+ `ReachOffset` (fed by BodyRig's reach budget). Linear drive = the PhysicsHands pattern at
@@ -216,19 +214,24 @@ Floor StaticBody scans layer 3 (collision_mask 13).
## 5. Known issues / open questions
- **Body Stage 1 (chest) FAILED in-headset on first playtest (2026-10-01) — DO NOT extend the
body track until diagnosed.** Owner report: "it quickly collapsed with my head detaching
from the body"; screenshot = prop table chaos. Log evidence: session calibrated at head
height **1.01 m (seated)** → chest box overlaps the table; the NaN flood
(`!v.is_finite()` at `instance_set_transform`, 22.8k lines) starts right after
**"grabbed 'Anvil · 50 kg' (50 kg, left, two-handed)"** — i.e. chest-vs-statics overlap +
50 kg prop rigid-welded to both 90 N hands pressed into that mess. Headless body spike
passes (it lacks static-table overlap + welded heavy props — that's the repro gap).
Full self-contained analysis for the owner's external agent:
**`research/body-stage1-failure-brief.md`** (evidence chain, hypotheses H1–H3, mitigation
candidates M1–M5, headless-repro plan). Working suspicion: the documented
"script velocity SETs + reaction forces = limit cycle" lesson (grab v5.0) resurfacing at
body scale — 30 kg velocity-write servo braced against statics.
- **Body Stage 1 chest collapse — ROOT-CAUSED + FIXED (2026-10-01), awaiting owner re-playtest.**
The first in-headset session NaN'd the chest ("head detaching from the body"). Cause was
SCRIPT MATH, not the solver: the orientation servo used `Quaternion.GetAngle()` = `2*acos(W)`
(Godot C# `Mathf.Acos` is unclamped) → NaN when rounding put W at 1.0000001, which a seated
still player reaches because `GetAxis()` (raw xyz when W > 1−1e-6) collapsed the servo gain
inside 0.16° and parked the body where a slowly drifting target crosses it. Fixed with
`BodyMath.RotationError` (atan2-based) in torso + hands, plus `BodyMath.ResetIfNonFinite`
escape hatch on every driven body. Deterministic repro + regression:
`scenes/collapse_spike.tscn` (old code 42/49, fixed 49/49). Solver stacking (chest in
static table + two-hand-welded 50 kg anvil) was tested and is stable. Full record:
`research/body-stage1-failure-brief.md` (RESOLUTION section). **RULE: never use
`Quaternion.GetAngle()/GetAxis()` for servo errors — use `BodyMath.RotationError`.**
- **Seated calibration** — BodyRig calibrates proportions from the head height at first
frame; seated (1.01 m) clamps arm length to the 0.50 m minimum, so normal reaches saturate
`ReachOffset` and lean the chest into the table (stable, but wrong proportions). Needs a
standing calibration step or a seated mode — owner's call.
- **Chest plows table props** when seated at the table (props thrown up to ~3.8 m/s by the
2400 N chest). Honest physics; tune by feel.
- **AnchorMoveMode NEEDS FIXING (owner playtest report, 2026-10-01)** — two-hand turning
is NOT working as intended (not 2-anchor based) and simultaneous two-hand movement acts
weird. NOTE before fixing: owner is considering replacing grab-locomotion with physics
@@ -311,15 +314,8 @@ Floor StaticBody scans layer 3 (collision_mask 13).
## 7. Next steps (in order)
1. **Diagnose + fix the body Stage-1 collapse (BLOCKS the body track)** — first playtest of
the physical chest NaN'd the solver (seated chest-in-table overlap + two-handed 50 kg
anvil weld pressed into it; "head detaching from the body"). All context, hypotheses,
mitigation candidates and the headless-repro plan are in
`research/body-stage1-failure-brief.md` — written self-contained so the owner can forward
it to their external agent verbatim. First move per the brief: extend `body_spike` with
the exact cocktail (chest target overlapping a static slab + two welded 90 N hands
dragging a 50 kg box into the chest) and get a deterministic NaN repro before touching
PhysicsTorso.cs. Owner re-playtests feel only after the fix.
1. **Owner re-playtest of the body (chest fix + Stage 2 arms)** — the Stage-1 collapse is
fixed (`collapse_spike` 49/49); feel is unvalidated in-headset. Read the log after.
2. **Locomotion decision** — owner report 2026-10-01: two-hand anchor turning broken (not
2-anchor based), simultaneous two-hand movement acts weird, teleport + lasers broken
(experiments, not current issues). Owner's candidate replacement: physics thumbstick