Advertisement
Games

Understanding the Game Loop - Basix

by

Almost every game can be thought of as having one main function that contains all the game logic, and which is run either when the user does something, or after a certain amount of time. This cycle of running the same core function over and over again is called the game loop, and is crucial to understand for any sort of game development.

You've probably played the board game Chutes and Ladders (or Snakes and Ladders as we call it in the UK).

(Photo credit incurable_hippie on Flickr)

Each player rolls the die (or spins the spinner) and moves forward the number of squares indicated. The square they land on may direct them to slide backwards or climb forwards several spaces. The player wins the game when they get to the final square.

So, in the above image, landing on Square 6 makes you climb four squares to Square 10; landing on Square 19 makes you slide back 15 squares to Square 4; and landing on Square 64 means you win the game.

Now suppose you're playing single player, to practice. You do the same thing as above, over and over again, until you reach Square 64. How would you represent this in code?

You'd probably start by creating an array to store the values of the squares. Most elements would contain zero, but a few would contain either a positive number (indicating a ladder), or a negative number:

Note: This is pseudocode, not AS3

var specialSquares:Array = [];
specialSquares[0] = 0;		//the square the players start on, before 1
specialSquares[1] = 0;

...

specialSquares[6] = +4;

...

specialSquares[19] = -15;

...and so on. Then, you'd have a function to move the player based on the number on the die:

function movePlayer(squares:Number) {
	newSquare = currentSquare + squares;
	newSquare += specialSquares[newSquare];
	currentSquare = newSquare;
}

You could then put this inside a bigger function representing a whole turn:

function takeATurn() {
	diceNumber = random(1, 6);	//random number between 1 and 6
	movePlayer(diceNumber);
	if (currentSquare == 64) {
		//player has won! game over
	}
}

This function, takeATurn(), encapsulates the core game logic for single-player Chutes and Ladders. But how do we actually get this function to run? There are several options:


Run the Function Based on Player Input

We could place a button on the screen, and have it call takeATurn() each time it's clicked. If you've ever played Facebook Scrabble or Words With Friends, you've seen this option in action.


Run the Function Based on Time Passed

We could make takeATurn() run every sixty seconds.

Actually, this option is a little more complicated than it may seem. In practice we never see any games without some player input; with no interaction, it can't really be considered a game. But still, some games have an element of "calendar time" involved. Consider FarmVille: you, the player, plant your crops, and then every few minutes (or hours) they develop a little further, from seeds to shoots to fruit. And in some modes of Civilization, you're given a set amount of time (say five minutes) to make all of your moves for one "turn"; once those five minutes are up, the core game logic function is triggered.


Do Both

Some games use a mixture of these two options: for example, Mafia Wars has a resource called "energy" which refills one unit every five minutes; you take actions in the game by using this resource, so the core game logic function is still triggered by a user action, it's just restricted by time.

This is a pattern common to most games: one piece of code containing the core game logic is triggered repeatedly. We call this the game loop.

There's a term for the action or period of time that triggers the core game logic code as well: a tick (like the sound a clock makes).

So in Civilization, the tick is every five minutes. In Words With Friends, playing your turn causes a tick. In other words, the game loop runs once per tick.


What About Mario?

Super Mario Bros doesn't seem to fit into either of these categories. Mario responds to the player's input... and yet all sorts of things are going on without you needing to do anything (Goombas walk around, the timer counts down, objects fall). Are there two game loops?

No. There's just one, and it's triggered solely by time -- but with a tick of just a fraction of a second.

In Civilization, you have a period of five minutes to input everything you want to do in the current turn, before the game "ticks" and runs the game loop again based on all your input. So if you say, in Turn 23, that you want your warriors to attack a deer, then in Turn 24 everyone's getting venison for dinner.

It's the same with Mario. If you press the Jump button during one tick, then in the next iteration of the game loop, Mario will start to jump.

Note that you don't have to time your Jump press to occur just as the core game logic function is triggered -- all of your actions during a tick period are recorded and used during the next iteration of the game loop.


Is Everything Controlled Through the Game Loop?

All of the game logic is handled in the game loop. But there's more to a game than its logic, graphics being the major example.

Drawing graphics to the screen is hard work for the computer. Let's suppose you've got an action game with a tick of 1/60th of a second; that should make the game feel like it's reacting fluidly to the player's controls. But what happens if the player's computer is too slow to run all the code for the game logic (responding to input, simulating gravity, running AI routines) and draw everything to the screen within 1/60th of a second?

In this scenario, we can use two separate loops: a game loop and a draw loop. We could then run the draw loop at a much lower frequency than the game loop; let's say we refresh the screen half as often, i.e. every 1/30th of a second.

The amount of processing power required by the game may vary from level to level. Consider a shoot-'em-up: the first few levels will have very few ships on the screen, to ease the player in gently, while the last levels could have dozens of enemy ships and hundreds of bullets all flying around the same scene at once. The game loop has to figure out how all those objects should move, and the draw loop has to render each one, so while it may have been possible to run both the game loop and the draw loop every 1/60th of a second at the start of the game, by the end something has to give.

It's generally simpler to slow down the draw loop than the game loop, if you have to choose. Adjusting the game loop's tick length means adjusting everything in your game that's based on time; if Mario runs at a speed of 20 pixels/second, and you design the game with a tick length of 1/60th of a second, then you have to move him 1/3rd of a pixel per tick. If you adjust the game loop to have a tick length of 1/30th of a second, then you have to adjust this to 2/3rds of a pixel per tick -- and even that's a simple change compared to keeping physics calculations and AI routines consistent.

For this reason, games often aim to keep the game loop's tick consistent, and slow down the draw loop if more power is needed. If you've ever turned on the FPS counter (short for Frames Per Second, the number of times the draw loop is running per second) in a first person shooter, you'll have seen it change depending on how much is on the screen; the draw loop's refresh rate gets adjusted automatically. The game may look juddery -- like a live streaming video on a slow internet connection -- but unless it's being run on a computer with a lot less power than the game developers had in mind, all the objects in the game world will continue to move and interact at the correct speeds.

For a great article explaining how Flash deals with this, check out Sean Christmann's post on the 'Elastic Racetrack'.

Related Posts
  • Game Development
    Haxe
    Write Once, Publish Everywhere With HaxePunk: Cross-Platform TipsHaxe article 2 main image resized
    Tips on how to make your games work well on multiple types of devices. We'll talk about screen sizes and resolutions, input types, interface layouts, and tips for app store submissions.Read More…
  • Game Development
    Game Design
    The Difference Between a Blatant Clone and Building on a Proven GameCloning games vs building on proven genre
    Games have been around for long enough that clearly defined game genres and mechanics have emerged. Most new games belong to one or more of these genres, and are composed of some combination of these mechanics. New genres and mechanics do occasionally arise and surprise the world, but they are rare exceptions.Read More…
  • Game Development
    Implementation
    Write Once, Publish Everywhere With HaxePunk: Making a GamePreviewretinaimage
    You've probably had this experience before: you hear about an awesome game, but then you find out that it's only coming out on the one platform that you don't own. It doesn't have to be this way. In this tutorial, you will learn how to use Haxe to make a game in one development platform that can target multiple gaming platforms, including Linux, Mac, Windows, iOS, Android, and Flash.Read More…
  • Game Development
    Implementation
    Make a Neon Vector Shooter for iOS: More GameplayGeometry wars ios enemies
    In this series of tutorials, I'll show you how to make a Geometry Wars-inspired twin-stick shooter, with neon graphics, crazy particle effects, and awesome music, for iOS using C++ and OpenGL ES 2.0. So far, we've set up the basic gameplay; now, we'll add enemies and a scoring system.Read More…
  • Game Development
    From Scratch
    Make a Megaman-Inspired Game in Construct 2Megaman 400px
    I am going to walk you through the creation of a Megaman-inspired shooter/platformer game. We will be more focused on the shooting aspects of the gameplay rather than the platforming. In this tutorial I will be using Construct 2 as the tool to make the game, but I will explain the logic using pseudocode so that you can follow this tutorial in any language or engine of your choice.Read More…
  • Game Development
    Game Design
    Don't Frustrate the Player: 3 Rules for Keeping Them InvolvedDont frustrate the player 400px
    It's not enough to just say that a game is simply "bad", and that it has nothing it can teach us: why is it bad? Is there a problem with the level design or the character movement? Is the game not rewarding? Perhaps the game is repetitive and unimaginative, or perhaps the game is targeted towards a demographic other than us. There are many ways to lose a player, but the fastest way is to make your game "not fun" - so how can we avoid this?Read More…