acdream/tests/AcDream.Runtime.Tests/Physics
Erik ec29a732f5 test(physics): settle #331 — the uphill "refusal" is the #137 anti-parallel absorb, not a defect
#331 reported that `PhysicsEngine.ResolveWithTransition` refuses ALL uphill
motion whenever a `body:` is supplied. It does not. It refuses a step whose
sub-step offset is exactly anti-parallel to a live sliding normal — the
#137-family absorb this project already recorded as retail-faithful.

Measured on the same fixture, same gradient, same body, varying only the
heading relative to the slope gradient:

  (0,     -0.1, 0)  cross-slope 0        -> zero movement, latched
  (0.0001,-0.1, 0)  cross-slope 0.0001 m -> zero movement, latched
  (0.001, -0.1, 0)  cross-slope 0.001 m  -> climbs 0.176 m in 5 ticks
  (0.01,  -0.1, 0)  cross-slope 0.01 m   -> climbs 0.176 m in 5 ticks

The threshold is retail's own F_EPSILON small-offset abort (0.0002 m): about
0.11 degrees off the exact gradient at a 0.1 m step. `RemoteRampHarness`
builds a ramp whose gradient is exactly along Y and the original probe pushed
exactly along -Y, so it hit the measure-zero case with probability 1.

The latch itself is production-real in mechanism — a pure gravity fall under
the production RuntimeRemotePhysicsUpdater, with no fixture settle seam
involved, lands leaving Contact|OnWalkable|Sliding with slidingNormal (0,1,0)
— but every link is faithful to retail, verified in the PDB-paired binary
rather than Binary Ninja (BN typed find_transitional_position `void` and
dropped the load-bearing return value):

  validate_walkable sets collision_normal from the terrain plane when
    OBJECTINFO CONTACT is clear      0x0050d251 / 0x0050d261 / 0x0050d26c
  validate_transition converts it unconditionally  0x0050ac19-0x0050ac30
  set_sliding_normal zeroes Z AND re-normalizes    0x0050a060
  SetPositionInternal persists SLIDING_TS          0x005154c2 / 0x005154e1
  get_object_info re-seeds it next frame           0x00511d44 / 0x00511d4f
  find_transitional_position returns
    `i != 0 && state == OK` on the step-0 abort     0x0050c0ed -> 0x0050c089

ACE agrees (Transition.cs:1027, CollisionInfo.cs:58). No production code
changed; no divergence introduced, so no register row.

What lands is the coverage whose absence made this invisible — nothing in the
suite asserted that a body-bearing mover makes uphill progress on a walkable
slope, and the test that found #331 passed vacuously because the body never
moved:

  RuntimeRemoteUphillProgressTests.ARemoteWithABodyClimbsAWalkableSlopeAndKeepsItsFeetOnIt
    per-tick climb + surface tracking under a realistic off-gradient heading.
    SAB-A1 AdjustOffset -> Vector3.Zero            reddens at tick 1
    SAB-A2 fixture gradient -> 0 (flat)            reddens at tick 1
  RuntimeRemoteUphillProgressTests.AnExactlyUpSlopeOffsetIsAbsorbedByThePersistedSlidingNormal
    characterization pin for the absorb, with the retail anchors inline.
    SAB-B1 delete the get_object_info sliding seed  reddens (climbs to 57.7544)
    SAB-A1                                          reddens
    SAB-A2                                          reddens
    NON-discriminating, measured and documented: making the final tick
    exactly up-slope leaves it green — by then the latch is already cleared.

RemoteRampHarness gains a warning block naming the axis-alignment trap so the
next vacuous uphill assertion is caught at authoring time.

Suite re-measured from a full clean (43 bin/obj removed): 11,198 passed /
4 skipped / 0 failed, against the 11,196/4/0 baseline at 0d62a5ff — exactly
the two tests added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:08:22 +02:00
..
RemoteRampHarness.cs test(physics): settle #331 — the uphill "refusal" is the #137 anti-parallel absorb, not a defect 2026-08-06 14:08:22 +02:00
RuntimeAuthoritativePositionRouteClassifierTests.cs fix(physics): C4 route 7 — child cell propagation moves from a render tick into Runtime 2026-08-04 23:53:05 +02:00
RuntimeCollisionMutationTransactionTests.cs feat(runtime): atomically replace collision generations 2026-08-01 17:33:34 +02:00
RuntimeCollisionPrefixQuiescenceTests.CornerLandblock.cs feat(runtime): C3c - production placement cutover: both hosts on the residence conductors (routes 1+8) 2026-08-02 18:10:33 +02:00
RuntimeCollisionPrefixQuiescenceTests.cs fix(physics): restore a cancelled park instead of leaving the entity withdrawn 2026-08-04 04:07:39 +02:00
RuntimeCollisionReportingStateTests.cs fix(runtime): preserve hidden setposition collision ownership 2026-08-01 18:22:45 +02:00
RuntimePhysicsOwnershipBoundaryTests.cs feat(runtime): atomically replace collision generations 2026-08-01 17:33:34 +02:00
RuntimePhysicsStateTests.cs wip(physics): collision O(changed) delta-commit (O1-O3) - ON HOLD, feel-test failed 2026-08-02 20:06:59 +02:00
RuntimePlacementProjectionSubscriptionTests.cs feat(app): observe canonical placement receipts 2026-08-01 15:22:52 +02:00
RuntimeRemoteFarSnapPositionTests.cs feat(physics): C4 route 4b-3 — remote teleport + cell-less through the canonical placement 2026-08-04 16:00:10 +02:00
RuntimeRemoteSlopeProjectionTests.cs test(physics): measure whether the remote sweep alone tracks surface Z (AD-10 Stage 0) 2026-08-06 09:34:56 +02:00
RuntimeRemoteSteadyStatePositionTests.cs feat(physics): C4 route 4b-3 — remote teleport + cell-less through the canonical placement 2026-08-04 16:00:10 +02:00
RuntimeRemoteSteepContactSlideTests.cs test(physics): measure whether the remote sweep alone tracks surface Z (AD-10 Stage 0) 2026-08-06 09:34:56 +02:00
RuntimeRemoteUphillProgressTests.cs test(physics): settle #331 — the uphill "refusal" is the #137 anti-parallel absorb, not a defect 2026-08-06 14:08:22 +02:00
RuntimeSetPositionMoverPreparationTests.cs fix(physics): #297 — keep the PWD bitfield live so PK status reaches the client 2026-08-03 20:59:01 +02:00
RuntimeSetPositionStateTests.cs fix(review): close the C5b architecture-review findings (D2/D3/D4, L1-L5, S1) 2026-08-05 22:08:46 +02:00
RuntimeWorldFrameTests.cs fix(runtime): name why a placement is parked and fail closed when it cannot resolve 2026-08-03 13:55:16 +02:00