# Accurate timing in the game loop

## Recommended Posts

Gage64    1235
Suppose my game runs constantly at 60 fps. That means that each frame lasts about 16 ms. Now suppose that I want to perform an action every 10 ms. The obvious way to achieve this is to check each frame if 10 ms have passed, and if it has, perform the action. Unfortunately this doesn't work. Using this method, the action will be performed at most once per-frame, meaning that it will really be performed every 16 ms. How can I solve this? Thanks in advance.

##### Share on other sites
MJP    19787
This is the common way to do fixed time-step:

void Update (float dt){    accumUpdate += dt;    while (accumUpdate > timeStep)    {        accumUpdate -= timeStep;        DoStuff();    }}

##### Share on other sites
Gage64    1235
Thank you. How do you determine what time step to use?

##### Share on other sites
davidsporn    126
the timeStep is 10ms in your case. The function calling "update" must track how much time passed since the previous call to "update"

##### Share on other sites
ValMan    466
The short answer is that you can't (with your present game loop setup).

The long answer is that you will probably need multi-threading. If one iteration of your game loop takes 16 MS, it's either because you fixed it to that interval (see MJP's post), because you are CPU bound, or because you are GPU bound (including Present()'s waiting for vsync). Either way, your main game loop will be busy doing something. The only solution, then, is to use another thread to check continuously if the interval has elapsed.

##### Share on other sites
Gage64    1235
Quote:
 Original post by davidspornthe timeStep is 10ms in your case.

That can't be right. I can have many actions, some of which will be performed every 5 ms, some every 50 ms, etc, so the time step has to be based on something else.

Quote:
 Original post by ValManIf one iteration of your game loop takes 16 MS, it's either because you fixed it to that interval (see MJP's post), because you are CPU bound, or because you are GPU bound (including Present()'s waiting for vsync). Either way, your main game loop will be busy doing something.

The 16 ms was just for the sake of discussion. Besides, I think pretty much every game supports this in some way. Are you saying that they all use multi-threading (even the old ones)?

##### Share on other sites
MJP    19787
Quote:
Original post by Gage64
Quote:
 Original post by davidspornthe timeStep is 10ms in your case.

That can't be right. I can have many actions, some of which will be performed every 5 ms, some every 50 ms, etc, so the time step has to be based on something else.

You can implement this for every action if you want, with timeStep being a member variable for that particular class. This won't allow you to update things at the exact moment the time step elapses, but the end result will be the same over a long period of time.

##### Share on other sites
Gage64    1235
Quote:
 Original post by MJPYou can implement this for every action if you want, with timeStep being a member variable for that particular class.

If you mean what I think you mean, this won't work properly. If you'll read a couple of posts starting from here, you'll see what I mean.

##### Share on other sites
Kylotan    10010
I would argue that it would be best to give up on the idea of getting anything to happen every 5 milliseconds. That sort of resolution isn't really reliable without a lot of work.

##### Share on other sites
Gage64    1235
Quote:
 Original post by KylotanI would argue that it would be best to give up on the idea of getting anything to happen every 5 milliseconds. That sort of resolution isn't really reliable without a lot of work.

Again, it was just an example. The question is, how do I do this for a frequency that's higher than the game loop's. For example, if it's running at 30 fps, each frame lasts about 33 ms, and suppose I want something to happen every 20 ms.

##### Share on other sites
gekko    478

Basically, you should never need anything to be done more than once per game loop. Games are not real-time, the user won't be able to know if you are running at 60fps and emitting a particle every 5ms or if you simply emit 3 per loop.

If you want twice the particles if the game was running at 30fps, then I'd argue against the idea since you're only getting 30fps. But to simulate 5ms timing, divide your frame time by 5ms, and emit that many particles. Then at 60fps you will get 3, at 30fps you will get 6, etc.

But I'd strongly suggest re-thinking what you're trying to do. Odds are you can achieve the same thing for much less work and overhead that will give the end user the same experience.

##### Share on other sites
Marmin    523
You need an accurate timer; and then make a separate calculation loop and a render loop. You call these in your main loop and you can call these at any time interval. No need for threading imho. Of course threads can; but will make things complicated.

##### Share on other sites
Gage64    1235
Quote:
 Original post by gekkoBut I'd strongly suggest re-thinking what you're trying to do. Odds are you can achieve the same thing for much less work and overhead that will give the end user the same experience.

This is mostly theoretical thinking. In the games I've created so far (pong, snake, tetris), the naive approach I described in my original post worked just fine (or seemed to work just fine. Some of the posts in the link I gave earlier show that this stuff can be tricky to get right, and you might not even notice if it's wrong).

I was just trying to think ahead for more complex games. For example, if you have a machine gun, it should fire at a very high rate of fire, so maybe firing just one bullet per-frame won't be fast enough.

This is also an attempt to better understand the discussion over here.

I guess I need to try and implement this, and when I'll actually encounter a problem I'll know what questions to ask.

##### Share on other sites
lexs    148
The code MJP posted will solve that issue, as it will execute the code x times each frame to compensate for the fact that your game is running at 60 hz instead of say 200 which is the machine-guns rate of fire.. The user won't notice this and he can't, the world state is only rendered at 60 hz anyways.

##### Share on other sites
Gage64    1235
Then I'll repeat my earlier question: How do you determine what time-step to use?

##### Share on other sites
RabidDog    116
Quote:
 Original post by Gage64I was just trying to think ahead for more complex games. For example, if you have a machine gun, it should fire at a very high rate of fire, so maybe firing just one bullet per-frame won't be fast enough.

That's not the way to go about doing this. Just fire more bullets per frame in that scenario.

##### Share on other sites
MJP    19787
Quote:
Original post by Gage64
Quote:
 Original post by gekkoBut I'd strongly suggest re-thinking what you're trying to do. Odds are you can achieve the same thing for much less work and overhead that will give the end user the same experience.

This is mostly theoretical thinking. In the games I've created so far (pong, snake, tetris), the naive approach I described in my original post worked just fine (or seemed to work just fine. Some of the posts in the link I gave earlier show that this stuff can be tricky to get right, and you might not even notice if it's wrong).

I was just trying to think ahead for more complex games. For example, if you have a machine gun, it should fire at a very high rate of fire, so maybe firing just one bullet per-frame won't be fast enough.

This is also an attempt to better understand the discussion over here.

I guess I need to try and implement this, and when I'll actually encounter a problem I'll know what questions to ask.

Interesting...I suppose are cases where simulating concurrency will break down quite quickly. Unfortunately I don't really know of any sure-fire solutions, so I can't really help you out. If you do come up with anything, be sure to share with us. [smile]

##### Share on other sites
lexs    148
Quote:
 Original post by Gage64Then I'll repeat my earlier question: How do you determine what time-step to use?

Say you want the machine gun to fire 200 times per second, if float dt is in seconds your timestep for the bullet fire code should be float timestep = 1.0/200.0

##### Share on other sites
Gage64    1235
Quote:
 Original post by lexsSay you want the machine gun to fire 200 times per second, if float dt is in seconds your timestep for the bullet fire code should be float timestep = 1.0/200.0

Quote:
 Original post by Gage64 That can't be right. I can have many actions, some of which will be performed every 5 ms, some every 50 ms, etc, so the time step has to be based on something else.

##### Share on other sites
Kylotan    10010
Quote:
 Original post by Gage64I was just trying to think ahead for more complex games. For example, if you have a machine gun, it should fire at a very high rate of fire, so maybe firing just one bullet per-frame won't be fast enough.

Even the typical machine gun probably won't need to fire more than 20 times a second. But remember the aim of a game isn't necessarily to simulate every single bullet.

Your original suggestion is good enough, with a small modification. If you need to do something every 10ms, but 16ms has elapsed, then you do whatever needs to be done, and you cut 6ms off the schedule for the next one. It's a tiny bit more complicated when your timestep is big enough to encompass two sequential events rather than just one. The system perhaps needs to repeatedly ask the event generator (eg. the gun in this case) for the next event, and if it's due, handle it, and if it's not, leave it for the next frame.

##### Share on other sites
Gage64    1235
Quote:
 Original post by KylotanYour original suggestion is good enough, with a small modification. If you need to do something every 10ms, but 16ms has elapsed, then you do whatever needs to be done, and you cut 6ms off the schedule for the next one.

Unfortunately this doesn't work. This post explains why. Unless I misunderstood you?

It looks like using MJP's fixed time-step will solve this issue, but I still haven't gotten an answer as to how to choose the time-step.

##### Share on other sites
Kylotan    10010
You misunderstood me. I'm not suggesting a sampling approach to see which events are due right now, I'm suggesting watching to see which events have become due since last time, and at that point, you can handle it and see if yet another event will become due as a result. Each time you check whether an event is due, and if it is, you handle it, which for repeated actions typically involves scheduling the next event. That new event may be due already, so you handle that as well, until you're out of events to handle. This way you could end up firing 10 bullets per update, or whatever. You also know exactly how overdue each one is, so you can factor that into your physics or graphics.

As for choosing the time step, it's arbitrary. Pick one that is fine-grained enough to work for you, but not so fine-grained that you waste too much CPU time on trivial updates. As typical examples, I've heard of some people using 10Hz, others using 25Hz or 30Hz.

##### Share on other sites
Gage64    1235
Quote:
 Original post by KylotanI'm suggesting watching to see which events have become due since last time, and at that point, you can handle it and see if yet another event will become due as a result. Each time you check whether an event is due, and if it is, you handle it, which for repeated actions typically involves scheduling the next event. That new event may be due already, so you handle that as well, until you're out of events to handle. This way you could end up firing 10 bullets per update, or whatever.

I think I'm starting to get it. I also think that that's what MJP suggested with his code for the fixed time-step loop, though it looks like I'll have to do that for each event (because different events can have different execution frequencies). I'm not sure how I should set all this up...

Quote:
 This way you could end up firing 10 bullets per update, or whatever. You also know exactly how overdue each one is, so you can factor that into your physics or graphics.

I assume you are referring to interpolation. I haven't even thought about how that will work, but that's a topic for another thread...

Thank you for your help. I'll think about this some more and maybe try to implement a simple demo and see if it works out.

Thanks again to everyone.