I'm learning Java game development and trying to dissect this game loop:
// Game loop
final int TICKS_PER_SECOND = 60;
final int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
final int MAX_FRAMESKIP = 5;
long nextGameTick = System.currentTimeMillis();
int loops;
float interpolation;
boolean running = true;
while(running) {
loops = 0;
while(System.currentTimeMillis() > nextGameTick && loops < MAX_FRAMESKIP) {
System.out.println(System.currentTimeMillis() + " > " + nextGameTick);
update();
ticks++;
nextGameTick += SKIP_TICKS;
loops++;
}
interpolation = (float) (System.currentTimeMillis() + SKIP_TICKS - nextGameTick)
/ (float) SKIP_TICKS;
render(interpolation);
if(System.currentTimeMillis() - timeAtLastFPSCheck >= 1000) {
System.out.println("FPS: " + ticks);
gameWindow.setTitle(gameName + " - FPS: " + ticks);
ticks = 0;
timeAtLastFPSCheck = System.currentTimeMillis();
}
}
So far, here's what I understand:
- TICKS_PER_SECOND is the amount of times we want the game to update per second
- SKIP_TICKS is the max time that a game tick should take if we want to keep to our TICKS_PER_SECOND value
- MAX_FRAMESKIP is the max amount of updates per render
Here's where I'm confused: the 'nextGameTick' variable takes the current time and then we go into the loop. The first logic that we come across is that while the current time is GREATER THAN 'nextGameTick' AND the loops of this logic is LESS THAN the MAX_FRAMESKIP (the max updates per render). I cannot get my head around why we are comparing if the current time is greater than the 'nextGameTick' - as far as I can see from the code the 'nextGameTick' is basically the time value if the update took the maximum amount of time allowed. But surely then we should be comparing if the current time is LESS THAN the maximum time allowed for the update - i.e. if the update is taking too long we break from the loop immediately and go to render. However if I change the GREATER THAN to a LESS THAN then update is never called.
I think what this logic is trying to do/doing (but I don't know how) is basically allowing the game to update more times than it renders - because a lot of people's computers will be fast enough to do so. So it allows us to update 5 times per render (while loops < MAX_FRAMESKIP). HOWEVER we also have the comparison to check if these updates are taking longer than expected in which case we should stop being greedy with the updates and go ahead and render (at least, this is what I think it's trying to do, please correct me if I'm wrong). But surely the current time being LESS THAN the time expected to take is the condition on which we want to continue updating?
As for the next part of the logic, the interpolation, I know we receive a value that we can use within rendering logic to draw game objects "in-between" updates so the movement doesn't seem jerky. Could someone expand on this though? And possibly even break down the actual code and how it arrives at the value we get.
So, to clarify, my overall question about this is: - Why do we check if the current time is greater than the time it was expected to take (this would surely mean it took longer than expected?? which is a BAD thing) - How does the interpolation value work, and how to we obtain it?
Thanks to anyone who can help me. Please just ask if you need more information from me.