How to debug fast-paced action games
April 19, 2007 on 3:10 pm | In Actionscript, Games | 8 CommentsDuring the development of my last game I took a different approach of debugging it which is especially useful for real time games. Because it’s so simple I’m wondering why I haven’t used this method before (perhaps too lazy ? ;-)) Usually you include a bunch of trace statements everywhere or create a logger system which prints out the information you need. But this is useless in games where many simultaneous events occur. Your logger will be flooded with messages so it’s hard to keep track of everything.
The idea is to include a simple playback control by using keys or invoking a custom breakpoint() method, so you can stop and resume the game at any time and trace out additional information with it. Here is how it’s done (again, basic stuff here):
var updateGame:Boolean = true;
var useBreakpoints:Boolean = false;
//main loop: update game logic, render scene..
function tick():Void
{
if (!updateGame) return;
update();
render();
}
function update():Void
{
//...
if (player.collides(wall)) breakpoint("player-wall collision");
//...
}
So whenever the player collides with the wall, the game stops and prints out the passed string. The breakpoint function itself can look like this:
function breakpoint(message:String, forced:Boolean):Void
{
//just quit if breakpoints are disabled
//this can be overridden by setting forced=true
if (!useBreakpoints && !forced) return;
//print out message and stop game
trace("breakpoint:" + message);
updateGame = false;
}
Obviously, when breakpoint() is called, ‘updateGame’ is set to false so the main loop stops doing anything. The function also checks if breakpoints are enabled so you can globally turn them on or off. Furthermore, you have the option to call breakpoint() with a forced flag, so even if breakpoints are entirely disabled, your game will stop at that point. This is useful to keep some breakpoints active for very rare events or stuff you aren’t sure is working at all and at the same time you can test the game without being constantly bothered by existing regular breakpoints. I have also defined some keys:
function onKeyDown()
{
switch (String.fromCharCode(Key.getAscii()))
{
//stop/resume game
case "u":
updateGame = !updateGame;
break;
//toggle breakpoints
case "b":
useBreakpoints = !useBreakPoints;
trace("breakpoints " + (useBreakpoints ? "on" : "off"));
break;
//step through game
case "s":
if (!updateGame)
{
update();
render();
}
break;
}
}
Game playback is toggled with ‘u’, and when the game is frozen by a breakpoint call, you can advance frame-by-frame by pressing the ’s’ key or resume playing by pressing ‘u’. This makes debugging much easier because you actually now have the time to think about what’s going on when something goes wrong ;-).
That’s a really nice and simple solution. Great stuff. Only one tiny alteration I would consider making is, if the tick() method got more complicated than those two lines, also implement a “forced” parameter to the tick method, then use that to call tick from your step keypress. For example:
function tick( forced:Boolean ):Void
{
if (!updateGame && !forced) return;
update();
render();
}
Then in the switch statement, rather than replicating the tick method lines of code, simply call tick, like so:
//step through game
case “s”:
if (!updateGame)
{
tick( true );
}
break;
Tiny suggestion. But if you keep the tick method small enough, not really needed.
Anyway, thanks for the code tip!
Comment by Miles Green — April, 20 2007 #
[...] How To Debug Fast Paced Action Games [...]
Pingback by Starsky & Hutch » Blog Archive » Polygonal Labs Articles — April, 20 2007 #
Thanks for the enhancement, it makes more sense this way :-) Also note that the a breakpoint() function is not a true breakpoint so all the code after it will be executed until the next tick() function is called.
Comment by mike — April, 20 2007 #
Hi,
just crossread the website. Nice stuff indeed.
If you really want to stop at some point and enter the debugger programmatically you can do this:
import flash.debugger.enterDebugger;
enterDebugger();
To me thats often really useful and i have no idea why Adobe pulled that from the docs.
flow
Comment by flow — June, 14 2007 #
thanks, this is really helpful!
Comment by Michael — June, 14 2007 #
Really good to know, thanks!
Great site by the way.
Comment by WoW Hacks — January, 31 2008 #
Thanks for the tips, this really handy! Definitely something I’m going to have to utilize.
Comment by Action Games — June, 13 2009 #
sometimes the best ideas are simple like this one–will definitely implement this…right now…also nice to learn about the
import flash.debugger.enterDebugger;
enterDebugger();
trick
Comment by Vernon Morris — June, 15 2010 #