Game loop

I was considering using the following for my game loop. Anyone have an alternative?


long nextFrameStart = System.nanoTime(); 
while(true) { 
  do { 
     // ... update the game state ... 
     nextFrameStart += FRAME_PERIOD; 
  } while(nextFrameStart < System.nanoTime()); 
  // ... render the state to the screen ... 
  long remaining = nextFrameStart - System.nanoTime(); 
  if (remaining > 0) { 
     Thread.sleep(remaining / 1000000); 
  } 
} 

You are pausing your loop twice.


long currentTime;
while(true) {
  currentTime = System.nanoTime();
  .
  . //all game stuff
  .
  while(System.nanoTime - currentTime < FRAME_TIME);
}

If you don’t call Thread.sleep(), CPU will be pegged to 100%

[edit] Which is especially bad if you want it to be responsive to the keyboard or mouse. Also, the inner loop is required to skip rendering (frame skipping) if it gets behind.

That will not affect the responsiveness of the mouse or keyboard. The JVM has full control over thread resources. All you are doing is telling the JVm that you are no taking a pause. I since we are talking about 4K, less is more. Your loop will take at least twice as much space as mine. Don’t worry about treating the rest of the system properly in that respect. Just make sure your game runs.

I have already made game loops like this with no loss of response from the mouse or keyboard.

Let’s assume that is the case. What about frame skipping?

Your loop is OK but why make multiple updates between rendering?

About the sleep() call & mouse input, I’ve found that on some computers it does make the mouse lag so I always do sleep(1). Note that this does kill performance a little though since on MS Windows the sleep time actually turns out to be about 20milliseconds regardless of what number you give to sleep() that’s less than 20.

The idea behind the inner-loop is to update the model more than once if the game is lagging behind. Meaning, on slower computers, it will occationally skip drawing one or more frames.

[edit] Note, this means that you need to separate out your rendering code from the code that updates the model. Unfortunately, that often means extra loops. For instance, to update the position of all the sprites in the game, you’ll need to iterate over the collection of sprite positions. Then later when you draw the sprites, you’ll need to iterate over that collection again to access those sprite positions. You could kill 2 birds at the same time and do the position updates and drawing within the same loop, but you’ll never be able to skip frames if you do that.

[edit] Also, this design assumes that it takes a lot less time to update the model than it does to render the frame to the screen. The inner-loop can be modified to put a cap on the number of times the model can be updated per rendering. Meaning, you can set the max number of frames to ever skip. That way for computationally complex games it may occationally slow down (lag behind), but at least it won’t be skipping so many frames that the screen effectively keeps freezing, making the game unplayable.

Thread.sleep() is more accurate than you think at least under windows. You can measure the sleep time using System.nanoTime(). I found it often sleeps about 0.1 extra milliseconds than specified. But, that still doesn’t matter. If it sleep too long on one iteration, it will sleep less the successive iteration.

I completely agree with what you are saying. However, we are talking about 4K. It is very very unlikely that you will have that kind of lag. You can also lock the frame rate to a sufficiently low count, such as 40 frames/sec that it should work fine. The way you want to do it will add upwards of 100bytes or more to your final size. This is very significant in the 4K compo. You can do it whichever way you would like. And if you can fit all you want into it with the extended loop logic, then more power to you.

frame skipping is like… the least of your worries in 4K… O_o

Frame skipping is a huge worry in 4K. =)

Miners4k, for examples, needs to run at the same speed on all computers to make sure the level times are “fair”.

If your clock displayed simulation time, rather than real-time - this would not be a concern.
Though I suppose it depends on whether it is acceptable for a 1 second count-down to be potencially longer than 1 second.

Miners4K is one specific example where frame skipping would be a worry (if you didn’t use simulation time as Abuse suggested)

with the timing code provided by oNyx, a few frame skips (like, in Goomba4K) are not a huge deal, the timing code more or less accounts for such things

I was experimenting with the game loop posted above, when I noticed that my Windows clock was slowly gaining time. After a few hours, I had to move the clock back 20 minutes. I found a workaround snippet of code that works well in this link:

http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=80aeda52b83875e57063f604054c:WuuT?bug_id=6435126

Obviously, we can’t paste that into a 4K game, but if you’re developing something larger, this may be relevant.