I've read that the speed of game objects should not be hindered by FPS but instead should be based on time. How can I seperate the update/draw code to maximize performance without limiting the drawing rate and provide a constant logic update rate based on time?

My current pseudo code is as follows

    if (ticksElapsed() > 100)
        ticks+= ticksElapsed();

The problem is the drawing code hinders the performance of the update() rate. And it consumes 100% cpu because if sleep is thrown in, it throws off both drawing/logic functions.

I am also using SDL and it doesn't seem to have a vsync option. I've also heard of the terms fixed and variable time-stepping however I'm not sure how that can be done with sleep()

  • 1
    \$\begingroup\$ You don't need to waste 100% CPU power just for waiting, put a sleep(0) at the end of the while loops if ticksElapsed() < 100. The OS will return to the thread immediately if there is no other thread that wants to run. But not wasting 100% CPU power anymore. \$\endgroup\$ – Maik Semder Jul 10 '11 at 14:56
  • \$\begingroup\$ However, best solution for such a 1 thread setup is to use vsync, if you cant vsync, then call sleep(0) in a loop until you reached the target frame rate, then update and draw \$\endgroup\$ – Maik Semder Jul 10 '11 at 15:09

In your code snippet it looks like you're trying to run your game in fixed-time step mode by busy-waiting if your drawing and updating took less then 15ms (60fps). This is possible and you guessed right that this can't be done using a sleep call because you don't exactly know how long you're going to sleep. The busy-waiting-loop is the good solution.

However consider the case where your updating and drawing exceed 15ms, you now have the game drawing and updating to slow. You can now do either two things: detect this state and drop frames (skip drawing and go straight to updating until you are in sync again) however if the computer is just to slow it will never catch up.

An other solution is to make your update logic fixed-time independent. You don't need a separate thread for this, you just have to respecify how fast things should move. Instead of 5pixels per tick, you should use 50pixels per second. You would need a high precision timer to achieve this, and all your update logic should be able to access the timer to see how much time passed since last update.

Basically you go from:

void UpdatePlayer()
 player.x += 10;


void UpdatePlayer(float elapsedSeconds) //the total seconds elapsed since last update
 player.x += walkspeed * elapsedSeconds;
| improve this answer | |
  • \$\begingroup\$ So my engine will always consume 100% and there's nothing I can really do about it? \$\endgroup\$ – Oskenso Kashi Jul 9 '11 at 19:48
  • 1
    \$\begingroup\$ It will consume as much cycles as the scheduler allows it to get, but that's not really an issue since you can't really do a lot of other things while you're playing a game :). \$\endgroup\$ – Roy T. Jul 10 '11 at 7:26
  • \$\begingroup\$ @Oskenso However, it is a problem if you use more than 1 thread, then the main thread will not let the others run as much as they could, wasting a lot of computational power in the while loop, you really should consider a sleep \$\endgroup\$ – Maik Semder Jul 10 '11 at 14:09
  • \$\begingroup\$ @Maik Semder: do you have a solution for sleep(x) not being accurate? After the sleep interval has passed, the thread is ready to run. But a ready thread is not guaranteed to run immediately. That's up to the scheduler. When you're using two threads there are other solutions, for that see this excellent article: altdevblogaday.com/2011/07/03/threading-and-your-game-loop \$\endgroup\$ – Roy T. Jul 10 '11 at 14:16
  • 1
    \$\begingroup\$ @Roy sleep(0) is the solution. It returns immediately if there is no other thread that wants to run (Sleep WinAPI) and gives other threads the chance to run. If the other thread will not give the main thread the chance to run in return, then you have a threading problem, but blocking everything else by not calling sleep in the first place makes it even worse and is hardly a solution. The key is to call sleep(0) and test the elapsed time until you hit your target fixed frame rate, so you dont waste 100 % CPU just for waiting. \$\endgroup\$ – Maik Semder Jul 10 '11 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.