The Art of Handling Failure

If you are looking for some wisdom about handling personal failure, stop reading and call a shrink. My focus here is to discuss application failure, the situation where some defensive code has found an anomaly and needs to handle it. There's a great conversation you can start with a group of programmers about how to handle errors or failures in games. The subject has more grey area than you'd think, and therefore doesn't have a single best strategy. The debate starts when you ask if games should ignore failures or if they should stop execution immediately.

I'm talking about the release build, of course. The debug build should always report any oddity with an assert, so programmers can catch more bugs in the act. The release build strips asserts so there's a good question about what should happen if the assert condition would have been satisfied in the release build. Does the game continue, or should it halt? As with many things, there's no right answer. Here's an example of two functions that handle the same error in two different ways:

 void DetectFixAndContinue(int variable) {    if (variable < VARIABLE_MINIMUM)    {      variable = VARIABLE_MINIMUM;      assert(0 && "Parameter is invalid");    }    // More code follows... } void DetectAndBail(int variable) { if (variable < VARIABLE_MINIMUM)    {      throw ("Parameter is invalid");    }    // More code follows... } 

The first function resets the errant variable and calls an assert to alert a programmer that something has gone wrong. The execution continues, since the variable now has a legal value. The second function throws an exception, clearly not allowing the execution to continue.

Best Practice

Notice the assert statement in this example. It's a conditional that includes a text string. Since the conditional is always false, the assert will always fire. The text string will appear in the assert dialog box, and can give testers a clue about reporting the problem, and even what to do about it. You might add, "You can always ignore this" to the text string so testers can continue playing.

The debate most programmers have goes something like this: If you ever reach code where an assert condition in debug mode evaluates to false, then something has gone horribly wrong. Since you can't predict the nature of the failure, you must assume a worst case scenario and exit the program as elegantly as possible. After all, the failure could be bad enough to corrupt data, save game files, or worse.

The other side of the argument takes a kinder, gentler approach. Failures can and will happen, even in the shipping product. If the program can fix a bogus parameter or ignore corrupt data and continue running, it is in the best interests of the player to do so. After all, they might get a chance to save their game and reload it later without a problem. Since we're working on computer games we have the freedom to fudge things a little; there are no human lives at stake and there is no property at risk due to a program failure. Both arguments are valid. I tend to favor the second argument because computer games are frequently pushed into testing before they are ready and released way before testing is completed. Bugs will remain in the software, and if the game can recover from them it should.

Best Practice

Never forget that your game's purpose is entertainment. You aren't keeping an airplane from getting lost and you aren't reporting someone's heartbeat. Remember that games can get away with lots of things that other software can't. If you are relatively sure that you can make a choice to allow the game to continue instead of crashing, I suggest you do it.

That's not to say that games can't find themselves in an unrecoverable situation. If a computer game runs out of memory, you're hosed. You have no choice but to bring up a dialog and say, "Sorry dude. You're hosed," and start throwing exceptions. If you're lucky, your exit code might be able to save the game into a temporary file, much like Microsoft Word sometimes does when it crashes. When the game reloads it can read the temporary file and attempt to begin again just before everything went down the toilet. If this fails, you can exit again and lose the temporary file. All hope is lost. If it succeeds, your players will worship the ground you walk on. Trust me, as many times as Microsoft Word has recovered pieces of this book after my portable's batteries ran out of electrons, I can appreciate a little data recovery.

Best Practice

If a Win32 function fails, you must usually call GetLastError() to determine the exact nature of the error. Instead, simply put @err,hr in your debugger's watch window. This will show you a string formatted version of the error.

Game Coding Complete
Game Coding Complete
ISBN: 1932111751
EAN: 2147483647
Year: 2003
Pages: 139 © 2008-2017.
If you may any questions please contact us: