Fixed timestep physics update with unlimited framerate

Hello guys,

I have some problem with using fixed timestep collision detection with unlimited framerate movement logic. Let’s say I have 30 FPS fixed timestep for collision detection and unlimited (1000+ FPS) of movement update, and I have 2 boxes colliding. The update loop of the movement is unlimited, meaning that the first box can intersect with the second box and the draw call will happen, so that it’s visible for the player that the 2 boxes have intersected, then (at some point) the fixed update of the collision detection will kick in and push the first box out of the second as a collision response.
This create a “bouncy” effect when the player falls down to the ground or onto any other collider: it is briefly rendered slightly inside the other collider and then being pushed out of it, all because of the difference of the framerate.
Is there a way to smartly combine fixed timestep physics update with unlimited movement logic without having this weird bouncy effect?

Thanks!

I’d say that with a physics loop that runs less that 60 times a second, it’s going to be difficult to prevent visible “bounciness” with collision responses; especially with fast moving objects. Heck, rocket league has a fixed physics loop that runs 120 times a second, regardless of how low or high the update frames run. You could try to make 30 work, however if the amount of time and effort (as well as computations) that are put in doesn’t end up much of a positive tradeoff, then maybe just raise the physics iterations until it looks good. You could try blending the intersected position and the corrected position to make it look better, but it’s still not going to look as good as just raising physics iterations, IMO.

1 Like

Actually I kinda solved it, or at least I found a better way to do things.
I have changed my code and now I’m doing all the update movement calculations in the fixedupdate loop, always before the collision engine runs (which is also running in the fixedupdate). This has completely elimimated the bouncyness and overlap issues, becase after every movement calculation, the collision engine fixes the positions and the rendering will only run after both has finished.
However, it caused the game look like as it was running with 30 FPS (that’s my fixedupdate timestep) regardless of the actual framerate, because the character position was now only updated 30 times a second. I solves this by interpolating between the last position and current position using how far we in the current frame as alpha value, and now it looks smooth while the physics calculations are only running with fixed 30 FPS, plus some other logic (movement, gravity, etc) has also beem moved to the fixedupate, which decreased the CPU load! It looks really nice now, but there is still a slight, barely noticable visual difference between the “regular 60 FPS” (with 60 FPS physics update) and the above method, but I expect to be able to solve it by figuring out a better frametime/alpha calculation.

i run physics update to up to 2000 fps and draw at 60fps… then i can clamp my physics to anything less… by measureing how long the update took. but calls like Sleep , if you wanna throttle the physics, depend on the timer resolution.

my physics/ collider runs on separate thread… than draw in parallel whenever system calls draw usually 60 time a sec.
I used to get a waithandle, release it after draw and same for physics, waitforaccess. …because draw reads teh body list and body position, since i access the position and list which can be changed during a physics update.

i dont use locks anymore because locks on android time out and can take 16 ms. on windows u need to call [System.Runtime.InteropServices.DllImport(“winmm.dll”, EntryPoint = “timeBeginPeriod”)] set to 4ms or even 1ms or its 16, basically a full 60 fps frame, useless. Then u can use locks at > 60 fps… else ur timers, ur locks, your wait, semaphores, and even sleep(4) could be actually sleeingp 16 ms. i copy all the visible state when physics is done to a drawlist, draw the last copied frame body list, either keep a list of that for replays view or toss the old frames. this is the way.