Ideal Gameloop Implementation

Started by
11 comments, last by Krohm 12 years ago
Hello,

I have been researching different methods on implementing a game loop. The most common I have found are:

  • FPS dependent on Constant Game Speed (Where you cap the FPS to some constant and sleep the remainder away)
  • Game Speed dependent on Variable FPS (Where you subtract the new frame from the previous frame and use this to update the game)
  • Constant Game Speed with Maximum FPS (Where you guarantee updating the game logic x amount of times per frame and then render the frame)

I want a deterministic behavior for my game to help with networking and physics. It would seem that option 3 would be the best. I guess I am not 100 percent sure as to how to implement it.

Lets say that I want 60 frames per second. So, each frame should be 16.6666667 milliseconds long. I am not sure what my delta time should be or how often I should be updating my game logic before I render the frame.

I looked at these following resources.

http://www.koonsolo....tters-gameloop/
http://gafferongames...-your-timestep/

Thank you
Advertisement
I personally prefer the 1st choice. It not only simplifies you work, lets you profile easily and lets you sets a target, it's also better in the sense that most physics engines require you to have a *constact timestep* if not, the physics starts to look all weird.

What I usually do is to update the game based on the current FPS, update the Physics engine with an absolute timestep which is at the framerate you cap (if your framerate cap is 60 FPS, then update the physics engine by 1.0/60.0 ). This provides both stable physics as well as a proper benchmark.

I know that many prefer to use the 2nd or 3rd method, but I personally prefer the 1st one :)

Bollu

a WIP 2d game engine: https://code.google.com/p/modulusengine/

English is not my first language, so do feel free to correct me :)

You forgot one: constant update rate and variable FPS. The idea is that you separate your rendering logic from your update logic, and you render as fast as you can and as many time as you can, while only updating your game at a specific rate. This makes physics engines happy and allows you to have better looking results (as you can interpolate your renderings).

I'm surprised you didn't mention this, as you linked to the Fix Your Time Step article.

AFAIK, this is what is normally done in most games.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

You forgot one: constant update rate and variable FPS.

My understanding is that this is what was meant by “Constant Game Speed with Maximum FPS”, and yes it is the standard way to go.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

[quote name='Cornstalks' timestamp='1333084723' post='4926574'] You forgot one: constant update rate and variable FPS.
My understanding is that this is what was meant by “Constant Game Speed with Maximum FPS”, and yes it is the standard way to go.[/quote]
Now that you say it, that is probably what he intended by "Constant Game Speed with Maximum FPS." His description of it though is what made me think he was referring to something else (because there is no "guarantee updating the game logic x amount of times per frame" since the frame rate (and thus the frames) are totally independent of the game logic update frequency).
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

I personally prefer the 1st choice. It not only simplifies you work, lets you profile easily and lets you sets a target, it's also better in the sense that most physics engines require you to have a *constact timestep* if not, the physics starts to look all weird.

What I usually do is to update the game based on the current FPS, update the Physics engine with an absolute timestep which is at the framerate you cap (if your framerate cap is 60 FPS, then update the physics engine by 1.0/60.0 ). This provides both stable physics as well as a proper benchmark.

I know that many prefer to use the 2nd or 3rd method, but I personally prefer the 1st one :)

Bollu

I am just guessing that one of your peeves with #3 is that you consider there is no reason to draw multiple times the same frame over and over.
If logic causes position changes, and that only happens say 30 times per second, then rendering faster than that is useless since objects will still appear to move only 30 times per second, even if the actual FPS is 200.

But #3 is more complex than that, and also requires care in implementing. My next tutorial will be about this since this also just appeared in some code my ex-coworker had me debug.

#3 allows all of the stability required by physics engines and other systems but allows as-smooth-as-possible a framerate as players desire. Making players think their games are running smoothly is a very important aspect, and FPS is often used as a benchmark, so limiting your FPS as mentioned in #1 is never desirable. It also causes inconsistencies in most implementations because programmers who implement it tend to forget that timers, sleeping, and friends are not reliable. Most naive implementations set a timer or somehow force a certain FPS, but forget that no matter how you do this, timers, sleeping, and even while loops are subject to the thread scheduler which may (and will 99% of the time) decide to delay your execution for a few nanoseconds because another thread is busy.

In naive implementations, by forgetting the above, you will be passing a fixed delta each tick, because you assume hardware is reliable and each tick represents exactly that delta. This is wrong and will never ever happen in real life. Your ticks will never ever be the exact same amount apart no matter how hard you try. Method #3 handles this fact.


#3 relies on a bit of experience though. Implementing it incorrectly will actually heavily hinder your performance as my ex-coworker discovered.

I am not going to explain the nuances of that now because it will be more efficient to make a post about it on my site and then post that here. This is a problem that pokes out its head very frequently so I would rather not explain how to do it correctly multiple times.
Just wait about 12 hours.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


Just wait about 12 hours.

Waiting. While I get the idea of how this works, I've always wanted a good in depth article on it (and judging by your in depth article on your DXT compressor, it'll be a good one).
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
same, waiting :)

a WIP 2d game engine: https://code.google.com/p/modulusengine/

English is not my first language, so do feel free to correct me :)

I have just finished. It can be found here.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Ultimately the "ideal" game loop depends on the game but my personal take:

I agree with bollµ that #1 is by far easier to code and gives good results (I do this myself as well). And sure, as L. Spiro points out you will realistically get around 29.99 fps or below if you lock at 30fps, but I don't believe this is such a huge problem in practice, and even then the fluctuations in real FPS should mostly be minor (IMO much less so than the fluctuations you will get if you allow rendering as fast as possible)

L. Spiro, you do point out some very good things to keep in mind when implementing this in your writeup (which I think got for any loop implementation), namely to make sure to get the current time only once per tick, storing time values in 64 bit ints, and making sure you always pass/use the same duration/time lapse for each tick to be consistent. (You may also want to talk about how to avoid wrap around timer issues by checking difference between times instead of checking absolute times too!)

I think the major problem with #3 is just getting it right. It is extremely, extremely easy to botch this, and if you go this route, you will need to decide which parts/objects that get drawn should be interpolated to take advantage of the extra fps (only fast moving objects, or all objects, what's the cutoff? other graphical variances like color changing etc?). And the other moral dilemma you will have to consider with this option is that what the user sees may not match the physics, aka hitboxes that don't correspond to what is shown visually which can be frustrating. That said, if this is done correctly, this does give awesome results and is pretty much required for networked games anyways which need prediction to visually smooth things out to begin with.

But hey, when in doubt, write both and compare yourself :)

This topic is closed to new replies.

Advertisement