Wires the M1 InterpolationManager into the per-tick + UP-receipt paths
in GameWindow for player remote entities. Visual-verified against a
retail-controlled remote: smooth body chase, no per-UP rubber-band, no
staircase on slopes.
OnLivePositionUpdated:
- Gate changed from `ACDREAM_INTERP_MANAGER == "1"` to
`IsPlayerGuid(update.Guid)`. NPCs continue through the legacy
synth-velocity branch (ServerVelocity / ServerMoveTo) below — their
motion model is correct as-is.
- Within-bubble enqueue passes `currentBodyPosition` so the M1 far-
branch detection (>100 m from body) can pre-arm an immediate blip.
- Three branches (airborne no-op, near-enqueue, far-snap) now sync
`entity.Position = rmState.Body.Position` before returning. This
overrides the unconditional `entity.Position = worldPos` snap at
the top of the function. Without this sync the entity teleports
forward to server truth on UP receipt and TickAnimations yanks it
back to the queue-driven body next frame — visible 0.5–1 m rubber-
band per UP.
TickAnimations:
- Gate changed from `ACDREAM_INTERP_MANAGER == "1"` to
`IsPlayerGuid(serverGuid) && !rm.Airborne`. Airborne player remotes
fall through to the legacy path so K-fix15 landing + gravity sweep
still fire on the jump arc.
- Step 2 (per-frame translation) replaced. Was
`rm.Position.ComputeOffset(...)` (mixed queue catch-up + animation
root motion); now direct `rm.Interp.AdjustOffset(...)` (queue-only,
no anim contribution). M3 will layer anim root motion on top so
legs match body pace; for M2 the body chases server position
smoothly without any anim-driven translation.
- Step 4b (ResolveWithTransition collision sweep) REMOVED for player
remotes. Server already collision-resolved the broadcast position;
running the sweep on tiny per-frame queue catch-up deltas amplified
micro-bounces into the ISSUES.md #40 staircase + flat-ground blips.
- Step 5 (LastServerZ landing fallback) REMOVED — unreachable in the
`!rm.Airborne` branch.
Per retail spec (docs/research/2026-05-04-l3-port/01-per-tick.md +
04-interp-manager.md): m_velocityVector stays 0 for grounded remotes,
apply_current_movement is local-player-only, and per-tick translation
comes entirely from InterpolationManager queue catch-up.
Behavior for player remotes:
| Scenario | Path | Translation source |
|-----------------------|--------|------------------------------|
| Grounded near (≤96m) | M2 | Queue catch-up (2× max-speed)|
| Grounded far (>96m) | M2 | Hard-snap to worldPos |
| Far enqueue (>100m) | M2 | Pre-armed blip-to-tail |
| Airborne (mid-jump) | Legacy | Gravity arc + sweep |
| Landing | M2 | Hard-snap, queue cleared |
NPCs: legacy path unchanged (synth velocity, ServerMoveTo, etc.).
Closes the regression observed in 9b0f4f2 ("modern, not retail-faithful")
and the L.3 attempts on 91bf1e0 / e94e791. Replaces the env-var path
(ACDREAM_INTERP_MANAGER=1) which was marked DO-NOT-ENABLE in
ISSUES.md #40 — the env-var no longer toggles anything for player
remotes; this IS the path now.
Build green, dotnet test green (8 pre-existing failures unchanged on
this baseline; verified via stash on a3f53c2).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>