Hey everyone I'm new to LÖVE and Lua, and I've been messing around with the examples you've all posted online. The level of community support this framework has is refreshing
I created a simple project that features a box you can move around with the arrow keys. I'm noticing, however, that the box stutters on occasion. It's minor, and you probably wouldn't notice it if a lot was happening on the screen, but it's definitely there.
I thought this might be because the update and draw functions were falling out of sync. But that shouldn't be the case because love.run calls draw() immediately after update() every time, right?
I tried a few different approaches to my update loop which you can see commented out in the .love file. I tried a fixed timestep without dt, a fixed timestep with dt, and a variable timestep with dt. They all have stuttering problems
Next I tried turning off vsync, but that slowed everything down to a crawl (shouldn't it have sped everything up? I might not have tested it with the three update loop configurations...).
Is there any way around this? I know a lot of people link to this article about fixing your timestep. Maybe I'm missing the step about integrating or interpolating my moving object(s)?
The default LÖVE app with the spinning logo and scrolling starfield runs so smoothly! What am I doing differently?
Thank you all for the help
Stuttering & Fixed Timesteps
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Stuttering & Fixed Timesteps
- Attachments
-
- StutterTest.love
- (7.6 KiB) Downloaded 506 times
Last edited by Bryant on Thu Sep 29, 2011 7:00 am, edited 1 time in total.
Re: Stuttering
The accumulator is wierd. Don't do it. The "variable timestep with dt" is better. Doesn't stutter at all for me.
draw() and update(dt) are run independently of each other. That's a good thing.
draw() and update(dt) are run independently of each other. That's a good thing.
My game called Hat Cat and the Obvious Crimes Against the Fundamental Laws of Physics is out now!
Re: Stuttering
I agree that the accumulator is weird But what other option is there for games that require a high level of precision like a competitive fighting game or a rhythm game? In those cases a single frame makes all the difference, and a variable timestep won't suffice.
- slime
- Solid Snayke
- Posts: 3166
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Stuttering & Fixed Timesteps
Yeah, for a fixed update loop with a variable framerate (which is generally what you want), you'll need to rewrite the love.run function to have a love.update accumulator as well as a love.draw interpolator.Bryant wrote:Is there any way around this? I know a lot of people link to this article about fixing your timestep. Maybe I'm missing the step about integrating or interpolating my moving object(s)?
The default LÖVE app with the spinning logo and scrolling starfield runs so smoothly! What am I doing differently?
Thank you all for the help
The default variable update and variable framerate loop shouldn't cause any problems usually though, as long as you multiply the appropriate things by the deltatime.
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: Stuttering & Fixed Timesteps
I use an accumulator technique in my game Underlife, and it runs beautifully. Here's basically what I do:
I hope that helps you.
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
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+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Stuttering
I might be wrong, but it seems to me that the variable timestep actually gives you more control over those cases. I don't see what problems a fixed frame rate would solve that can't be done better with a variable one.Bryant wrote:I agree that the accumulator is weird But what other option is there for games that require a high level of precision like a competitive fighting game or a rhythm game? In those cases a single frame makes all the difference, and a variable timestep won't suffice.
When I write def I mean function.
- slime
- Solid Snayke
- Posts: 3166
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Stuttering
I suggest you read http://gafferongames.com/game-physics/f ... -timestep/ (linked in the OP), it makes excellent points.kikito wrote:I might be wrong, but it seems to me that the variable timestep actually gives you more control over those cases. I don't see what problems a fixed frame rate would solve that can't be done better with a variable one.Bryant wrote:I agree that the accumulator is weird But what other option is there for games that require a high level of precision like a competitive fighting game or a rhythm game? In those cases a single frame makes all the difference, and a variable timestep won't suffice.
However, a fixed update timestep is usually only needed in multiplayer games with high precision physics where it's much better to be deterministic.
Re: Stuttering
or, in my game (assuming i ever work on it), a timing system. if i call wait() i want an object to wait *exactly* some number of ticks, not plus or minus some number of milliseconds. this also means floats are out, unless they're limited to being exactly representableslime wrote:I suggest you read http://gafferongames.com/game-physics/f ... -timestep/ (linked in the OP), it makes excellent points.
However, a fixed update timestep is usually only needed in multiplayer games with high precision physics where it's much better to be deterministic.
Re: Stuttering & Fixed Timesteps
Thanks for all the great responses!
slime -- A fixed update loop with a variable framerate is exactly what I'm looking for. I'll try rewriting love.run() with the accumulator method. But interpolating any "leftover" time in the draw() function is where I get confused (in the "Fix Your Timestep" article, this is where the author uses a "blending factor" to linearly interpolate the simulation before rendering).
Also, maybe I'm misunderstanding something, but is LÖVE's rendering really decoupled from the update loop? Just looking at the default implementation of love.run(), it looks like update() and draw() are called on the same timestep. So draw() will never be called more frequently than update(). If anything, with the accumulator method, draw() might be called *less* frequently. If that's true, jittering/stuttering seems unavoidable
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?
Thanks again, everyone. As a side note, here's a good article explaining XNA's approach to the problem.
EDIT: Two more good XNA articles explaining the problem and potential solutions: Part 1 and Part 2.
slime -- A fixed update loop with a variable framerate is exactly what I'm looking for. I'll try rewriting love.run() with the accumulator method. But interpolating any "leftover" time in the draw() function is where I get confused (in the "Fix Your Timestep" article, this is where the author uses a "blending factor" to linearly interpolate the simulation before rendering).
Also, maybe I'm misunderstanding something, but is LÖVE's rendering really decoupled from the update loop? Just looking at the default implementation of love.run(), it looks like update() and draw() are called on the same timestep. So draw() will never be called more frequently than update(). If anything, with the accumulator method, draw() might be called *less* frequently. If that's true, jittering/stuttering seems unavoidable
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?
Thanks again, everyone. As a side note, here's a good article explaining XNA's approach to the problem.
EDIT: Two more good XNA articles explaining the problem and potential solutions: Part 1 and Part 2.
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: Stuttering & Fixed Timesteps
The accumulator code I posted above is aimed at running updates more times than it draws. Or as the article you linked to phrased it, "Call Update extra times (without calling Draw) until we catch up.".Bryant wrote:slime -- A fixed update loop with a variable framerate is exactly what I'm looking for. I'll try rewriting love.run() with the accumulator method. But interpolating any "leftover" time in the draw() function is where I get confused (in the "Fix Your Timestep" article, this is where the author uses a "blending factor" to linearly interpolate the simulation before rendering).
You're right - with Love2D's default love.run(), you get exactly one love.update() and then one love.draw(). And with my accumulator code, you'll get more updates than drawn frames.Bryant wrote:Also, maybe I'm misunderstanding something, but is LÖVE's rendering really decoupled from the update loop? Just looking at the default implementation of love.run(), it looks like update() and draw() are called on the same timestep. So draw() will never be called more frequently than update(). If anything, with the accumulator method, draw() might be called *less* frequently. If that's true, jittering/stuttering seems unavoidable
If you want to draw frames faster than you're updating the game, you'll need some sort of bizarre code which predicts object movement and integrates the prediction with reality once an update rolls around. And you'll need to do all this faster than it takes to just update the world. But honestly, this strikes me as patently crazy.
Also, in your .love file, FIXED TIMESTEP WITH DT and VARIABLE TIMESTEP WITH DT both run smoothly for me, while FIXED TIMESTEP WITHOUT DT is slightly less smooth.
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+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Who is online
Users browsing this forum: No registered users and 6 guests