fix(physics #145): Slice 7 — idle the motion interpreter on teleport arrival

SetPosition zeros the body velocity but the motion interpreter kept the
PRE-teleport ForwardCommand (RunForward), so the next Update() rebuilt that
run vector via get_state_velocity and the player sprinted off in the old
direction on arrival. DoMotion(Ready) makes the player arrive at rest. Not a
cascade fix anymore (Slice 3 closed that) — the last user-visible bit of #145.
All suites green: Core 1529 / App 480 / UI 425 / Net 313.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-21 13:54:29 +02:00
parent 6349ba49aa
commit 403a338feb

View file

@ -816,6 +816,14 @@ public sealed class PlayerMovementController
_body.TransientState = TransientStateFlags.Contact | TransientStateFlags.OnWalkable; _body.TransientState = TransientStateFlags.Contact | TransientStateFlags.OnWalkable;
_body.Velocity = Vector3.Zero; _body.Velocity = Vector3.Zero;
// #145 Slice 7: idle the motion interpreter on a server snap / teleport arrival.
// SetPosition zeros the body velocity, but the motion interpreter still holds the
// PRE-teleport ForwardCommand (e.g. RunForward), so the next Update() would
// reconstruct that run vector via get_state_velocity and the player would sprint
// off in the old direction the instant input resumes. Resetting the forward
// command to Ready makes the player arrive at rest.
_motion.DoMotion(MotionCommand.Ready, 1.0f);
// Reset physics clock so any subsequent update_object calls start fresh. // Reset physics clock so any subsequent update_object calls start fresh.
_body.LastUpdateTime = 0.0; _body.LastUpdateTime = 0.0;
_physicsAccum = 0f; _physicsAccum = 0f;