The Game Loop

The game loop is the heartbeat of every game. We used a very rudimentary one so far (you can find it here) without any control over how fast or slow we update our game state and which frames to render. To recapitulate, the most rudimentary game loop is a while loop that keeps executing some instructions until we signal it to finish, usually by setting a variable called running to false

boolean running = true;
while (!running)
{
   updateGameState();
   displayGameState();
}

The above code runs blindly without a care for timing and resources. If you have a fast device then it will run very fast and if you have a slow one it will run slower.
The updateGameState() updates the state of every object in the game and the displayGameState() renders the objects into an image which is displayed onto the screen.

There are two things we should consider here: FPS and UPS.

FPS – Frames per Second – the number of times displayGameState() is being called per second.
UPS – Update per Second – the number of times updateGameState() is being called per second.

Ideally the update and render methods will be called the same number of times per second (preferably not less than 20-25 times per second). 25 FPS is usually enough on a phone so us humans won’t notice the animation being sluggish.

For example if we target 25 FPS then it means we have to call the displayGameState() method every 40ms (1000 / 25 = 40ms, 1000ms = 1s). We need to bear in mind that updateGameState() is also called before the display method and for us to reach 25 FPS, we have to make sure that the update – display sequence executes in exactly 40ms. If it takes less than 40ms, then we have a higher FPS. If it takes more than that, then we have a slower running game.

Let’s see some examples to understand the FPS better.

The following diagram shows exactly 1 FPS. It takes the update – render cycle exactly one second to execute. This means that you will see the image on the screen change once every second.

1 Frame per Second

The following diagram shows 10FPS. An update – render cycle takes 100ms. This means every tenth of a second the image changes.

10 FPS

10 FPS

But the above scenario means that the update-render cycle executes in 1/10 of a second EVERY time. That is an assumption and we can’t control the actual times on cycle executes, or can we? What happens if we have 200 enemies and every enemy is shooting at us? We need to update the state of each enemy and the states of their bullets and check for collisions in one single update. It’s different when we have just 2 enemies. The times will clearly differ. The same applies to the render method. Rendering 200 firing droids will clearly take more time than rendering only 2.

So what are the scenarios? We could have an update-render cycle that finishes in less than 100ms (1/10 of a second), finishes in exactly 100ms or finishes in more than that. On a powerful hardware it will be faster than on a weaker one. Let’s see the diagrams.

The cycle finishes before the desired timeframe so we have a small amount of free time before running the next cycle.

Frame with time to spare

The following diagram shows a cycle which falls behind. That means that the time it takes for a update-render cycle to finish is greater than the desired one. If it takes 12ms that means we are 2ms behind (still considering the 10FPS). This can mount up and every cycle we loose time and the game will run slowly.

Overdue Frame

The first situation is the desired one. This gives us some free time to do something before we kick off the next cycle. We don’t need to do anything so we just tell the game loop to go to sleep for the remaining time period and wake up when the next cycle is due. If we won’t do this the game will run quicker than intended. By introducing the sleep time we achieved constant frame rate.

The second situation (I skipped the ideal one as it almost never happens) when the loop is behind, requires a different approach.
To achieve constant speed in a game we need to update the state of our objects when required. Imagine a droid approaching you at a constant speed. You know if it travelled half the screen in one second, so it will take another second to reach the other side of the screen. To calculate the position accurately we need to know either the time delta since the last postion, and the current speed of the droid, or we update the position (status) of the droid at constant intervals. I will choose the second one as playing with deltas in the game update can be tricky. To achieve a constant game speed we will have to skip displaying frames. Game speed is NOT FPS!

Examine the following diagram. It is a scenario in which the update-render cycle takes longer than the desired time so we have to catch up. To do that we will skip the rendering of this frame and will do another update so the game speed won’t be affected. We’ll do a normal cycle in the next frame with even some time to give to the CPU to rest.

Constant Game Speed with Variable FPS

The above scenario has many variations. You can imagine the game update taking more than one full frame. In this case we can do nothing to keep the game speed constant and the game will run slower. We might have to skip multiple renderings to keep the speed constant but we have to make sure that we set the maximum number of frames allowed to be skipped because it can take quite a few updates to catch up and in case we skipped 15 frames that means we lost a lot from the game and it will just be unplayable.

The MainThread.java‘s run() looks like this:


	// desired fps
	private final static int 	MAX_FPS = 50;	
	// maximum number of frames to be skipped
	private final static int	MAX_FRAME_SKIPS = 5;	
	// the frame period
	private final static int	FRAME_PERIOD = 1000 / MAX_FPS;	


	@Override
	public void run() {
		Canvas canvas;
		Log.d(TAG, "Starting game loop");

		long beginTime;		// the time when the cycle begun
		long timeDiff;		// the time it took for the cycle to execute
		int sleepTime;		// ms to sleep (<0 if we're behind)
		int framesSkipped;	// number of frames being skipped 

		sleepTime = 0;
		
		while (running) {
			canvas = null;
			// try locking the canvas for exclusive pixel editing
			// in the surface
			try {
				canvas = this.surfaceHolder.lockCanvas();
				synchronized (surfaceHolder) {
					beginTime = System.currentTimeMillis();
					framesSkipped = 0;	// resetting the frames skipped
					// update game state 
					this.gamePanel.update();
					// render state to the screen
					// draws the canvas on the panel
					this.gamePanel.render(canvas);				
					// calculate how long did the cycle take
					timeDiff = System.currentTimeMillis() - beginTime;
					// calculate sleep time
					sleepTime = (int)(FRAME_PERIOD - timeDiff);
					
					if (sleepTime > 0) {
						// if sleepTime > 0 we're OK
						try {
							// send the thread to sleep for a short period
							// very useful for battery saving
							Thread.sleep(sleepTime);	
						} catch (InterruptedException e) {}
					}
					
					while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
						// we need to catch up
						// update without rendering
						this.gamePanel.update(); 
						// add frame period to check if in next frame
						sleepTime += FRAME_PERIOD;	
						framesSkipped++;
					}
				}
			} finally {
				// in case of an exception the surface is not left in 
				// an inconsistent state
				if (canvas != null) {
					surfaceHolder.unlockCanvasAndPost(canvas);
				}
			}	// end finally
		}
	}

Examine the above code very carefully as it implements the logic behind the diagram.
You can find the full code in the downloadable project.

There is another approach which I like. It is constant game speed with maximum number of frames per second. It uses interpolation to draw the state and it occurs on fast hardwares when there is time left for another rendering before the next game update. This can enhance the visuals of a game as it enables smoother animation but because we use mobile devices, giving the CPU some rest will save the battery quite a lot.
There is an awesome article on game loops here. I personally understood the game loops reading this article so I highly recommend it. The best I could find.

Note that I also modified the default values in the Speed.java class. The speed is measured in units/second.
Because we are setting our desired FPS to 50 that means that the speed will increase by 50*speed.value every update. To have the speed of let’s say 40 pixels/second you will need to set the speed delta for every tick to 2 (40 / (1000 / 50) = 2). In other words you need the droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second.

Download the code here and play with it.

Examine it and you have a constant game speed with variable frame rate.

To see how we measure the FPS check the next entry.

LinkedInRedditTumblrDiggTechnorati FavoritesShare

42 Responses - Add Yours+

  1. Vasi says:

    I want to remark something is wrong I do not know, but I think it would be fair to initialize beginTime = System.currentTimeMillis (), the first line below while (running).
    initialization of canvas she and her some time to be able to get a accurate FPS. Sorry for grammar mistakes.

  2. Juris says:

    Hey, I have used this code, and When i set FPS let’s say to 50, it jumps around 48 – 50. But 48 FPS mostly. I use SDL. Any idea? This could lead to objects updating unevenly? right?

  3. BorisKarloff says:

    Great code. There is a problem when u press home or back button and u come back in the app. I fixed in this way:

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

    //if it is the first time the thread starts
    if(thread.getState() == Thread.State.NEW){
    thread.setRunning(true);
    thread.start();
    }

    //after a pause it starts the thread again
    else
    if (thread.getState() == Thread.State.TERMINATED){
    thread = new MainThread(getHolder(), this);
    thread.setRunning(true);
    thread.start(); // Start a new thread
    }
    }

    and this
    @Override
    protected void onPause() {
    Log.d(TAG, “Pausing…”);
    MainThread.running=false;//this is the value for stop the loop in the run()
    super.onPause();
    }

    making the “running” variable, static

  4. Shasha says:

    How would you handle touch events with this? Currently my update() call is done outside my main game thread because it is called directly from a touch listener is the main game activity. How would I get the update() call away from the touch listener and into my thread? Would I need to save the calls from touch listener elsewhere, to be consumed during an update() call from the thread?

  5. Rene says:

    You have a good way of explaining this matter clearly. I think your next project should be to bundle all your tutorials into a book (PDF) about 3D Android game programming :)

  6. Hasan says:

    Hey, Great Work! Dude your tutorials help me, a high school-student, learn game programming.
    But there is a question of mine over FPS thing.

    I, by applying similar algorithm, got to know the default FPS of the game on my device Samsung Galaxy S3. Please note that its just default for what my phone gives.
    So the result came out to be 30 FPS approx. (And the animations were extremely fluid.)

    But now when I use your algorithm with MAX_FPS = 30 the game on my S3 is sluggish!
    Why is that happening if everything was same itself?
    And when I put MAX_FPS = 55 the game gets better. (With relatively better fluidity).

    I’ll be extreme glad if you could help me.
    Thanks.

  7. jazz says:

    Thank you for providing this great tutorial:D
    but i have a question regarding the elapsed time.

    should’t we put
    beginTime = System.currentTimeMillis();
    right after
    timeDiff = System.currentTimeMillis() – beginTime; ?

    because all those sleeptime checking,frameskipping will still consuming some millisecond and i think we should add all this into the calculation of elapsed time as well.

    please help ~ :)

  8. EGS says:

    Great article!

    Used it as starting point for my first game. However I stumbled across a synchronization problem when using Tread.sleep(). Solved by using surfaceHolder.wait() instead.

    http://www.giskeskaaren.com/wordpress/?p=99

  9. Nikhil says:

    Your articles are rightly paced for someone new to android. Very good for learning !!!
    Last paragraph of above article is confusing for me.

    1) “If desired FPS is 50, speed will increase by 50*speed.value every update” ??
    Speed of droid should be constant according to me.

    2) “droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second” ??

    If it travels 2 pixels every update and in total 50 updates happen in a second, then it will travel 2*50=100 pixels and not 40 pixels ??

    Please help me understand this.

  10. Nikhil says:

    Your articles are rightly paced for someone new to android. Very good for learning !!!
    Last paragraph of above article is confusing me. Last Paragraph says:

    “Because we are setting our desired FPS to 50 that means that the speed will increase by 50*speed.value every update. To have the speed of let’s say 40 pixels/second you will need to set the speed delta for every tick to 2 (40 / (1000 / 50) = 2). In other words you need the droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second.”

    My Doubts
    1) “If desired FPS is 50, speed will increase by 50*speed.value every update” ??
    Speed of droid should be constant

    2) “droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second” ??

    If it travels 2 pixels every update and in total 50 updates happen in a second, then it will travel 2*50=100 pixels and not 40 pixels ??

    Please help me understand this.

  11. Nikhil says:

    Your articles are rightly paced for someone new to android. Very good for learning !!!

    Last paragraph of above article is confusing me.

    Last Paragraph says:
    “Because we are setting our desired FPS to 50 that means that the speed will increase by 50*speed.value every update. To have the speed of let’s say 40 pixels/second you will need to set the speed delta for every tick to 2 (40 / (1000 / 50) = 2). In other words you need the droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second.”

    My Doubts
    1) “If desired FPS is 50, speed will increase by 50*speed.value every update” ??
    Speed of droid should be constant

    2) “droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second” ??

    If it travels 2 pixels every update and in total 50 updates happen in a second, then it will travel 2*50=100 pixels and not 40 pixels ??

    Please help me understand this.

  12. Conrad B Hart says:

    Great tutorials! :)

    Can you tell me how System.currentTimeMillis() – beginTime gives the cycle time, though? its says is returns the time since 1970??

    Thanks

  13. Conrad B Hart says:

    Great tutorial, explained very clearly. Keep up the good work! :)

    However, can you describe how:
    System.currentTimeMillis() – beginTime gives the time taken for that cycle, timeDiff (update + draw time, as I understand it). Doesn’t System.currentTimeMillis() return the time since 1970???

    Thanks

    • Impaler says:

      beginTime gets the value just before the update and drawing happens. Check line 27.
      It’s only a reference.
      timeDiff is the difference between the reference time and the current time.

      So when starting the measurement at X point in time, which is today at 12:00.00 for example (this is what currentTimeMillis() gives) and the update with the rendering takes up 3 seconds, the timediff will be:

      currentTime since 1970 minus the time the update has started (begin time).
      Which gives you 3 seconds as 12:00.03 – 12:00.00 = 3 seconds.

      • Conrad B Hart says:

        Perfect :)

        Thanks again. You can delete my other post – my browser was playing up so tried again :S

  14. dzule says:

    Thanks for the great tutorials. I’m just learning and I keep running into similar issues when I leave the app and try to resume it. This isn’t the only game loop template / tutorial I run into issues doing this.

    I’m running in android 2.3.3 and everything works fine I can click the bottom the the screen and the game exits like it should. However if instead I press the home button then click the app icon again to resume it the game looks like its working with the robot bouncing around but it no longer accepts any click events. The debugger doesn’t even go into onTouchEvent(MotionEvent event). If I keep tapping the screen I can sometimes get android to popup a message saying the application has stopped responding and allow me to force close it.

    Any ideas whats going on and how to solve it?

    Thanks!

  15. [...] When in android should I place main game loop in the initial activity class? I’m trying to create a game loop using this tutorial. [...]

  16. Zippy says:

    Excellent excellent tutorial! Couple of questions, in the last ‘while’ loop what is the purpose of the line:

    “sleepTime += FRAME_PERIOD;”

    Wouldn’t this just set sleepTime back to your target interval (frame period) and therefore mean that the loop will never run more than once? I must have it wrong! But would be grateful if someone could explain :-)

    Lastly, I’ve got this running on my test device and also on the emulator, now I know the eumlator is s-l-o-w and I get only about 10FPS on it compared to 60fps on my device (I’m running this with my target frame period set to 16ms) but on the emulator, my object takes twice as long to go from the bottom to the top – should it not take the same amount of time, but appear a lot ‘chooppier’/jerky??

    Thanks again for any help you could offer!! :-)

    • Derrik Curran says:

      If you set a frame period of 20ms and a cycle takes 60ms to run, the sleep time will be -40ms. If you then update the panel and add the frame period to the sleep time, the new sleep time will be -20ms which is still less than 0 so the loop will run again.

      That said, I’m not sure I understand the logic either. If the sleep time is -10ms and the following render-less update takes 15ms to complete, no further frames will be skipped (since the 20ms frame period added to the -10ms sleep time exceeds 0) but the next normal cycle will start 5ms later than it should have.

      I believe the amount of time the update takes should be taken into account.

      Shouldn’t it be:
      long updateBeginTime = System.currentTimeMillis();
      this.gamePanel.update();
      long updateTimeDiff = System.currentTimeMillis() – updateBeginTime;
      sleepTime = (FRAME_PERIOD + sleepTime) – updateTimeDiff;
      framesSkipped++;

      That way, if the first render-less update cuts into the next frame, sleepTime will be set to a number less than 0 and another render will be skipped.

      Can someone confirm whether or not my method makes sense? I don’t really have any experience with this.

  17. [...] It maintains the frame rate of our game. Here’s a good article regarding the game loop: http://obviam.net/index.php/the-android-game-loop/. Also, write a new class inheriting the SurfaceView class. I’ve called mine [...]

  18. [...] particually in the Killer Game Programming in Java book and in this tutorial I just found: Here Just a simple, timed gameloop with a back [...]

  19. [...] trying to implement a SurfaceView, calling its onDraw() method from a Thread, based on this tutorial. My app is giving ANR after I start the below code [...]

  20. Simon says:

    Hello,
    one small question:
    Why do you set the complette gameloop-body into a synchronized block?

    greetings

    • Impaler says:

      As the renderer and the update methods run in separate thread and both access the same instances of game objects, I have to take care that no object is modified by 2 threads at the same time.
      Failing to do so, will result in exceptions.

      • Ed says:

        Suppose I had the View and Thread running in the same file how would I set up the game-loop body. Because I put both in the same file so I could understand most examples I see better. Thanks a lot though for the tutorials, it makes a lot of things easier to get.

        • Impaler says:

          You mean the View and GameLoop to run in the same thread? Or do you mean creating the Thread as an innerclass for the view?
          In the first case, you will call the update just before the render and it will be sequential.

          • Ed says:

            Creating the thread as a innerclass of for the view.

          • Impaler says:

            For this you will just have to move the content of the file containing the thread into your main file. But I wouldn’t do that as it can get cluttered and hard to read.
            You might want to look up how to use volatile variables to handle concurrency as well if yo will access shared data.

  21. Jesse Blasengame says:

    Very cool. I’m more into the graphics design and 3d modeling but I’ve been trying to get into the coding so I can do it all myself if necessary. Shoot me an email if you’d ever like to work on a bigger project and would like some graphic/art help. Meanwhile I’m going to finish your tutorials and then on to the next ones I can find! You have been great, these are the best tutorials on Android games I’ve found so far!

    Thanks again!

  22. rob says:

    you have another typo.

    Where you say “If it takes 12ms that means we are 2ms behind (still considering the 10FPS).”

    I think you meant to say “If it takes 102 ms…….”

  23. lokendra says:

    Thank you for the amazing tutorial to make me start gaming in android !!!

  24. Lindroos says:

    This series of tutorial are awesome and I have a question about send value to Activity, hope you can help me.

    I recoded your example “The Game Loop” and made it become a game that user can destroy robots by touch to increase score,
    the question is how can I send score to next Activity ?
    because I want to let user decide play again or not and show the score with it.

    In the usual way there is a button in OnCreate and with an OnClickListener,
    but in this case, I don’t know how to do.

    Thank you.

  25. Molion says:

    You say that with 2 pixels per update we get 4 pixels a second with 50 updates a second. However 2 pixel per update times 50 updates per second = 100 pixels per second (2*50=100). To get 40 pixels a second we need 50 updates per second divided by 40 pixels per second = 0.8 pixels per update (50/40=0.8).

    • Impaler says:

      I’m not sure I get what you mean but here is what I understood.

      You will be displaying an image in a render cycle. If you want to have a 50 fps renderer you have to display the image (the whole screen is an image) every 1000/50 = 20 millisecond.

      An image can consist of multiple pixels. A typical HVGA is 480×320 = 153.600 pixels.
      That many pixels are drawn to the screen every 20 ms in case of a 50 fps.
      Hope this clarifies it a bit.

  26. Sravan says:

    Hi,
    Thats really informative…
    i must appreciate your effort

    i have a question or help you can say.

    in your example to explain game loop.. you are calling

    this.gamePanel.render(canvas);

    for drawing…

    but if i use OpenGL ES, how can i control this step… since Renderer has OnDrawFrame. which runs automatically….

    this.gamePanel.render(canvas);(internally it call to draw bitmap)
    is a synchronous call i believe, that’s the reason why we are able to calculate time to update & draw and then sleep in extra time….

    how can i achieve this with OpenGL ES, with Renderer??

    it would be great help.

    • Impaler says:

      Hi there,

      That is a very good question. In the next set of articles I will be switching to OpenGL and indeed, the render cycle is not controllable from within the main thread.
      I will introduce a delta and will use interpolation to display the correct positions of the objects.

      It will be interesting as it will include volatile variables to work across threads and multi-threading will have to be done properly.

      I’m actually working on some proof of concepts and will write about them as soon as everything is in place and working.

      The update and render will work independently.

      Good observation!

  27. Thomas says:

    Thanks a lot for your tutorial. I have had experience programming graphics before using SlimDX and SDL but I was unsure how to get to that point of control on Android. Your walk through has been invaluable!

    I thought you’d like to know you have a little typo:

    “The following diagram shows 10FPS. An update – render cycle takes 10ms. This means every tenth of a second the image changes.”

    10ms should read 100ms.

  28. nobody says:

    Thank you for the tutorial, great intro-tutorial for starters.

  29. hl says:

    very cool, article, began to understand the game design a bit.

    thanks