This website uses cookies to improve user experience. By using our website you consent to all cookies in accordance with our Cookie Policy. X

Debugging in local enviroment [basic]

In previous post I've described some very basic debugging methods for already released products - while we are on topic of debugging, lets have a look at some popular and easy methods for fixing errors in local environment. Of course everything comes down to what we want to do with our application, but there will be always room for those universal tricks:

1. Execution speed time.
Skipping past the fact you should build your application also considering slower computers, speed measuring is a great way to test algorithms, especially if we know how much time they need beforehand. For more prominent results it's usually a good idea to add a loop:

public static function measureProcessTime(fun:Function, repeat:int = 10):Number {
	var time:Number = getTimer();
	for(var i:int = 0; i < repeat; i++) {
		fun();
	}
	return getTimer() - time;
}
Note that local functions are especially useful here as Flash allows their creation pretty much everywhere, allowing us to test any part of the code by simply enclosing it in the following way:
var someVar:Number = 0;
someVar = 1;
function debug() {
	var otherVar:Number = 10;
	someVar += otherVar;
}
trace(measureProcessTime(debug));
}

2. Loop traversing.
This is another neat neat way to test algorithms. Basically the idea here is to display one single point in a loop, but with ability to move that point around. Example implementation:

private static var DEBUG_COUNT:int = 0;
private static var DEBUG_STEP:int = 0;
public static function nextStep():void {
	DEBUG_STEP++;
}
public static function prevStep():void {
	DEBUG_STEP--;
	if(DEBUG_STEP<0) DEBUG_STEP=0;
}
public static function resetDebug():void {
	DEBUG_COUNT = 0;
}
public static function countDebug():Boolean {
	DEBUG_COUNT++;
	return  DEBUG_COUNT == DEBUG_STEP;
}
Functions nextStep and prevStep are meant to be connect to the arrow keys, allowing us to traverse the loop. The resetDebug function should be called before the loop we want to test. Finally the countDebug function which will return true when our loop reaches the selected step. Although it doesn't seem like much, loop traversing can be incomparable debugging tool. Good example of this is a line drawing algorithm:
(Use the up and down arrow keys to move around the loop)

3. Graphics overlay.
I think no one will disagree it's easier to see data in graphic representation rather than list of variables, which is why every application should always have some kind of way to draw (using Graphics class) information above every other object. This can be easily done by holding the main application in a "container" MovieClip, while having a single Sprite one step above it, which will be empty but accessible from anywhere in the application:
public static debug:Sprite;
public function DocumentClass() {
	var main:MyApplication = new MyApplication();
	addChild(main);

	var debug:Sprite = new Sprite();
	addChild(debug);
}
Now we just need to write DocumentClass.debug.graphics to start drawing over everything else. Personally I like to use it as a way to check hit-boxes of objects on the screen:

Debugging on user side [basic]

Debugging is a popular term used to describe a process of removing errors (or any kind of unwanted behavior) from a source code. Developing in Flash Professional or FlashDevelop we already have an access to pretty good debugging tool, which no doubt helped all of us fix at least few problems. Unfortunately debugger can only used by the developers themselves and they can not always foreseeing every possible scenario users might find themselves in. Which is why it is always a good idea to implement a mechanism for catching any errors from the user side - lets have a look at the most popular ones.

1. Main Loop.
This, what might seem to be a trivial thing, should be a part of every self-respected applications and not only because it makes debugging a much easier process, but also helps avoid memory leaks and makes whole code easier to read. But what exactly is a "main loop"? In Flash it basically comes down to having only ONE "ENTER_FRAME" event in whole application, which means every other function will executed directly (or indirectly) from the main loop. Such approach will make catching errors a trivial task, as it only requires a simple try and catch around loop's code, ensuring we always stay in control. Here is an example of a main loop:

public function render(e:Event):void {
	try {
		processPlayer();
		processEnemy();
		processMap();
	} catch(e:Error) {
		trace("Error!");
	}
}

2. Log.
Even though catching errors is very important, they might useless without information about circumstances that surround them, which is why a log that details all key functions used by the user is second most important element in every application. Writing down user status (Flash version, user's operating system etc.), button they press or windows they opened, or in case of games, what map they are on, what is their progress and events they already completed will help us recreate the scenario in which user encountered the problem.
Log class is always the easiest one to implement:

public class Log {
	private static var log:String = "";
	public function Log() {}
	public static function add(s:String):void {
		log += s+"n";
	}
	public static function toClipboard():void {
		System.setClipboard(log);
	}
}

3. Console.
Most likely there is no PC gamer didn't ever use a console, even if it only was to enable the "god mode". By console I mean a (usually hidden) applications commend line, which allows every user to fire a predefined functions at any given moment. Implementation of a good console requires a good deal of work, but luckily there is already a nice selection of ready solutions on the Internet, like for example: Flash Console. Everyone should try out creating a console for their application - one time is enough to fall in love for them.

Finally, when our application is ready, it is a good idea to replace the trace function in the main loop with something that will help us receive any possible error's information, by for example sending an e-mail.