Home > SoulHow > SoulHow to avoid infinite loops

SoulHow to avoid infinite loops

June 5, 2008

NOTE: Comments are locked. I no longer answer questions about the Game Maker tutorials on this blog; I suggest you take any questions to the Game Maker Community. For more info, view the FAQ page.

Skill Level: Experienced user (6)

I have decided to write this short SoulHow Game Maker Assistance Article about infinite loops. Infinite loops are the landmines that stop your game faster than…well something that stops fast.  Very fast.  They don’t necessarily come up that often, but they come up enough.

In this article, I will discuss some techniques to prevent infinite loops. Even if you haven’t encountered one of them, it’s very important to learn about them. First off, I will mention that an infinite loop is one which never stops going.

Take a look at this bit of code:

myvariable=5;
while (myvariable>2)
{
myvariable+=1;
}
show_message("Finished!");

Take a look at what this code does. First, it sets myvariable to 5. Then, we mosey on down to the while loop, which has the expression “myvariable>2”. 5 is certainly greater than 2, so on we go to the first statement (the only statement). We add 1 to myvariable, making it 6, and then we hit the close bracket. We loop back up to the while expression. 6 is greater than 2, so we go down to the statement again, add 1 to myvariable (making it 7), and up we’re dragged to the while expression once more. I’m sure you can see the pattern here. If we keep adding to our variable, it will always be greater than 2 and therefore we never move down to the call to show_message(). That is what is meant by an infinite loop: a loop that repeats infinitely.

Do you know what a break statement is? No? Ok.

…what? Oh, you want to know what a break statement is?

Fine, I’ll explain. A break statement breaks from a loop, ending it entirely and moving on to the code just after it. Let’s return to our example above and add one more line:

myvariable=5;
while (myvariable>2)
{
myvariable+=1;
if (myvariable==10) break;
}
show_message("Finished!");

Ok, now we have the same initial conditions, and the same expression. The only difference is the line with the “break” on it. Let’s see what happens now. myvariable gets 5 slapped on it, and the while expression comes back true. On we go to the first statement, adding 1 to myvariable. Now it’s equal to 6. As we progress to the next line, myvariable does not equal 10, so this part is ignored. Then we go back to the expression again, yadda yadda, until myvariable equals 9. Now, 9 is greater than 2, so we enter the while loop again. Adding 1 to myvariable gets us a value of 10. And yes, for all you who cheated off the kid with glasses in fourth grade math, 10 is indeed equal to 10. So on that next line, we reach the break statement. Out of the loop we go.

We exit the loop just after the close bracket, taking us to the next line. The call to show_message brings up an ugly gray box, but it does bring it up! Success! Let’s look at another, more practical example.

while(!place_meeting(x,y+1,objWall)) y+=1;

This code will move an object down until it meets a wall. Maybe for a landing script in a platform game. We might execute it when we want to instantly ground the player. Consider, though, what happens when we run this code while the player is jumping over an endless pit. We continuously check whether there’s a wall under the player and then if there’s not, we move him down. Because there’s no wall anywhere underneath the player when he’s over an endless pit, we never stop moving the player down. OMG ANOTHER INFINITE LOOP NOOOOO

Fear not, for we can get out of this as well. We’re going to create what I like to call a breaker variable. Back to da codez:

breaker=32;
while(!place_meeting(x,y+1,objWall) and breaker>0) {y+=1; breaker-=1;}

This time, we have a bit of protection. Should this code be executed over an endless pit, we’ll continuously move the player downward – until our breaker variable kicks in. As you can see I’ve added another part to the while loop expression, joined with the and operator. I’ve also added another statement to the block after the expression – which subtracts 1 from the breaker variable.  So each time we reach the statments of the loop (called an iteration), we add 1 to y and subtract one from “breaker”. When breaker inevitably reaches 0, the whole while expression turns false and the loop ends regardless of the fact that a wall is never met.

And that, my friends, is how you beat the infinite loop menace. Either use the built-in break statement or use the expression and a breaker variable to break from the loop yourself. It’s a good idea to recognize where possible infinite loops could occur and prevent them, because in some ways they can kill your game’s public reception worse than an error message. At least in an error message the player can try to click ignore and if that doesn’t work they have a sure fire way to terminate the game (the “abort” button). An infinite loop means the user must control-alt-delete the game and go through the whole “end now” stuff, a very irritating procedure the aftermath of which can *sometimes* cause memory problems.

One last thing I’d like to mention about infinite loops is this.  While it is good to include failsafes for infinite loops, it can be a problem for testing the game.  For example, if we were using some code similar to the first example provided in this article and we meant to subtract from myvariable instead of add to it, because we included a failsafe (the break statement) the loop will end without a visible hitch but now myvariable equals 10 instead of 1 like we’d probably be expecting it to.  Because no visible effects of our typo would be immediately visible, it might be a bit of a hassle to search through our code figuring out why some other part of code (which “expects” myvariable to equal 1 after that code) doesn’t work right.

So when creating failsafes like those described above, it’s a good idea to be careful and realize exactly what kind of failsafe you’re putting on to ease debugging later.  You might also consider instead of using a break statement in your loop’s failsafe, using a call to show_error() which displays a custom error message and allows you to abort the game so you know exactly when and where a problem occurs rather than having to guess.

Well good luck with your Game Making.

If you enjoyed this article, please consider checking out the rest of the blog.

If you have a technical question, such as “How do I do this” or “this is not working right” (relative to something with your Game Maker game after reading this tutorial), please head over to the Game Maker Community and ask there.  I can’t answer any such questions in this blog and the members at the GMC will be more than capable to help you.  For more info, go to this blog’s FAQ page.

Advertisements
%d bloggers like this: