EpichinoM2
EpichinoM2

Reputation: 11

How can you make the updates/second constant?

As far as I know, love.update and love.draw is called every frame. You can turn vsync off (unlimited calls to love.update) or leave it on (fixed to refresh rate). Since different computers have different refresh rates, you need to be able to support different ups's, otherwise the game will run at different speeds for different computers.

There are 2 solutions I can think of:

  1. Cap UPS.

  2. Run at an arbitrary UPS.

There were a few issues with 2, so I think a constant UPS might be better. My computer's refresh rate is 57Hz so I used that in the code.

function love.update(dt)
  t = t + dt
  while t >= 1/57 do
    t = t - 1/57
    --stuff
  end
end

The game runs fine if I turn vsync on, but if it's off, then it's slightly jittery and I think it would probably be like that regardless of vsync on other PC's. Is there a way to cap the UPS better or should I just use solution 2?

Upvotes: 1

Views: 1241

Answers (3)

mDeram
mDeram

Reputation: 91

Be careful with vsync since some computer screens can run at different frame-rate (like 60fps, 120fps...). And even with computer screens that run at the same frame-rate, enabling vsync in love2d is a setting that can be overridden by the graphic card settings. So you should always consider using the delta-time (dt). Refer to @nepta answer to know how the delta-time should be used.

Upvotes: 0

nepta
nepta

Reputation: 31

you need to use the dt in update function, let's say you have a sprite moving 1 pixel every frame

function love.update(dt)
   sprite.x = sprite.x + 1
end

for you with a refresh rate of 57 fps the sprite will move of 57 pixel per second, but others would see it move at say 60 pixel per second

function love.update(dt)
   sprite.x = sprite.x + 60*dt
end

now at 57 fps, you call 57 time update in one second and your sprite would move exactly 60 pixel (60*(1/57)*57), and others running at 60fps would also see it moving of 60 pixels (60*(1/60)*60)

using dt you are doing computation time relative, not frame relative discarding the problem altogether

Upvotes: 1

SkippyNBS
SkippyNBS

Reputation: 777

It seems like you know how to set vsync, but here's the code I'm using in love.load() to set it:

love.window.setMode(1, 1, {vsync = false, fullscreen = true})

At the start of my update loop I have the following code:

self.t1 = love.timer.getTime()

This grabs the time at the beginning of the loop and is paired with the following code at the end end of the loop:

self.delta = love.timer.getTime() - self.t1
if self.delta < self.fps then
    -- sleep to maintain 60fps
    love.timer.sleep(self.fps - self.delta)
end
-- calculate frame rate
self.delta = love.timer.getTime() - self.t1
self.frameRate = 1 / self.delta

If your computer is able to run the update at faster than 60FPS then the game will sleep at the end of the update loop to enforce a constant frame rate. Unfortunately this only caps the frame rate (solution 1 in your post). That being said, this method runs with no jitters (I have tested on multiple Windows machines).

I believe I got this method from this link.

Upvotes: 0

Related Questions