# Character Presentation Interpolation The authoritative game simulation still advances in exact 100 ms ticks. Character interpolation is a rendering-only feature and does not modify `CharacterState`, network commands, tick IDs, state hashes, or deterministic lockstep behavior. ## How it works Each runtime `Character` keeps two presentation samples: - `previous`: the visual values received at the preceding completed simulation tick; - `current`: the visual values received at the latest completed simulation tick. Rendering calculates an alpha from the real elapsed time since the latest completed tick, clamped to the 100 ms simulation interval. It renders the delayed `previous -> current` transition. This introduces at most one simulation tick of presentation latency, but it avoids predicting a state that has not arrived from the authoritative simulation. The following values are interpolated: - Position uses linear interpolation. - Facing angle uses the shortest angular path, including wraparound at ±π. - Animation frame remains fractional and is interpolated when both samples use the same animation state. Looping clips treat the last frame to first frame transition as a cyclic interval instead of interpolating backward through the entire clip. The interpolated values are used by mesh, weapon, shadow, night-lighting, name, and health-bar rendering. The local camera and shadow-map center follow the same interpolated player position; otherwise the camera would jump to the newest authoritative position while the player model was still in its presentation transition. Gameplay queries, commands, callbacks, collision, and presentation events continue to use the authoritative snapshot. ## Other presentation animations Teleport-zone star particles are advanced by `Location::updatePresentation()` once per render frame using the real frame delta. They are no longer advanced only from the 100 ms simulation-tick callback, so their visual motion remains continuous without affecting teleport activation or other authoritative state. Dialogue typewriter text and cutscene presentation timers use the same per-render-frame path. This keeps character reveals, subtitle timing, fades, and cutscene image poses smooth instead of stepping in 100 ms increments. Interactive objects retain authoritative move, rotate, scale, and fade tasks on the simulation tick. Their previous and current visual transforms are sampled at tick boundaries and interpolated only while drawing, so doors and similar objects remain logically deterministic while their presentation is smooth. The same render-only sampling is used for `NpcCar` taxi visuals. Its position, body rotation, wheel rotation, and steering angle are interpolated for drawing; the authoritative taxi movement and waypoint logic remain fixed-step. ## Animation skinning GPU and CPU bone interpolation receive the fractional render frame instead of an integer-truncated frame. Bone positions are linearly interpolated and bone rotations use spherical interpolation as before. Frames at the end of a clip are clamped to the final keyframe. ## Discontinuities The presentation buffer is reset instead of blended when a character is first observed, changes animation state or enabled state, or has not received a tick for a sufficiently long gap. This prevents stale positions, animation clips, or disabled characters from producing visible interpolation artifacts. ## Local and networked games Local games continue accumulating wall-clock remainder time and executing exact 100 ms simulation updates. Networked games continue consuming only contiguous server tick messages. Both paths publish completed snapshots to the same runtime presentation objects; interpolation only changes how those snapshots are drawn between updates.