probe(physics): ACDREAM_PROBE_SUPPORT + ACDREAM_WIRE_MESH — separate #337's three candidates

The user is wedged at the top of Neftet rock plateaus, jumps sink into the
mesh, and a corpse falls straight through. ACDREAM_PROBE_REACH already ruled
out its own domain: blocked=0, every candidate tested-ok. Three candidates
remain — terrain support, a collision mesh not where its visual is, or the
transition wedging on an unobstructed path.

ACDREAM_PROBE_RESOLVE alone cannot separate them. It prints a three-value
contact-plane token, no plane normal, no plane height, no terrain sample and
no plane provenance, so all three produce the same line. Two additions:

[support] — one line per resolve for EVERY body, not just the player. A corpse
is a plain physics body with no player-specific logic, so its fall-through is
the cheapest available control on "movement code vs geometry data", and it is
invisible to any player-filtered probe. The line samples the outdoor terrain
INDEPENDENTLY at the body's own out-XY and prints the contact plane's own
height at that same XY. Two heights at one point make support=terrain /
object / none a measurement rather than an inference, and cpSrc= names the
site that asserted the plane so provenance and classification cross-check.

[geom] — once per GfxObj that comes near a mover: the object's physics-BSP
vertex cloud against its visual mesh AABB in the same local frame, through the
same prepared accessors the resolver queries. verdict=coincident REFUTES the
working hypothesis for that object outright; no-physics-bsp / empty-physics-bsp
/ displaced / extent-mismatch each name a specific data defect. Built to
refute, not to confirm — two diagnoses on this defect's lineage have already
been refuted by measurement.

ACDREAM_WIRE_MESH upgrades the existing F2 overlay, which drew a broadphase
proxy cylinder for BSP objects and so could not answer the question at all, to
the real physics-BSP polygon edges (cyan) beside the visual mesh box (magenta)
and the terrain surface (yellow). Own class per code-structure rule 1.

The provenance latch lives on PhysicsDiagnostics, not on CollisionInfo. Two
fields there first — the obvious home — broke the flat/graph differential
referee and the scratch-reset poison test, both of which compare CollisionInfo
member-for-member. Teaching either to skip a member is a one-line green fix
that puts a permanent hole in a referee whose whole job is comparing
everything. Captured as feedback_probe_state_off_compared_types.

Seven tests cover the support classifier's boundaries: a wrong classifier does
not fail to answer, it answers confidently wrong.

Gates: Release build 0 errors; complete suite 11,225 passed / 4 skipped / 0
failed from a cleaned tree — baseline 11,218/4/0 plus exactly the seven new
tests, skips unchanged.

Issue #337 filed with the symptom set, what is ruled out, and a table of what
each possible output means. All of this is TEMPORARY and recorded for
stripping with the physics-probe family.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-06 19:49:59 +02:00
parent 13fcf38138
commit 49a7e90652
9 changed files with 1376 additions and 1 deletions

View file

@ -1475,6 +1475,29 @@ via `PlayerMovementController.ApplyServerRunRate`) or from
delta), `[sticky-snap-skip]` at the suppressed NPC UP-snap site.
Heavy while a pack is stuck (~60 Hz × stuck count). Converged the
#171 residuals (the deep-overlap sign pin AP-82).
- `ACDREAM_PROBE_SUPPORT=1` — **what is holding a body up, and is the
collision geometry where the visual geometry is?** (#337, TEMPORARY).
`[support]`: one line per resolve **for every body, not just the player**
(a corpse falling through geometry is the cheapest control there is on
"movement code vs geometry data"). It samples the outdoor terrain
independently at the body's own out-XY and prints the contact plane's own
height at that same XY, so `support=terrain` / `object` / `none` is a
measurement rather than an inference; `cpSrc=` names the site that wrote
the plane so provenance cross-checks the classification. Edge-eager,
throttled to 4 Hz per body, and emits every 10 cm of vertical movement.
`[geom]`: once per GfxObj near the mover — the object's physics-BSP vertex
cloud against its visual mesh AABB in the same frame, with a verdict
(`coincident` REFUTES "collision isn't where the visual is";
`no-physics-bsp` / `empty-physics-bsp` / `displaced` / `extent-mismatch`
each name a data defect). `ACDREAM_PROBE_RESOLVE` alone cannot separate
those cases — it carries no plane normal, no plane height, no terrain
sample and no provenance.
- `ACDREAM_WIRE_MESH=1` — upgrades the existing **F2** collision overlay from
a broadphase proxy cylinder to the real physics-BSP polygon edges (cyan)
beside the same objects' visual mesh boxes (magenta) and the terrain
surface (yellow). Settles "visual versus collision" by eye instead of by
log. `ACDREAM_WIRE_RADIUS=<metres>` sets the window (default 30).
TEMPORARY, with the #337 probe family.
- `ACDREAM_CAPTURE_RESOLVE=<path>` — live capture of every player-side
`PhysicsEngine.ResolveWithTransition` call. Each call appends one
JSON Lines record with full inputs, PhysicsBody snapshot before AND