deWiTTERS Game Loop

      117 Comments on deWiTTERS Game Loop

The game loop is the heartbeat of every game, no game can run without it. But unfortunately for every new game programmer, there aren’t any good articles on the internet who provide the proper information on this topic. But fear not, because you have just stumbled upon the one and only article that gives the game loop the attention it deserves. Thanks to my job as a game programmer, I come into contact with a lot of code for small mobile games. And it always amazes me how many game loop implementations are out there. You might wonder yourself how a simple thing like that can be written in different ways. Well, it can, and I will discuss the pros and cons of the most popular implementations, and give you the (in my opinion) best solution of implementing a game loop.

(Thanks to Kao Cardoso Félix this article is also available in Brazilian Portuguese, and thanks to Damian/MORT in Polish)

The Game Loop

Every game consists of a sequence of getting user input, updating the game state, handling AI, playing music and sound effects, and displaying the game. This sequence is handled through the game loop. Just like I said in the introduction, the game loop is the heartbeat of every game. In this article I will not go into details on any of the above mentioned tasks, but will concentrate on the game loop alone. That’s also why I simplified the tasks to only 2 functions: updating the game and displaying it. Here is some example code of the game loop in it’s most simplest form:

    bool game_is_running = true;

    while( game_is_running ) {
        update_game();
        display_game();
    }

The problem with this simple loop is that it doesn’t handle time, the game just runs. On slower hardware the game runs slower, and on faster hardware faster. Back in the old days when the speed of the hardware was known, this wasn’t a problem, but nowadays there are so many hardware platforms out there, that we have to implement some sort of time handling. There are many ways to do this, and I’ll discuss them in the following sections. First, let me explain 2 terms that are used throughout this article:

FPS
FPS is an abbreviation for Frames Per Second. In the context of the above implementation, it is the number of times display_game() is called per second.
Game Speed
Game Speed is the number of times the game state gets updated per second, or in other words, the number of times update_game() is called per second.

FPS dependent on Constant Game Speed

Implementation

An easy solution to the timing issue is to just let the game run on a steady 25 frames per second. The code then looks like this:

    const int FRAMES_PER_SECOND = 25;
    const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;

    DWORD next_game_tick = GetTickCount();
    // GetTickCount() returns the current number of milliseconds
    // that have elapsed since the system was started

    int sleep_time = 0;

    bool game_is_running = true;

    while( game_is_running ) {
        update_game();
        display_game();

        next_game_tick += SKIP_TICKS;
        sleep_time = next_game_tick - GetTickCount();
        if( sleep_time >= 0 ) {
            Sleep( sleep_time );
        }
        else {
            // Shit, we are running behind!
        }
    }

This is a solution with one huge benefit: it’s simple! Since you know that update_game() gets called 25 times per second, writing your game code is quite straight forward. For example, implementing a replay function in this kind of game loop is easy. If no random values are used in the game, you can just log the input changes of the user and replay them later. On your testing hardware you can adapt the FRAMES_PER_SECOND to an ideal value, but what will happen on faster or slower hardware? Well, let’s find out.

Slow hardware

If the hardware can handle the defined FPS, no problem. But the problems will start when the hardware can’t handle it. The game will run slower. In the worst case the game has some heavy chunks where the game will run really slow, and some chunks where it runs normal. The timing becomes variable which can make your game unplayable.

Fast hardware

The game will have no problems on fast hardware, but you are wasting so many precious clock cycles. Running a game on 25 or 30 FPS when it could easily do 300 FPS… shame on you! You will lose a lot of visual appeal with this, especially with fast moving objects. On the other hand, with mobile devices, this can be seen as a benefit. Not letting the game constantly run at it’s edge could save some battery time.

Conclusion

Making the FPS dependent on a constant game speed is a solution that is quickly implemented and keeps the game code simple. But there are some problems: Defining a high FPS will pose problems on slower hardware, and defining a low FPS will waste visual appeal on fast hardware.

Game Speed dependent on Variable FPS

Implementation

Another implementation of a game loop is to let it run as fast as possible, and let the FPS dictate the game speed. The game is updated with the time difference of the previous frame.

    DWORD prev_frame_tick;
    DWORD curr_frame_tick = GetTickCount();

    bool game_is_running = true;
    while( game_is_running ) {
        prev_frame_tick = curr_frame_tick;
        curr_frame_tick = GetTickCount();

        update_game( curr_frame_tick - prev_frame_tick );
        display_game();
    }

The game code becomes a bit more complicated because we now have to consider the time difference in the update_game() function. But still, it’s not that hard. At first sight this looks like the ideal solution to our problem. I have seen many smart programmers implement this kind of game loop. Some of them probably wished they would have read this article before they implemented their loop. I will show you in a minute that this loop can have serious problems on both slow and fast (yes, FAST!) hardware.

Slow Hardware

Slow hardware can sometimes cause certain delays at some points, where the game gets “heavy”. This can definitely occur with a 3D game, where at a certain time too many polygons get shown. This drop in frame rate will affect the input response time, and therefore also the player’s reaction time. The updating of the game will also feel the delay and the game state will be updated in big time-chunks. As a result the reaction time of the player, and also that of the AI, will slow down and can make a simple maneuver fail, or even impossible. For example, an obstacle that could be avoided with a normal FPS, can become impossible to avoid with a slow FPS. A more serious problem with slow hardware is that when using physics, your simulation can even explode!

Fast Hardware

You are probably wondering how the above game loop can go wrong on fast hardware. Unfortunately, it can, and to show you, let me first explain something about math on a computer. The memory space of a float or double value is limited, so some values cannot be represented. For example, 0.1 cannot be represented binary, and therefore is rounded when stored in a double. Let me show you using python:

>>> 0.1
0.10000000000000001

This itself is not dramatic, but the consequences are. Let’s say you have a race-car that has a speed of 0.001 units per millisecond. After 10 seconds your race-car will have traveled a distance of 10.0. If you split this calculation up like a game would do, you have the following function using frames per second as input:

>>> def get_distance( fps ):
...     skip_ticks = 1000 / fps
...     total_ticks = 0
...     distance = 0.0
...     speed_per_tick = 0.001
...     while total_ticks < 10000:
...             distance += speed_per_tick * skip_ticks
...             total_ticks += skip_ticks
...     return distance

Now we can calculate the distance at 40 frames per second:

>>> get_distance( 40 )
10.000000000000075

Wait a minute… this is not 10.0??? What happened? Well, because we split up the calculation in 400 additions, a rounding error got big. I wonder what will happen at 100 frames per second…

>>> get_distance( 100 )
9.9999999999998312

What??? The error is even bigger!! Well, because we have more additions at 100 fps, the rounding error has more chance to get big. So the game will differ when running at 40 or 100 frames per second:

>>> get_distance( 40 ) - get_distance( 100 )
2.4336088699783431e-13

You might think that this difference is too small to be seen in the game itself. But the real problem will start when you use this incorrect value to do some more calculations. This way a small error can become big, and fuck up your game at high frame rates. Chances of that happening? Big enough to consider it! I have seen a game that used this kind of game loop, and which indeed gave trouble at high frame rates. After the programmer found out that the problem was hiding in the core of the game, only a lot of code rewriting could fix it.

Conclusion

This kind of game loop may seem very good at first sight, but don’t be fooled. Both slow and fast hardware can cause serious problems for your game. And besides, the implementation of the game update function is harder than when you use a fixed frame rate, so why use it?

Constant Game Speed with Maximum FPS

Implementation

Our first solution, FPS dependent on Constant Game Speed, has a problem when running on slow hardware. Both the game speed and the framerate will drop in that case. A possible solution for this could be to keep updating the game at that rate, but reduce the rendering framerate. This can be done using following game loop:

    const int TICKS_PER_SECOND = 50;
    const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
    const int MAX_FRAMESKIP = 10;

    DWORD next_game_tick = GetTickCount();
    int loops;

    bool game_is_running = true;
    while( game_is_running ) {

        loops = 0;
        while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
            update_game();

            next_game_tick += SKIP_TICKS;
            loops++;
        }

        display_game();
    }

The game will be updated at a steady 50 times per second, and rendering is done as fast as possible. Remark that when rendering is done more than 50 times per second, some subsequent frames will be the same, so actual visual frames will be dispayed at a maximum of 50 frames per second. When running on slow hardware, the framerate can drop until the game update loop will reach MAX_FRAMESKIP. In practice this means that when our render FPS drops below 5 (= FRAMES_PER_SECOND / MAX_FRAMESKIP), the actual game will slow down.

Slow hardware

On slow hardware the frames per second will drop, but the game itself will hopefully run at the normal speed. If the hardware still can’t handle this, the game itself will run slower and the framerate will not be smooth at all.

Fast hardware

The game will have no problems on fast hardware, but like the first solution, you are wasting so many precious clock cycles that can be used for a higher framerate. Finding the balance between a fast update rate and being able to run on slow hardware is crucial.

Conclusion

Using a constant game speed with a maximum FPS is a solution that is easy to implement and keeps the game code simple. But there are still some problems: Defining a high FPS can still pose problems on slow hardware (but not as severe as the first solution), and defining a low FPS will waste visual appeal on fast hardware.

Constant Game Speed independent of Variable FPS

Implementation

Would it be possible to improve the above solution even further to run faster on slow hardware, and be visually more atractive on faster hardware? Well, lucky for us, this is possible. The game state itself doesn’t need to be updated 60 times per second. Player input, AI and the updating of the game state have enough with 25 frames per second. So let’s try to call the update_game() 25 times per second, no more, no less. The rendering, on the other hand, needs to be as fast as the hardware can handle. But a slow frame rate shouldn’t interfere with the updating of the game. The way to achieve this is by using the following game loop:

    const int TICKS_PER_SECOND = 25;
    const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
    const int MAX_FRAMESKIP = 5;

    DWORD next_game_tick = GetTickCount();
    int loops;
    float interpolation;

    bool game_is_running = true;
    while( game_is_running ) {

        loops = 0;
        while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
            update_game();

            next_game_tick += SKIP_TICKS;
            loops++;
        }

        interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
                        / float( SKIP_TICKS );
        display_game( interpolation );
    }

With this kind of game loop, the implementation of update_game() will stay easy. But unfortunately, the display_game() function gets more complex. You will have to implement a prediction function that takes the interpolation as argument. But don’t worry, this isn’t hard, it just takes a bit more work. I’ll explain below how this interpolation and prediction works, but first let me show you why it is needed.

The Need for Interpolation

The gamestate gets updated 25 times per second, so if you don’t use interpolation in your rendering, frames will also be displayed at this speed. Remark that 25 fps isn’t as slow as some people think, movies for example run at 24 frames per second. So 25 fps should be enough for a visually pleasing experience, but for fast moving objects, we can still see a improvement when doing more FPS. So what we can do is make fast movements more smooth in between the frames. And this is where interpolation and a prediction function can provide a solution.

Interpolation and Prediction

Like I said the game code runs on it’s own frames per second, so when you draw/render your frames, it is possible that it’s in between 2 gameticks. Let’s say you have just updated your gamestate for the 10Th time, and now you are going to render the scene. This render will be in between the 10Th and 11Th game update. So it is possible that the render is at about 10.3. The ‘interpolation’ value then holds 0.3. Take this example: I have a car that moves every game tick like this:

    position = position + speed;

If in the 10Th gametick the position is 500, and the speed is 100, then in the 11Th gametick the position will be 600. So where will you place your car when you render it? You could just take the position of the last gametick (in this case 500). But a better way is to predict where the car would be at exact 10.3, and this happens like this:

    view_position = position + (speed * interpolation)

The car will then be rendered at position 530. So basically the interpolation variable contains the value that is in between the previous gametick and the next one (previous = 0.0, next = 1.0). What you have to do then is make a “prediction” function where the car/camera/… would be placed at the render time. You can base this prediction function on the speed of the object, steering or rotation speed. It doesn’t need to be complicated because we only use it to smooth things out in between the frames. It is indeed possible that an object gets rendered into another object right before a collision gets detected. But like we have seen before, the game is updated 25 frames per second, and so when this happens, the error is only shown for a fraction of a second, hardly noticeable to the human eye.

Slow Hardware

In most cases, update_game() will take far less time than display_game(). In fact, we can assume that even on slow hardware the update_game() function can run 25 times per second. So our game will handle player input and update the game state without much trouble, even if the game will only display 15 frames per second.

Fast Hardware

On fast hardware, the game will still run at a constant pace of 25 times per second, but the updating of the screen will be way faster than this. The interpolation/prediction method will create the visual appeal that the game is actually running at a high frame rate. The good thing is that you kind of cheat with your FPS. Because you don’t update your game state every frame, only the visualization, your game will have a higher FPS than with the second method I described.

Conclusion

Making the game state independent of the FPS seems to be the best implementation for a game loop. However, you will have to implement a prediction function in display_game(), but this isn’t that hard to achieve.

Overall Conclusion

A game loop has more to it than you think. We’ve reviewed 4 possible implementations, and it seems that there is one of them which you should definitely avoid, and that’s the one where a variable FPS dictates the game speed. A constant frame rate can be a good and simple solution for mobile devices, but when you want to get everything the hardware has got, best use a game loop where the FPS is completely independent of the game speed, using a prediction function for high framerates. If you don’t want to bother with a prediction function, you can work with a maximum frame rate, but finding the right game update rate for both slow and fast hardware can be tricky.

Now go and start coding that fantastic game you are thinking of!

Koen Witters

117 thoughts on “deWiTTERS Game Loop

  1. Sebastien B

    Very interesting Koen. Thank you for sharing this.
    You are true about the fact that this subject is *not* obvious, while it’s been strangely ignored in most of the game dev literature.

    Reply
  2. Pingback: Create your own games» Lecture Video on Game Loops – Koonsolo Game Development

  3. Jef

    I did a test in C++ to check the point one rounding error you mentioned, the only error I got was when the fps was 33, and the result was ‘10.02’. This is the exact code I used:

    #include
    
    double get_distance( int fps ) {
         double skip_ticks = 1000 / fps;
         int total_ticks = 0;
         double distance = 0.0;
         double speed_per_tick = 0.001;
    	 while (total_ticks < 10000) {
                 distance += speed_per_tick * skip_ticks;
                 total_ticks += skip_ticks;
    	 }
         return distance;
    }
    
    void disp(double txt) {
    	std::cout << txt << std::endl;
    }
    
    int main() {
    	disp(get_distance(40));
    	disp(get_distance(100));
    	disp(get_distance(33));
    	disp(get_distance(99));
    	while (true);
    }
    Reply
  4. Daniel

    Awesome post, thanks.
    I am a little confused tho. What is GetTickCount() function? It’s be very useful if you could put an example implementation of it on the page as well.

    Reply
  5. Gideon

    @Daniel
    Hey Daniel,

    the GetTickCount() is an example of a typical function which returns the number of ticks (usually milliseconds) since the app is running. In SDL for instance this would be SDL_GetTicks(). It is used to measure time within your application.

    Reply
  6. Gideon

    Aloha Koen!

    Great article, it helped me a lot to get some things straight for my game.
    One question though..if i have very fast moving objects, how can i detect collision when checking only like 25 frames per second. It works when i do collision detection every loop (outside the update loop) and also using interpolation/prediction. But I really dont like this solution, because collision is now being checked for each time i render to the screen. Any suggestions?

    Thanks in advance and sorry for my bad english (i´m german) ^^

    Reply
  7. Koen Witters

    Hi Gideon, you should first figure out the exact problem. If your problem is that the game doesn’t respond fast enough, then you should use more ticks per second for your update_game loop. (Remark that this will also make the rendering more exact).

    If your problem is purely a visual one (the rendering), then you should use collision prediction in your rendering, and interpolate accordingly.

    There is one other solution though, but I haven’t yet written anything about it. If you use a physics engine, chance is that you need to do lots of iterations of that physics engine per update_game. What you can do is spread out those iterations while you render. For example if you need to do 20 physics iterations per update_game, you can spread those 20 iterations out while you render. This way your rendering can take advantage of more exact positions (provided by the physics engine), but your game still runs at the normal update_game rate. Hope this is a bit clear, or else I’ll see if I can write another article ;).

    Reply
  8. Gideon

    @Koen Witters
    Hi Koen,

    thanks for the quick answer \(^o^)/.
    Since i´m (not yet) at the point where i need a lot of physics operations, i
    will leave my implementation as it is. But i like the idea of spreading!
    I am updating my game state at 50fps now, and do rendering and collision detection as fast as possible. Works like a charm ^_^.
    Can´t wait for your next article!

    Reply
  9. Phil

    Nice article, its certainly what I was looking for.

    In the past I have used “FPS dependent on Constant Game Speed” (gameboy advanced 60fps) and “Game Speed dependent on Variable FPS” but I think now I want both to be variable! ie, a max display fps can be chosen and a max compute fps can be chosen (ie, 60fps display and 100fps if player accuracy is important). I think the source engine uses something like this (with compute capped to display) and that is the functionality I should aim for.

    What would be the prospects of having several fps independant components? should I use semaphores and have the game objects independantly wait on results? – AI for example. or independantly different fps for input, ai, particles, physics, rendering? what could I expect from such an approach and how would I actually control such a thing?

    Reply
  10. jon

    Really good stuff here. Thanks alot. Looks like this might solve my game issues. If it does , are there any donation button here ?

    Reply
  11. Shaun

    You have two separate definitions of the “tick.” GetTickCount() returns milliseconds, so that means there are 1000 ticks per second. But in the section “Constant Game Speed with Constant FPS,” you redefine the “tick” to mean a single execution of the update function instead of a cpu clock tick. I quickly lost any grasp of our timing units. Can we resolve the units with the following nomenclature?

    const int UPDATES_PER_SECOND = 25;
    const int TICKS_PER_SECOND = 1000; // GetTickCount() dictates 1000 ticks per second
    const int TICKS_PER_UPDATE = TICKS_PER_SECOND / FRAMES_PER_SECOND;

    So instead of SKIP_TICKS, we would just use TICKS_PER_UPDATE. This is clearer to me because I know what each number is measuring.

    Reply
  12. Sydney B

    With the implementation of loop which offers a constant game speed independent of variable FPS on a seperate thread. Would this not consume most of your cpu processing power? I tried the implemenataion by taking your exact code and running it. my CPU maxes out at 100% on one of the cores.

    Reply
  13. Slight problem

    GetTickCount is only specified to be accurate to 10-16ms. It’s not the best idea for a game timer, as it may start causing jitter at high (>60fps) frame rates.

    The alternative is using QueryPerformanceCounter, it’s high precision, but it is subject to problems with older hardware (read around), although most bugs are gone by now.

    Reply
  14. Paril

    Even with QueryPerformanceCounter, jitter is very visible if you use the second to last method at an FPS higher than (my tests show to be) ~45 fps.

    As is pushed by the article, the last method with interpolation is indeed the best method. Running it at 10 FPS ensures that there will be no jitter (since all known tick functions on Linux and Windows will keep up to this speed no problem), and the interpolation is pretty simple to work with.

    Big problems occur, however, when the game is changing how prediction works while it is happening (between frames perhaps). A good example of this is a particle system – particles might not have a constant velocity, it’s think function might change it around (for snow for example). Basically, what you need to do in this case (and what’s not covered here) is have the renderer aware of these kind of changes; two sets of predictions basically.

    One problem that you might also run into while using this “two-set prediction” method is randomness. What if you need/want/have to use rand() or related functions in here? The answer is simple: don’t. The renderer and client portions should share the same “prediction” class/stub, so basically you want to pre-calculate your random values so both systems have access to it while it is running. Don’t even get me started on physics calculations – that’s a whole nother bag of matches.

    Anyway, these are my small musings on this. Please, reply if you have anything to add, I’m interested in building my knowledge on this subject (game loops are so simple yet so complex…).

    Reply
  15. ChrisH

    Excellent overview of the more popular timing methods, Koen. With that said, I’d like to make note of three things, two of which are rare but particularly nasty events that would render any game using the above code unplayable until it was restarted.

    1). As has been said, GetTickCount() is not the most accurate way of measuring elapsed time. It typically has a resolution of ~10ms but in some cases (older Windows versions?) the resolution is upwards of 55ms! Such a huge time gap will cause severe, noticeable “lag” in the logic loop. There’s a ton of info about various timing functions out there so my advice to everyone is do some googling and figure out what’s going to work best for your game.

    2). The next thing worth noting involves the way in which time is compared in the logic loop. The loop is: while(GetTickCount() > next_game_tick …). This is comparing the “latest” timestamp with the previous timestamp. I’ve seen this countless times, even in professional engines, but it causes a rare yet disastrous bug which will prevent the loop from running (and give the appearance that your game is frozen). In order to understand why, you have to know a couple of things about GetTickCount(): a). it returns an unsigned 32 bit integer which means it has a value range of (0, 4294967295); this means GetTickCount() will rollover from 4294967295 back to 0 every ~49.7 days. and b). only system shutdowns and restarts reset GetTickCount(); things like Sleep and Hibernate mode do not, so it’s entirely possible for your players to have uptimes greater than what GetTickCount() can display (> 49.7 days).

    Now, knowing that, it’s a bit easier to see where the problem occurs. If your game is running while GetTickCount() rolls over and next_game_tick has not, the logic loop could be evaluating something like: while(0 > 4294967290 …). In this case the logic loop will never execute (at least not for another ~49.7 days!). Your game will appear to just stop responding; rendering will continue as fast as possible but the scene will not be updated so the game will render the same thing repeatedly. Only restarting the game or the system will fix this.

    3). The third issue is much like the second, just in reverse and with temporary but potentially disastrous effects. If next_game_tick rolls over before GetTickCount(), the logic loop may look something like this while(4294967295 > 0 …). In this case the logic loop will run repeatedly, only stopping to allow rendering when the number of loops exceeds MAX_FRAMESKIP. In other words, your logic loop (and input processing, physics, AI, etc. etc.) will run 5 times for every 1 render loop. This will continue until GetTickCount() rolls over and surpasses next_game_tick. Your game may eventually return to normal but there will be a period of “freak out” that’s noticeable to the player.

    Luckily the fix for #2 and #3 is exceedingly simple. Change the logic loop from: while(GetTickCount() > next_game_tick …) to: while(unsigned int(GetTickCount() – next_game_tick) > SKIP_TICKS …). In effect you’re going from comparing the timestamps directly to comparing the difference between the two timestamps against a set interval. So, when GetTickCount() rolls over, the loop will be evaluating something like: while(unsigned int(0 – 4294967295) > 40 …). The “0 – 4294967295” would return -4294967295 except it’s then casted to an unsigned int (which can’t represent negative numbers) so instead it returns: 0.

    Reply
  16. topright

    Thank you for very nice article!

    Last too approaches are good ONLY if you can guarantee that your update_game() will NEVER take longer than the fixed time step (SKIP_TICKS) to complete.

    “In practice this means that when our render FPS drops below 5 (= FRAMES_PER_SECOND / MAX_FRAMESKIP), the actual game will slow down”.

    So the converse is also true:

    When our actual game (update_game) slows down (too many AI logic, for example), FPS slows down, too.

    Reply
  17. topright

    There is one more approach not mentioned in the article: Variable Game Speed with Constant FPS.

    #define MAXIMUM_FRAME_RATE 120
    #define MINIMUM_FRAME_RATE 15
    #define UPDATE_INTERVAL (1.0 / MAXIMUM_FRAME_RATE)
    #define MAX_CYCLES_PER_FRAME (MAXIMUM_FRAME_RATE / MINIMUM_FRAME_RATE)

    void runGame() {
    static double lastFrameTime = 0.0;
    static double cyclesLeftOver = 0.0;
    double currentTime;
    double updateIterations;

    currentTime = GetCurrentTime();
    updateIterations = ((currentTime – lastFrameTime) + cyclesLeftOver);

    if (updateIterations > (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL)) {
    updateIterations = (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL);
    }

    while (updateIterations > UPDATE_INTERVAL)
    {
    updateIterations -= UPDATE_INTERVAL;
    updateGame(); /* Update game state a variable number of times */
    }

    cyclesLeftOver = updateIterations;
    lastFrameTime = currentTime;

    drawScene(); /* Draw the scene only once */
    }

    (Source: http://www.x-sky.ru/2006/11/22/print:page,1,animacija_v_igrakh.html)

    Reply
  18. ChrisH

    topright :
    Thank you for very nice article!
    Last too approaches are good ONLY if you can guarantee that your update_game() will NEVER take longer than the fixed time step (SKIP_TICKS) to complete.
    “In practice this means that when our render FPS drops below 5 (= FRAMES_PER_SECOND / MAX_FRAMESKIP), the actual game will slow down”.
    So the converse is also true:

    When our actual game (update_game) slows down (too many AI logic, for example), FPS slows down, too.

    That’s a bit of an unspoken rule when it comes to fixed rate timing. If the player’s computer can’t process your game’s logic within that set time period on a regular basis bad things are going to happen. This makes sense because it means the player really doesn’t have fast enough hardware to run your game and would run into problems regardless of which timing method you use.

    The above timing methods attempt to compensate for this in the same way the XNA SDK does – by running your logic loop multiple times in an effort to “catch up” but eventually it’ll just give up, render a frame and repeat the process.

    Your “Variable Game Speed with Fixed FPS” is one I haven’t heard of. What’re the pros and cons of it?

    It seems like it’d potentially be the worst of all the methods listed here because it appears to have all of the problems and none of the advantages. A variable logic update rate will be unsuitable for any game that needs even basic physics because the simulation will periodically (as Garaff put it) “explode.” The fixed FPS will be unfortunate for those with fast hardware.

    Reply
  19. Paril

    I’ve got a simple question that maybe someone can answer in regards to interpolation (maybe this should be added to another article about it?). How exactly does one “predict” and prevent jerkiness? I have my own prediction working based on your method above, but when he starts moving and the frame before he stops moving the player jerks. Any ideas?

    -P

    Reply
  20. Luke

    Hi, I made my version of the 4th code in python, but for some reason it is not working the way it is suposed, can someone take a look please? thanks.

    import pygame
    import time

    TICKS_PER_SECOND = 25
    SKIP_TICK = 1000 / TICKS_PER_SECOND
    MAX_FRAMESKIP = 5

    next_game_tick = time.clock()
    loops = int()
    interpolation = float()
    position = 0
    speed = 300

    game_is_running = True
    window = pygame.display.set_mode((640,480))
    window.fill((0,0,0))

    def update_game():
    global position,speed
    position = position + speed
    #print position

    def display_game(interpolation):
    global position,speed
    view_position = position + (speed * interpolation)
    pygame.draw.rect(window,(255,255,255),(int(view_position),0,20,20))
    pygame.display.flip()
    window.fill((0,0,0))
    #print view_position

    while(game_is_running):
    loops = 0
    while(time.clock() > next_game_tick and loops < MAX_FRAMESKIP):
    update_game()

    next_game_tick += SKIP_TICK
    loops += 1
    print loops

    interpolation = float(time.clock() + SKIP_TICK – next_game_tick) / float(SKIP_TICK)
    display_game(interpolation)

    Reply
  21. Geri

    Running the game cycle below the fps is a bad idea. In a game, the content update/animation/phisics should run at real time. In a game, if you just updating the screen with bigger fps than the whole content managing, the whole experience will decrase.

    And updating the frames and the camera with full fps will not cause smoother gameplay.

    In my games i am using the reverse of this: i am updating the game logic in every frame, and some parts of the graphics are only updated in second/third frames.
    Mode_Hero(1/fps) is your friend.

    Reply
  22. Marc Tache

    So I assume that display_game() is an asynchronous function running in a separate thread? Otherwise the number of iterations per second in the loop can never be greater than the FPS (in the last example).

    is update_game() also an ansynchronous function?

    Reply
  23. Joe

    @ChrisH
    In your fix, when GetTickCount() rolls over,

    while(unsigned int(0 – 4294967295) > 40 …)

    will be while( 0 > 40 ),
    and it also will never go into the loop to increase next_game_tick.
    We still have to wait for 49 days.

    The “0 – 4294967295″ would return -4294967295 except it’s then casted to an unsigned int (which can’t represent negative numbers) so instead it returns: 0.

    Reply
  24. Marku S

    I just implemented the “Constant Game Speed independent of Variable FPS” in Java and it works great! But when I run my game, I get a CPU-load of nearly 100% and frame rates of up to 3500 fps. How can I use your method but limit the frame rate to e.g. the mean fps of 10 seconds?
    Apart from that: great article! Thanks 🙂

    Reply
  25. Gorlan

    Phew at last! I found your article really helpful, this is the kind of thing I just couldn’t figure out myself (or didn’t want anyway, it’s almost always better to rely on more experienced than oneself, isn’t it? :D). I implemented the last method but with the little correction in the while.

    while ( (unsigned long) (GetTickCount() – nextGameTick) > SKIP_TICKS && numloops < MAX_FRAME_SKIP )

    but I first put 0 instead of SKIP_TICKS which gave me some headaches and some white hairs… so stupid am I…

    I just wanted to add a little thing for some beginners too:

    Suppose you wanted to rotate something at 90°/sec. You know that your game is refreshing the position of an object at X Hz or X times per second (25 here) so you need to recalculate the game logic speed. Here it is:

    float real_speed = 90.0; //
    float speed = real_speed / TICKS_PER_SECOND;

    in you game logic:
    angle = angle * speed;

    in the drawing:
    viewed_angle = angle + speed * interpolation;

    It may seem trivial but this is just what I said earlier about letting others doing things for you! 😀

    Reply
  26. ChrisH

    @Joe

    You’re right in that when GetTickCount() rolls over to 0, the while loop will evaluate to false and that iteration will be skipped. This is correct behavior, though, because the difference in time between GetTickCount() and nextGameTick at that particular moment will always be less than SKIP_TICKS and so the logic loop shouldn’t run. In other words, at that particular moment, not enough time has passed to need a logic update.

    Where you’re a little off is thinking it’ll still take another ~49 days to run. By casting the result of (GetTickCount() – nextGameTick) to an unsigned int, you’re taking advantage of the wrap around behavior caused by integer overflow, ensuring that the result will always be a positive number. Initially (when GetTickCount rolls over to 0 and nextGameTick is stuck at, say, 4,294,967,295) the result of (unsigned int)(GetTickCount() – nextGameTick) will be 0. But as GetTickCount() is incremented, this result grows from 0 to 1, 2, 3 and so on until it will eventually (in a matter of milliseconds) surpass SKIP_TICKS, at which point the logic loop will run.

    It’s tricky but the easiest way of understanding it is probably to see it in action. The simplest way is to code a little example for yourself. In C++ (or whatever language you’re comfortable with that has unsigned ints), set a uint variable to 4,294,967,295. Then increment this variable by some random amount (say, 10) and print the result. And for a more relevant example, set two uints (one called CurrentTickCount and one called NextGameTick) to 5 and 4,294,967,295. Then print the result of (unsigned int)(CurrentTickCount – NextGameTick).

    You might be surprised. :]

    Reply
  27. Jawad Amjad

    Well i implemented dynamic fps this way.

    while (_run)
    {
    c = null;
    next_tick=System.currentTimeMillis(); //fpss

    try {
    c = _surfaceHolder.lockCanvas(null);

    synchronized (_surfaceHolder)
    {
    _panel.updatePhysics(sleep_time,fps);
    _panel.onDraw(c);

    if(fps_overall_flg)
    {
    skip_ticks = 1000/fps; //fpss
    next_tick += skip_ticks;
    sleep_time = (int) (next_tick – System.currentTimeMillis());

    if(sleep_time>0 || sleep_time 0 )
    {

    sleep( sleep_time );
    if(sleep_time>0 && fps_chg == true)
    fps+=1;
    }

    else if(sleep_time 0 && sleep_time <10)
    { fps_chg = false; fps_overall_flg = false;}

    Log.d("HEEELEOELEOE"," "+fps_overall_flg);
    }

    else
    {sleep(sleep_time);Log.d("is sleepin for"," "+sleep_time);}

    }

    and i think its working fine….if any one find any problem in this code do tell me. Ill be thankful and will appreciate your corrections.

    Reply
  28. Phil

    const int TICKS_PER_SECOND = 25;
    const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
    const int MAX_FRAMESKIP = 5;

    DWORD next_game_tick = GetTickCount();
    int loops;
    float interpolation;

    bool game_is_running = true;
    while( game_is_running ) {

    loops = 0;
    while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
    update_game();

    next_game_tick += SKIP_TICKS;
    loops++;
    }

    interpolation = float( GetTickCount() + SKIP_TICKS – next_game_tick )
    / float( SKIP_TICKS );
    display_game( interpolation );
    }

    Nice!

    Its going to take me all week to get my head around this properly!

    Reply
  29. TheEnlightenedOne

    Can someone explain the final example to me? LoL. The one where he’s using implementation. I don’t 100% understand what’s going on with the ticks.

    Reply
  30. AlbeyAmakiir

    I think I’ve found an instance in which “Game Speed dependent on Variable FPS” is not so bad. If the game stores all movement in terms of vectors (for example: object a starts here at this time and will end here at this time using this path), then you just check the time every game update and move the object to where is should be, *regardless of where it is now*. This does not work in any game that has collisions at all, and games like that are few and far between, but I’m making such a game, and the negatives you describe do not apply for it.
    That said, I do wonder if there are any other hidden negatives that anyone can think of.

    Reply
  31. Lindsay

    I actually don’t have that full understanding regarding this but I really find this very useful..Maybe because I still have to read a lot more to know more as well..

    Reply
  32. Lefteris

    For those who don’t understand the last method:
    I have a very fast PC. The update method should run for 25 seconds, but because the pc is so fast, it runs for 10. If we show the game state immediately after update, then we have shown it 15ms earlier. So what we can do is interpolate between the current state and the previews one to show an intermediate state.

    Reply
  33. Erik

    I’m beginning a game and working on the gameloop right now. I see some examples in other places where the loop is put in a seperate thread. The problem is I am using GLFW and in its manual it says both GLFW and OpenGL should be called from the main thread and GLFW should only be called from one thread.

    I know that if you create a bunch of child threads, then sleep in a child thread it will just pick another child thread. My question is if I create a child thread from the main thread then sleep in the main thread…it will then try to run the child thread right? Which should be fine for for the gameloop right?

    Reply
  34. Lewis Sinfield

    Hey Koen, thanks for this awesome post! I am currently studying this subject in my game design course but i am still struggling with the understanding the game loop. The main thing that i cannot get my head around is if the game loop is independent from the rest of the game.

    While i am aware that this subject is not really in my ‘field’ as a game designer i am always up for extending my general knowledge within the industry.

    Many thanks

    Lewis Sinfield

    Reply
  35. yuzhou

    Well,why do u seperate two concepts?FPS and GAME SPEED?I thought there just be a speed!what benefit to seperate both?!

    Reply
  36. zaz

    I’m a complete newbie in game developement, even with a few years of other programming under my belt. I must say, I found your article to be very clear and helpful 🙂

    Thanks a lot !

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *