## Stuttering & Fixed Timesteps

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Bryant
Prole
Posts: 8
Joined: Wed Sep 28, 2011 12:12 am
Contact:

### Re: Stuttering & Fixed Timesteps

Ha, good points Taehl. I've only ever worked with variable timesteps before, so I'm learning about this topic as I go along

One of the XNA developers summed up the "Fix Your Timestep" article in a way I found helpful:
A few games use a hybrid approach (as in the link that was posted above). They use a variable timestep for Draw, calling it as fast as the GPU retrace will allow, but apply fixed timestep CPU logic to control the frequency of Update. To smooth out the visual results (since Draw may now be called half way in between two Update time locations, or there could even be more than one Draw per Update), they interpolate the game state some fraction between two different Update results when drawing at times that do not exactly align to a fixed timestep tick point. This allows them to maintain as good as possible monitor sync, while still being able to write their physics assuming a nice simple fixed timestep. The downside is the extra code for lining up the two timelines and doing the state interpolation, which can be a serious PITA. There's nothing built into the XNA Framework to help you if you want to use this mode: you'd have to start with our variable timestep and then implement your own logic on top of that.
The accumulator method takes care of the fixed update and variable draw timesteps. The missing link is the state interpolation to smooth out the end results. I have no idea what an implementation of that would look like, but I guess I just need to take a stab at it

(Unless someone here has already done it? )

Taehl
Dreaming in associative arrays
Posts: 1024
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

### Re: Stuttering & Fixed Timesteps

State interpolation sounds like an awful idea to me. Not only does it mean you need to keep the current state, but also the last state (meaning, twice as much memory usage); you need to do interpolation on all that (meaning eating more CPU); and the controls would always lag at greater than or equal to [the time it takes to update the state] + [the time you wait between state updates] (since the time the player touches a control is in the "future" of the game's state, since you have to wait for the next update before the control will have any affect).

So, you're using more RAM and CPU, and intentionally lagging the controls (a sin, in my mind!), all for what, exactly? I fail to see how this scheme would offer a smoother experience than without it (to say nothing of performance in general).
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.

slime
Solid Snayke
Posts: 2853
Joined: Mon Aug 23, 2010 6:45 am
Contact:

### Re: Stuttering & Fixed Timesteps

Taehl wrote:State interpolation sounds like an awful idea to me. Not only does it mean you need to keep the current state, but also the last state (meaning, twice as much memory usage); you need to do interpolation on all that (meaning eating more CPU); and the controls would always lag at greater than or equal to [the time it takes to update the state] + [the time you wait between state updates] (since the time the player touches a control is in the "future" of the game's state, since you have to wait for the next update before the control will have any affect).

So, you're using more RAM and CPU, and intentionally lagging the controls (a sin, in my mind!), all for what, exactly? I fail to see how this scheme would offer a smoother experience than without it (to say nothing of performance in general).
The linked article (titled "Fix your timestep!") explains it very nicely. The extra amount of CPU and RAM usage is negligible, and a fixed physics timestep is necessary in some situations - because of the way physics engines work, a deterministic simulation isn't really possible with a variable timestep.

A more optimal solution would be to separate rendering from updating entirely by putting everything except rendering into its own thread, but that's another topic.

Xgoff
Party member
Posts: 211
Joined: Fri Nov 19, 2010 4:20 am

### Re: Stuttering & Fixed Timesteps

Bryant wrote:Xgoff -- Floating point precision is exactly the problem I have with a variable timestep Have you tried implementing your own fixed timestep in LÖVE yet?
no i've just been using the default setup for now. actually whether or not i even make this game in love depends on whether or not i decide on 3d graphics (technically it'd still have 2d gameplay, but adding all the relevant 3d code would probably be annoying)

although atm i'm working on other things

ivan
Party member
Posts: 1530
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Stuttering & Fixed Timesteps

First of, the box2d documentation says that b2worlds should be updated with a constant timestep.
If your timestep varies you may get unstable behavior with certain joints, etc.

Code: Select all

function love.update(dt)
local accum = dt
while accum > 0 do		-- accumulator for physics! no more penetration!
local dt = math.min( 1/50, accum )	-- use whatever max dt value works best for you
accum = accum - dt

-- now, do whatever it is you need to do with dt
end
end
That's not exactly how accumulators are supposed to work.
Your dt varies if accum is < 1/50.
Also, your accumulator doesn't really 'accumulate' anything since you set it to "dt" at each update.
If you are getting 'penetration' (usually called 'tunneling') with a particular body you might want to set its "bullet" flag to true.

The following code is from a short tutorial that I wrote on box2D:

Code: Select all

accumulator = 0

function Update ( delta )
accumulator = accumulator + delta

while accumulator > 0.016 do
world:Step ( 0.016, 10 )
accumulator = accumulator - 0.016
end
end

pancakepalace
Prole
Posts: 40
Joined: Wed Aug 03, 2011 3:13 pm

### Re: Stuttering & Fixed Timesteps

Doesn't the stuttering occur because you are not moving the player the same pixel distance on every instance of love.draw(). Your pixel distance depends on many variables including some that are floating point like dt so that after being floored to the nearest x and y, your distance changes making a stutter.

Couldn't you simply set the player speed to an integer that doesn't change. This would mean that at every dt interval your player moves this speed (or distance) in pixels. If you then want to calculate the speed per second so that it doesn't depend on framerate your could then get the number of FPS from dt and adjust the speed accordingly.

I very well might be missing something.

Code: Select all

player = {}

player.image = love.graphics.newImage( 'content/textures/player.png' )
player.x = 0
player.y = 0
player.speed = 3
love.graphics.setBackgroundColor( 245, 245, 245 )
end

function love.update(dt)
if love.keyboard.isDown( "up" ) then
player.y = player.y - player.speed
end

if love.keyboard.isDown( "down" ) then
player.y = player.y + player.speed
end

if love.keyboard.isDown( "left" ) then
player.x = player.x - player.speed
end

if love.keyboard.isDown( "right" ) then
player.x = player.x + player.speed
end
end

function love.draw()
love.graphics.draw( player.image, player.x, player.y )
end


Taehl
Dreaming in associative arrays
Posts: 1024
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

### Re: Stuttering & Fixed Timesteps

ivan wrote: That's not exactly how accumulators are supposed to work.
Your dt varies if accum is < 1/50.
Also, your accumulator doesn't really 'accumulate' anything since you set it to "dt" at each update.
If you are getting 'penetration' (usually called 'tunneling') with a particular body you might want to set its "bullet" flag to true.
All well and good. But I'm not using Box2D, so I don't have a "bullet" flag to set to true. My game works fine with variable timesteps, it just needs to make sure that things don't move more than half a meter in one update (hence, a (quite high) speed limit and the code I posted). Anyway, it doesn't matter if it doesn't work "exactly" like some article says it should - it works flawlessly. Underlife can be running at 2 FPS and still have no problems.

And who said anything about Box2D anyway?
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.

Bryant
Prole
Posts: 8
Joined: Wed Sep 28, 2011 12:12 am
Contact:

### Re: Stuttering & Fixed Timesteps

A friend of mine gave me another technique to try out. It's not a true fixed timestep update loop, so it might not work for my situation. But it produces relatively smooth, jitter-free movement. It's still not perfect, but it seems to produce, at least for me, smoother results than previous update loops we've discussed.

Here's the meat of it:

Code: Select all

function love.run()

local totalTime = 0.0
local deltaTime = 1 / 200

local currentTime = love.timer.getMicroTime()
local accumulator = 0.0

-- Main loop time.
while true do

local newTime = love.timer.getMicroTime()
local frameTime = newTime - currentTime

if frameTime > 0.25 then
frameTime = 0.25
elseif frameTime < 0.0 then -- Handle the case where getMicroTime() rolls over back to 0
frameTime = deltaTime
end

currentTime = newTime

accumulator = accumulator + frameTime

while( accumulator >= deltaTime ) do

if love.update then love.update(1.0) end

totalTime = totalTime + deltaTime
accumulator = accumulator - deltaTime

end

if love.update then love.update(accumulator / deltaTime) end
accumulator = 0.0

if love.graphics then
love.graphics.clear()

if love.draw then love.draw() end
love.graphics.present()
end

-- See the attached .love file for more

There are 2 major things to note. I'm running the update loop at 200 frames per second, passing a delta time of 1 to each update. If, at the end of those 200 updates, I still have some unaccounted for time, I'll run update() again with a fraction of my previous delta time (this step is what prevents it from being a perfect fixed timestep update loop).

How does this run on your machines? Jittery? Smooth?
Attachments
JitterTest.love

kraftman
Party member
Posts: 277
Joined: Sat May 14, 2011 10:18 am

### Re: Stuttering & Fixed Timesteps

smoooooth

ivan
Party member
Posts: 1530
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Stuttering & Fixed Timesteps

My game works fine with variable timesteps, it just needs to make sure that things don't move more than half a meter in one update
Bryant wrote:at the end of those 200 updates, I still have some unaccounted for time, I'll run update() again with a fraction of my previous delta time (this step is what prevents it from being a perfect fixed timestep update loop)
I don't really understand why you would want to use accumulators if you delta is allowed to vary.
A simpler solution would be to simply clamp the delta value.

### Who is online

Users browsing this forum: No registered users and 7 guests