Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: If statement vs While loop for Updates in a Fixed Timestep  (Read 3281 times)

0 Members and 1 Guest are viewing this topic.

arnavb

  • Newbie
  • *
  • Posts: 18
    • View Profile
If statement vs While loop for Updates in a Fixed Timestep
« on: July 14, 2018, 01:18:31 am »
Let's say I'm in the process of implementing the game loop for my SFML game. In order to maintain a fixed timestep, I would follow something like outline in: https://gafferongames.com/post/fix_your_timestep/

In order to implement something like that, the code would probably be:

void Game::run()
{
        sf::Clock clock;
        sf::Time timeSinceLastUpdate = sf::Time::Zero;
        while (mWindow.isOpen())
        {
                sf::Time elapsedTime = clock.restart();
                timeSinceLastUpdate += elapsedTime;
                while (timeSinceLastUpdate > TimePerFrame)
                {
                        timeSinceLastUpdate -= TimePerFrame;

                        processEvents();
                        update(TimePerFrame);
                }

                updateStatistics(elapsedTime);
                render();
        }
}
 

(This is directly copied and pasted from https://github.com/SFML/SFML-Game-Development-Book/blob/master/01_Intro/Source/Game.cpp, and seems to be the direct implementation of the concept linked to in the article above).

However, I recently bought the book SFML Game Development By Example (by Raimondas Pupius), and found the following paragraph in Chapter 2:

Quote
... (Page 32)
Unlike the variable time-step, where the next update and draw happens as soon as the previous one is done, the fixed time-step approach will ensure that certain game logic is only happening at a provided rate. It's fairly simple to implement a fixed time-step. First, we must make sure that instead of overwriting the elapsed time value of the previous iteration, we add to it like so:

void Game::RestartClock() {
    m_elapsed += m_clock.restart();
}

The basic expression for calculating the amount of time for an individual update throughout a 1 second interval is illustrated here:

                           1.0f
FrameTime =  --------------
                       Updates/s

(It's actually an image, but whatever)

Let's say we want our game to update 60 times a second. To find the frame time, we would divide 1 by 60 and check if the elapsed time has exceeded that value, as shown here:

float frametime = 1.0f / 60.0f;

if (m_elapsed.asSeconds() >= frametime) {
    // Do something 60 times a second.

    m_elapsed -= sf::seconds(frametime);
}

As evident, the difference between both snippets is that one uses a while loop to check if the elapsed time is greater than the frametime, and keeps updating/subtracting until it isn't. This seems logical to me. The other approach, as shown in the quote, suggests to skip updates (to increase the elapsed time) until the time comes. These to me seem completely different ways of implementing a similar concept. Which type of fixed timestep should I use?

(Side question: How do I embed a link with its own text i.e in markdown: [link text](URL)?)
« Last Edit: July 15, 2018, 12:21:55 am by arnavb »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: If statement vs While loop for Updates in a Fixed Timestep
« Reply #1 on: July 14, 2018, 02:44:43 am »
It makes sense to follow the while version as a rule as it makes sure that it processes all excess time whereas the if version only process only "frame" even if many have passed in time, which does happen (for example, if three 60ths of a second have passed, only one will be processed and the game will lag behind real-time by two 60ths of a second).

However, there is a compromise, which is outlined in the gafferongames article, I'm sure. Basically use the while loop but limit the amount of accumulation you accept. This "throws away" excess time if too much time has passed as opposed to possibly processing 30 seconds of physics in less than a frame, which could be a bit less than aesthetically pleasing. If you set the maximum to equal the frame time (dt), it's equivalent to the if version.



FORUM:
To link text, highlight the text and click the Insert HyperLink icon (it should be under the italic icon). This will turn the text into a link but you must adjust it to contain the actual URL.
The icon will create this:
[url]this is the text[/url]
which shows this:
this is the text
To add a destination URL, simply add
="DESTINATION"
direction after "url" and before the first "]"
For example, to link to Google, it should look like this:
[url="https://www.google.com/"]Google[/url]
which appears as this:
Google

Of course, you could just type in the entire code instead of using the icon if you prefer ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

arnavb

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: If statement vs While loop for Updates in a Fixed Timestep
« Reply #2 on: July 14, 2018, 03:25:01 pm »
I actually don't see the "compromise" you are referring to in the article. Are you talking about something similar to the deWiTTERS game loop? (Thanks for telling me how to embed links, BTW).

I don't see any sort of compromise in the code I copied and pasted from Github either, but I still want to avoid the 30 second problem you mentioned (although I presume interpolation should fix the problem).

Could you provide some example code to illustrate your point (I find that I understand that better than just words  ::)?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: If statement vs While loop for Updates in a Fixed Timestep
« Reply #3 on: July 14, 2018, 09:13:00 pm »
I'm going by memory on this subject because it's been a bit of a while since I created my own timing library (Kairos) so I use its Timestep for anything I do (it's based on the gafferongames article and some of my own experience.)

The part of Fix Your Timestep that talks about maximum accumulation is under the "Semi-fixed timestep" section.
Quote
if your simulation is the most expensive part of your frame you could run into the so called “spiral of death”.
...
Quote
What is the spiral of death? It’s what happens when your physics simulation can’t keep up with the steps it’s asked to take.
...
Quote
So how do we avoid this? In order to ensure a stable update I recommend leaving some headroom.
...
Quote
Alternatively you can clamp at a maximum # of steps per-frame and the simulation will appear to slow down under heavy load. Arguably this is better than spiraling to death, especially if the heavy load is just a temporary spike.

That last part is the suggestion that I made about the maximum accumulation, which, by the way, Kairos' Timestep also has ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

arnavb

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: If statement vs While loop for Updates in a Fixed Timestep
« Reply #4 on: July 15, 2018, 12:21:38 am »
Hmmmm, I'll definitely make a point to look at your library for larger games, but the game I'm currently making doesn't really need it. However, I will take a look at the source code you used to see how you implemented a fixed timestep. Thanks for linking!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: If statement vs While loop for Updates in a Fixed Timestep
« Reply #5 on: July 15, 2018, 04:16:52 am »
It's only a small library :P
Actually, Timestep does rely on the dedicated clocks in the library but maybe you could just try the Timestep Lite class. It isn't reliant on anything else in the library so it's pretty portable; just copy the hpp and cpp files into your project! ;)
It's basically just my implementation of the gafferongames code; however, note that the lite version doesn't actually include the maximum accumulation code but it should be simple enough to modify. ;D
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*