Jump to content

  • Log In with Google      Sign In   
  • Create Account

Timing game loop


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 GrimV5   Members   -  Reputation: 101

Like
0Likes
Like

Posted 28 January 2014 - 03:57 PM

Is there a standard value for the amount of time I should wait between each update of the main thread? I'm using SFML on c++, right now I just have a basic loop:

 

while(game.isRunning()){

   game.HandleEvent();

   game.Update();

   game.Paint();

   //time sleep method

}

 

I'm making a 2d game, so how long should the loop wait before starting over?



Sponsor:

#2 richardurich   Members   -  Reputation: 1187

Like
1Likes
Like

Posted 28 January 2014 - 04:38 PM

You usually don't sleep at all in a game. You could yield (SwitchToThread on windows) if you really want, but it's not like we're still using win9x kernels or something.

 

Also keep in mind you'll already be sleeping until vsync if you're using vsync in your game.



#3 SolarChronus   Members   -  Reputation: 199

Like
0Likes
Like

Posted 28 January 2014 - 05:05 PM

If you're not using a fixed time step or waiting for vsync, you may want to keep track of the time between frames. Which in your case it's pretty simple, a frame is each run of your game loop.

 

You should start a clock right before your game loop starts. At the beginning of each loop save the clock time and restart the clock. This would typically be called the game time as it'll be the time between the previous from to the beginning of the next frame. You would then pass this game time around to the various parts of your game to make sure everything is executed at the correct speed. I.E  movement of objects, physics, etc.



#4 GrimV5   Members   -  Reputation: 101

Like
0Likes
Like

Posted 28 January 2014 - 05:06 PM

You usually don't sleep at all in a game. You could yield (SwitchToThread on windows) if you really want, but it's not like we're still using win9x kernels or something.

 

Also keep in mind you'll already be sleeping until vsync if you're using vsync in your game.

I may have asked this the wrong way.  What I meant was what kind of time step should I use so that it doesn't look like the sprites are flying across the screen at mach 3?



#5 SolarChronus   Members   -  Reputation: 199

Like
0Likes
Like

Posted 28 January 2014 - 05:18 PM

 

You usually don't sleep at all in a game. You could yield (SwitchToThread on windows) if you really want, but it's not like we're still using win9x kernels or something.

 

Also keep in mind you'll already be sleeping until vsync if you're using vsync in your game.

I may have asked this the wrong way.  What I meant was what kind of time step should I use so that it doesn't look like the sprites are flying across the screen at mach 3?

 

 

Try doing what I suggested above, and when you're manipulating the speed of your sprites, make sure to multiply the speed by the game time.

 

I.E

 

objectPosition.x = objectPosition.x + (speed * gameTime).

 

This would make sure the speed value for your object is only as fast as the time step. The longer it takes for the next frame (or loop) to begin, the greater that speed value will end up being, and vice versa.

 

Say it takes .161 seconds to go from frame 1 to frame 2, and you have a speed of 50.  50 * .161. Doing the math would give you a 'speed for this frame' of 8.05, and thus would only move the sprite by that much, instead of the full 50.


Edited by SolarChronus, 28 January 2014 - 05:18 PM.


#6 L. Spiro   Crossbones+   -  Reputation: 14446

Like
3Likes
Like

Posted 28 January 2014 - 08:41 PM

objectPosition.x = objectPosition.x + (speed * gameTime).

Just change gameTime to frameTime. The amount of time since the last update of your game (time since the loop…looped).

If you have any form of physics, a fixed time step will also be necessary.
Fixed-Time-Step Implementation


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#7 King Mir   Members   -  Reputation: 2050

Like
0Likes
Like

Posted 28 January 2014 - 09:17 PM

You usually don't sleep at all in a game. You could yield (SwitchToThread on windows) if you really want, but it's not like we're still using win9x kernels or something.
 
Also keep in mind you'll already be sleeping until vsync if you're using vsync in your game.

I may have asked this the wrong way.  What I meant was what kind of time step should I use so that it doesn't look like the sprites are flying across the screen at mach 3?

You want to update sprites at 30-75 Hz. 75Hz is at the high end of what a LCD will display. A frame rate higher than the monitor refresh rate cannot be seen. 60Hz is also a common limit for monitors. You may be able to poll the OS to find out the current display refresh rate. 30 Hz is the low end of what will look like smooth motion. You can run slower, but then tics start being visible.

#8 incertia   Crossbones+   -  Reputation: 779

Like
0Likes
Like

Posted 30 January 2014 - 09:55 AM

If anything, only throttle the drawing of objects. If you throttle input/physics it will make your game seem laggy. So basically just keep a timer and do something like
input();
update_states();
physics();
if(cur_time > max_frame_time) draw(), cur_time = 0;
cur_time += frame_time;

what

#9 Glass_Knife   Moderators   -  Reputation: 5057

Like
1Likes
Like

Posted 30 January 2014 - 11:21 AM


If you have any form of physics, a fixed time step will also be necessary.
Fixed-Time-Step Implementation

 

What a great explanation.


I think, therefore I am. I think? - "George Carlin"
Indie Game Programming

#10 Shannon Barber   Moderators   -  Reputation: 1390

Like
0Likes
Like

Posted 01 February 2014 - 12:20 PM

To play nice you can put in a Sleep(0).

This will yield your process to anything else that needs processing time after you finished your game loop.

If you do not do this then your process will starve anything waiting and eventually Windows will slice you out at some random place in the game-loop.

 

The nice part of Sleep(0) is if nothing is waiting then it returns to your app right away (unlike Sleep(1) which will probably take 10ms).


- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

#11 Aardvajk   Crossbones+   -  Reputation: 6280

Like
0Likes
Like

Posted 01 February 2014 - 04:37 PM

Here's the fundamental thing to bear in mind - you can never, ever predict the frame rate on any other machine than the one you are on.

 

If you use vsync to control the frame rate, you're code will be run on a machine with a different refresh rate, or someone will force vsync off on their graphics card settings (causing the hardware to falsly report vertical blank period as soon as it is asked rather than when it is actually happening).

 

The Fix Your Timestep article has already been posted. This is the defacto standard article to read on this subject. Fix your timestep and allow your graphics to render as fast as possible. Make vsync optional and never assume it is on even if you have requested it in your setup.

 

You pass a delta value into your update() methods and move based on this. So if your object should move 10 units per second, you add 10 * delta to the position where delta is a float representing the number of seconds (normally a small value like 0.0016) that have passed since the last update.

 

The gaffer article, in my humble option, makes it seem a bit more complicated than it actually is. I've found all you need to store is the previous position and the current position, then interpolate between them based on the error. My game loop looks something like:

        float t = timer.elapsed();

        accumulator += t;

        while(accumulator >= delta)
        {
            app.update(delta);
            accumulator -= delta;
        }

        app.render(accumulator / delta);

I use a fixed delta (1.0f / 60.0f for example) so every update is deterministic and repeatable, and characters don't, for example, jump to different heights depending on the frame rate. This is a problem even with simple physics if you have variable timestep, not just highly sophisticated physics sims, although in the latter the problem can lead to worse consequences than characters jumping to different heights. Still, in a Mario style 2D platformer, you want complete control of the maximum jump height for obvious reasons. This approach is the way to ensure that on different hardware.

 

Each entity stores previous and current position, then I do a linear interpolation based on the blend factor passed to app.render when working out where to draw the entity. This means the visuals always lag very slightly behind the real game state, but that's fine.

 

You also need to store previous values for things like fade values, animation track positions and so on and interpolate these but I've never found it necessary to store and interpolate things like acceleration. Maybe its just too small a difference to be visually noticeable, or maybe I misunderstand Gaffer's article.

 

This approach is the most stable for physics, the most consistent across different hardware and very hard to find a reason not to do since it isn't really much work.


Edited by Aardvajk, 01 February 2014 - 04:42 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS