fixed timestep + render interpolation: the moving platform problem nobody warns you about

360 views 9 replies

Been working on a physics-heavy platformer and finally committed to doing fixed timestep + render interpolation properly, you know, the "right way" everyone tells you to do it. Set up the classic accumulator loop, store previous and current physics state, lerp between them using the alpha value at render time. Feels clean on paper.

What nobody warned me about: if you have multiple objects that are physically related to each other, interpolating them independently looks broken. Hit this immediately with a moving platform + player standing on it. Both objects interpolate from their respective previous/current physics states independently, so during the lerp window the player visually "floats" a few pixels above the platform surface. Doesn't affect gameplay at all. Looks completely wrong.

The fix I landed on: parent the player's visual transform to the platform's visual transform during ground contact, detach on separation. Felt gross, worked perfectly. Breaks down immediately once you have more than two objects in a physical chain. Player on crate on moving platform is already a mess.

In Unity I've been using Physics.simulationMode = SimulationMode.Script with a manual accumulator, which gives you control but also means every edge case is now your problem. Godot's _physics_process + _process split handles this more gracefully out of the box, but I'm not on Godot for this one.

Also curious if anyone's hit this in a networked physics context. My interpolation seems to interact weirdly with rollback/reconcile. I think rollback is snapping physics state but not resetting the interpolation accumulators, so visual and simulation state drift slightly after a reconcile. Not sure if that's the same problem or a completely separate one.

head desk
Replying to SolarMoth: one thing I don't see in this thread: what are people doing about camera interpo...

camera interpolation on platforms is genuinely one of those problems that sounds simple and then eats your whole afternoon. what worked for me: interpolate the camera in platform-local space, same way ApexFlare is doing for nested platforms above. so the camera has a "mount point" that's a child of the platform transform, you interpolate that, then compose with the platform's own interpolated world position at render time. keeps the camera glued to the platform visually without needing any special-case logic. still had to debug it for like 3 days though lol

Replying to PulseCaster: Camera interpolation in platform-local space works really well until you need to...

The blend-out transition is genuinely the hardest part of this whole system. What ended up working for me: when the player leaves the platform, I don't snap back to world space at all — I take the current platform-local camera position, convert it to world space at that exact moment, and continue interpolating from there. The blend-out becomes a gradual shift from 'tracking platform velocity' to 'standard world-space damping', with no position discontinuity at the handoff point.

I also scale the blend-out duration based on how much residual velocity the platform was contributing when the player left. Stepping off a slow elevator is nearly instant. Jumping off a fast-moving ship takes a full second or two to fully decouple. That scaling alone made it feel intentional rather than janky.

the thing that finally fixed moving platforms for me was storing the platform's velocity separately and adding it to the interpolated render position, not the physics position. so your physics sim is still clean fixed-timestep, but at render time you're like: renderPos = Lerp(prevPhysPos, currPhysPos, alpha) + platformVelocity * renderDeltaTime. feels wrong but it makes the visual snap go away completely. took way too long to figure out that the interpolation and the platform offset had to live at different layers.

Replying to BinaryVale: the nested platform case is where this whole system starts showing its seams. ev...

the nested platform floating point thing is brutal. my janky solution was to store all child platform transforms relative to their parent in the physics tick and only compose them at render time. means the accumulated error only happens during the short composition step instead of snowballing tick-over-tick. still not perfect on 5+ levels of nesting but honestly if your game has 5 nested moving platforms that's a different problem lol

Replying to EmberMoth: The blend-out transition is genuinely the hardest part of this whole system. Wha...

The "sample the interpolated world-space velocity at departure and use it as your new anchor" approach is exactly what I landed on too. The edge case that gets me is when the platform was mid-acceleration at the moment the player leaves. The instantaneous velocity at that frame isn't representative of what the camera was "feeling", so the blend-out has a subtle pop. I ended up doing a short weighted average over the last 4-5 frames of platform velocity before departure, which smooths it considerably. Small thing but it matters on fast-moving platforms.

Replying to FluxReed: adding an edge case I don't see covered here: platforms riding other platforms. ...

the nested platform case is where this whole system starts showing its seams. even if you handle the chain correctly, floating point accumulates fast when you're composing multiple interpolated transforms. outer platform interpolates, inner platform interpolates relative to that, and by the time you get to the player standing on top you've got enough drift to cause visible jitter at high relative speeds.

I ended up computing the full world-space interpolated transform for each platform in the chain rather than compositing local→parent, which at least keeps the error bounded to one interpolation step instead of N.

reaction

one thing I don't see in this thread: what are people doing about camera interpolation relative to platforms? like your character is correctly interpolated relative to the platform, great. but your camera is chasing a world-space transform. if the platform moves fast enough between physics ticks the camera lags in a way that reads as a bug even if technically everything is correct. I ended up having the camera interpolate relative to the platform too if the player is standing on one, which adds another layer of parent-tracking complexity. curious if there's a cleaner pattern.

Replying to CobaltVale: camera interpolation on platforms is genuinely one of those problems that sounds...

Camera interpolation in platform-local space works really well until you need to blend out of it, like when the player jumps off the platform and the camera needs to stop following it. The transition back to world space is abrupt if you don't handle it explicitly. I track a "camera attachment weight" that lerps from 1 to 0 over a short window when the player leaves the platform, then compose the final camera position from both spaces weighted together. Adds some complexity but the blend out feels natural instead of snapping.

adding an edge case I don't see covered here: platforms riding other platforms. if you have an inner platform moving relative to an outer one (elevator on a moving ship, etc.), RiftMesh's velocity-on-render-position fix only handles one level of the hierarchy. anything standing on the inner platform gets the wrong interpolated offset.

ended up maintaining a simple parent chain and accumulating platform velocities up it. not pretty but it works. tbh by the time I finished that fix I started wondering if my physics design needed a rethink more than another patch.

Moonjump
Forum Search Shader Sandbox
Sign In Register