Day 18 Sleep Question

Hi Guys,

I was going back through HMH Day 18, to refresh my memory on Game Loop stuff, and I was a bit confused about something.

1
2
3
4
5
6
 
if(SleepIsGranular)
{
    DWORD SleepMS = (DWORD)(1000.0f * (TargetSecondsPerFrame - SecondsElapsedForFrame));
    Sleep(SleepMS);
}


In Day 18, Casey wrote the above code, and when asked if it could cause us to miss the target FPS he said no because we made a call that allowed us to be MS granular, and the SleepMS is truncated.

I understand his point; however, can't we still miss the SleepMS here, because even if the scheduler is MS granular, if it wakes up at a different offset from when we actually called Sleep there may be some inaccuracy depending on the fractional part of SleepMS right?

For example, if SleepMS is 10.3 and so we call Sleep(10), but we called Sleep(10) 0.2ms after the last run of the scheduler then the scheduler will miss the 10ms and actually wake up after 10.8ms of sleeping. (the arithmetic may be wrong here, but I think the question still hopefully makes sense).
I added an Assert and it does seem like the Sleep can overshoot.

Would appreciate any insight!

Edited by Henry Kloren on
In the Sleep msdn documentation:
1
The system clock "ticks" at a constant rate. If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time. If dwMilliseconds is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on.


So yes Sleep can take more or less time than request.

You should not rely on it if you intention is to synchronize with the screen. Use vsync instead.
sure. that's what i was thinking just wanted to double check. also, i have another question if you don't mind. casey says that it was important to choose and lock to a target framerate early because it would drive many decisions regarding how we implement / tune certain parts of the game code. i'm not really sure how locking to a particular FPS actually changes anything we may write in the game. is this referring to things like choosing acceptable audio latency, etc?

here is the clip with a linked time for reference:
https://youtu.be/TPpn2fee77M?t=146

Edited by Henry Kloren on
The only way to be sure is to ask him on the stream if you can.

But I guess he is just saying that you need to ensure that the game will run at 60fps because if you tweak values to work at 60fps and the game runs at 30 or 120 fps, the game will be too slow or too fast and some things might behave slightly differently (in addition to the general game speed). You can also try to make the game frame rate independent (I think most games do) but it has its complication too. As far as I know handmade hero is still using (currently at day 536) a (semi) hard-coded delta time, and slows down if the target frame rate is not reached.

HFKloren
sure. that's what i was thinking just wanted to double check. also, i have another question if you don't mind. casey says that it was important to choose and lock to a target framerate early because it would drive many decisions regarding how we implement / tune certain parts of the game code. i'm not really sure how locking to a particular FPS actually changes anything we may write in the game. is this referring to things like choosing acceptable audio latency, etc?

here is the clip with a linked time for reference:
https://youtu.be/TPpn2fee77M?t=146


The big difference is that if you don't lock to a framerate you have to account for the delta time in every update.

This means that a physics update becomes

1
2
pos = pos + dt*vel;
vel = vel + dt*accel;


Passing this delta time around then becomes pervasive throughout the codebase. It also creates problems with rounding when the delta is too small (though that can be solved by limiting the framerate).
makes sense. thanks!
thanks to you also mrmixer. really helpful answers.

Edited by Henry Kloren on