Live-test bug: player getting "super stuck" near walls without touching
them. Diagnostic showed 0 step-up calls, so the issue wasn't in DoStepUp.
Root cause: my subagent's L.2.1 commit added a Placement validation
inside DoStepDown to prevent step-up-through-walls. That check is right
for DoStepUp's call (the original use case). But DoStepDown is ALSO
called from TransitionalInsert's contact-recovery branch when the per-
sub-step contact plane is briefly lost (e.g., right after a wall-slide
nudges the sphere slightly upward).
For that "maintain contact during normal movement" use, the Placement
check is over-strict. Wall-slide can leave the sphere with sub-EPSILON
overlap of the wall's BSP solid; SphereIntersectsSolid returns Collided
inside Placement; DoStepDown returns false; my L.2.3e then escalates
that to TransitionState.Collided in the outer loop; ValidateTransition
reverts the position to CurPos every frame. Result: player stuck near
the wall without ever touching it.
Fix: add a `bool runPlacement = true` parameter to DoStepDown.
- DoStepUp passes the default (Placement runs — protects step-up).
- TransitionalInsert's contact-recovery branch passes false (Placement
skipped — accepts whatever walkable surface is found within reach).
This preserves L.2.3e's edge-block (genuine edges return Collided
because no walkable is found, not because Placement rejected) while
unbreaking normal-walking-near-walls.
ACE Transition.cs:731-741 runs Placement unconditionally, but ACE's
pre-step-down state machine is cleaner — acdream's residual wall-slide
artifacts make Placement misfire here.
Test count 825/825 still pass. Build clean.
Live verification needed: walk near a wall, should no longer get stuck.
Walk off a tall (>1.5m) balcony, should still edge-block.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>