Commit graph

2 commits

Author SHA1 Message Date
Erik
06c76009f1 fix(physics): #265/#166 - stop zeroing grounded residual velocity, wire GroundNormal
Capture bisect (docs/research/2026-07-30-265-capture-bisect.md, mined
from artifacts/matrix-session2-resolve.jsonl records 3415-3434) traced
#265's lost roof slides / permanent landing freeze and #166's missing
downhill sled to a pre-existing (2026-07-20, ten days before Campaign P
- not a regression) mechanism in PlayerMovementController.cs's grounded
quantum block: it hand-zeroed Velocity.X/Y to exactly zero every tick
once OnWalkable whenever animation root motion drives the walk (the
production graphical local-player path), discarding any residual
horizontal momentum a fall left on the body before calc_friction
(AP-7/AD-55, already correctly ported) or PhysicsBody.
UpdatePhysicsInternal's Euler integrator ever got a chance to act on it.

Two changes:

1. PhysicsEngine.cs now syncs body.GroundNormal (the vector
   calc_friction dots velocity against, per retail
   CPhysicsObj::calc_friction 0x0050ee70's `contact_plane.Normal` read)
   from the committed ContactPlane.Normal at the same commit point that
   already publishes ContactPlane. GroundNormal had zero production
   writers before this and silently defaulted to Vector3.UnitZ forever
   - even surviving velocity would have been tested against a fake
   flat-ground normal on any real slope. Core-level, so player, remote,
   ordinary, and projectile movers all benefit uniformly.

2. PlayerMovementController.cs's grounded block no longer reconstructs
   Velocity at all for the animation-root-motion case (only the
   headless/test-controller get_state_velocity fallback still does,
   unchanged). Root motion continues to fully own commanded locomotion;
   this only stops destroying whatever Velocity already holds, letting
   it compose with root motion through the same ResolveWithTransition
   sweep exactly as retail's CPhysicsObj::UpdatePositionInternal
   composes both channels.

Symptom (a), the uphill-jump bounce, traces to a SEPARATE, byte-exact
(re-verified against acclient_2013_pseudo_c.txt:282647-282760),
already-closed retail mechanism (AD-25, PhysicsObjUpdate.
HandleAllCollisions's shouldReflect gate) - confirmed orthogonal to this
fix, not addressed here (see the research doc's as-fixed addendum §9.5).

Issue265SteepSlopeCaptureBisectTests.cs gains a composed harness
(ReplayRealRoofLandingComposed) mirroring PlayerMovementController.cs's
per-tick composition against Core types only, proving: the old model
reproduces the mined freeze exactly; the new model survives the landing
and slides continuously (the real captured geometry glides at constant
velocity per retail's own dot>=0.25 early-return - AP-7); a synthetic
dot<0.25 case shows genuine exponential decay via calc_friction; and a
synthetic uphill-bounce case proves the fix changes nothing about
HandleAllCollisions's reflection decision.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 19:28:28 +02:00
Erik
909bff0aa5 test(physics): #265 mining tool + real-trajectory replay harness for the steep-slope response family
Adds tools/analyze_265_steep_slope_capture.py (segment miner for the
ACDREAM_CAPTURE_RESOLVE JSONL captures: uphill-jump-bounce and
lost-slide/edge-wedge signature scans) and
tests/AcDream.Core.Tests/Physics/Issue265SteepSlopeCaptureBisectTests.cs (a
synthetic single-polygon PhysicsEngine that replays the EXACT real captured
ballistic approach + landing from artifacts/matrix-session2-resolve.jsonl
records 3415-3434, driving PhysicsEngine.ResolveWithTransition directly at
the Core boundary).

Mining found two dramatic real "velocity annihilation + permanent freeze"
events (records 3153/3159 and 3433/3434): a high-speed fall lands on a
moderate roof slope (normal.Z=0.857, ABOVE PhysicsGlobals.FloorZ — walkable
by threshold), and the very next tick shows Velocity forced to exactly
(0,0,0) with the position frozen byte-identical for the rest of the capture
(12,292 ticks to EOF for the second event).

No production code changes. Full Core.Tests suite: 4070 passed / 2 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 17:55:49 +02:00