Restores per-frame collision/terrain sweep that was DROPPED by e94e791
(L.3.1+L.3.2 Task 3) when the ACDREAM_INTERP_MANAGER=1 path replaced
the per-tick logic with a stripped-down version intended to mirror
retail's CPhysicsObj::MoveOrTeleport.
That was a category error: MoveOrTeleport (acclient @ 0x00516330) is
the *network packet handler* entry point — minimal work. The per-frame
physics tick is retail's update_object (FUN_00515020) — full chain
including FUN_005148A0 Transition::FindTransitionalPosition (the
collision sweep). The legacy (env-var off) path mirrors update_object
correctly; the env-var path was missing this single step.
Symptoms that map directly to the missing sweep:
- "Staircase" Z drift on slopes (horizontal Euler motion sinks into
rising ground until the next UP pops it up). User-confirmed for
BOTH retail-driven AND acdream-driven remotes when observed from
acdream.
- Position blips during steady-state motion (predicted XY drifts
unconstrained between UPs, then UP hard-snaps).
Fix: copy the legacy path's "Step 4: collision sweep" block (lines
~6483-6569) into the env-var per-frame branch, between
UpdatePhysicsInternal and the existing landing fallback. Includes
post-resolve landing detection (K-fix15 + K-fix17 mirror) so airborne
remotes correctly transition back to grounded after the sweep clamps
them to a walkable surface.
Sphere dims match the legacy path verbatim (0.48m radius, 1.2m height,
0.4m step-up/down, EdgeSlide moverFlags) — retail human-scale, already
proven via the legacy path before the e94e791 regression.
Does NOT address the separate Run↔Walk cycle bug (different root
cause: missing velocity-derived cycle inference for player remotes).
That's a follow-up commit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>