Error Code Tutorial - Debugging Techniques
Tutorials and Guides Table of Contents
Error Code Index
The problem with the errors in the interpreter is that it generally doesn't give you an indication of where the error occurred. Since the logic script language is compiled, it can't contain information on line numbers. The best way, after you've encountered an error, is to systematically go through your code to find where the error occurs. There are many techniques for this, and the interpreter supplies a few of them internally.
The obvious starting point is to look around code that's for the room you're in before the game crashes. Try and identify conditions that triggers the error. These would include: touching a line, sound finished, changing rooms, etc, etc. Once you know this, it will help you identify where to use the debugging tools.
Tracing
Tracing lets you step through each command individually. |
Tracing is a very useful tool available to AGI developers. It is available in the original Sierra interpreters, NAGI and Sarien (through the console). Tracing allows you to step through each command that the interpreter parses whilst going through the logic code. It lets you skip past logic code and you can call it in any part of the game through pressing the "scroll-lock" key.
Initializing Trace: In the interpreter's "natural state", it doesn't have tracing on by default. You have to perform a few functions first to initialize it. Most game have debug code to do this. The standard way is to press "alt-d", usually this will set the trace flag for you. The commands vary from game to game though. If you're adding it to your own game, the commands are:
set.flag(10);
trace.info(logic number, pos, height);
Flag 10 is the trace flag, it has to be set to enable tracing. "trace.info" does the initializing of the trace data. The logic number points to a special logic that has all the names of the commands as messages. The "pos" is the line number of the top of the trace window whilst "height" is the height of the trace window.
Calling Trace: There are two ways to open the trace window after you have initialized it with code or by the alt-d/"trace on" commands.
- Press "scroll-lock". This should open the trace window
- Call the logic function "trace.on". This will open a trace window.
Depending on what you want to do, either way is appropriate to call trace. If you want to trace a logic from a certain time (i.e., just before you change rooms), it would be better to use trace.on. A word of warning however, "trace.on" expects the trace code to be initialized before you call it. Due to a bug, it could corrupt the state of the interpreter if you call it before anything has been initialized.
Trace Commands: There are three basic commands whilst in the trace window.
- Any key - Call function and skip to the next one.
- '+' - Continue parsing logic until you get to the next one. Handy for skipping over logics.
- 'scroll-lock' - Return to game.
Be careful while tracing because, before logic.0 is called again, the interpreter will update the graphics and it may overlap over the trace window. Tracing will still continue however.
Closing Trace Window: After you are finished with trace, you can close the window off by pressing "scroll-lock".
Show Memory Info
"show.mem" will help you tune the memory usage of your game. |
If you continue receiving "out of memory" or "script full", then you may want to investigate the problem with the command "show.mem". It gives you a few statistics on the memory usage. The info is as follows:
- heapsize - amount of memory allocated for the interpreter. The "heap".
- now - amount of memory used by the interpreter at the moment "show.mem" was called.
- max - maximum amount of memory that was ever used at a time.
- rm.0, etc. - amount of memory set aside for logic.0, menus, object, words.tok, script, things like that.
- max script - maximum size the script ever reached.
The "max script" statistic is useful. You can set the script size to the maximum amount possible, play through the entire game, and the set the script to the highest value used. It will save on memory for other things.
Object Status
Object Status lets you quickly see what your animated object is up to. |
The "obj.status.v" command is handy if you want to know the properties of a certain animated object. It's probably handy to also have a display of the ego's on the screen as well.
Logging
Logging is great if you want feedback from the users of your game. You can use it to log anything. Most of the developers from Sierra used it to log words that users typed in but the interpreter didn't understand. It was this was that they managed to beef up their dictionaries. You could use it to log whole phrases, places in the screen that the user visits, the score at certain points in the game (to see if they're missing anything)... etc etc. For beta versions of your game, this would be great to incorporate if you want more feedback. You could even have a flag that's set to remind the users when they quit, if they logged anything, to email it back to you.
The syntax for the log function is simple:
log(<message>);
The format of the log is this:
Code:<syntaxhighlight lang="agi">
"
Room <room number> Input line: <last input line> <your message here>" </syntaxhighlight>
Note the two extra lines at the start of each entry. The message that you specify is wrapped so it will fit in an 80 character wide text file.
Print/Display
Having a constant display of the ego's position was common in Sierra's debug mode. |
Another handy tactic is to constantly display statistics on the screen. You may have seen some debug modes in Sierra games that displayed the x, y coordinates of the ego. You don't have to stop there. You could print on the screen the state of some flags or variables that you're debugging, or the time left between events. I've used it to accurately time the difference between events in the V intro and also to find out when a flag was being reset in another game.
The best way to display something is to use this code:
display(24, 0, "my variable = %v50 ");
It's suggested you use a few spaces after the string, because if the value of the variable changes from one digit to two, you won't get hanging characters.
Special Debug Code
In Kings Quest 3, they have an entire debug logic section dedicated to the wizard because he is such a complicated beast. You can track where he is, what he's doing, what he's waiting for you to do and how long he's going to be. You could do the same thing for you game if you wanted to debug some complicated code. Write code that would be run side by side, to give the state of the code that you're trying to debug.
Another technique is just to add to the generic debug logic code that all games have. This includes all those "show var" and "tp" commands that most AGI debug modes have. You could develop more debug commands off that.
Vary the Interpreter
A different strategy to try is to run the game under different versions of the interpreter or one of the fan made interpreters. The reason for this is because of the different ways they can handle the data. NAGI has a few workarounds for bugs and so would Sarien and AGIL. One bug that crashes the Sierra interpreter might not crash NAGI or Sarien. The idea is to see the effects of what the bug does so, if game still runs with the ego running around as a spaceship, you might want to look at any code that changes the ego's view resource.
Tutorials and Guides Table of Contents
Error Code Index
< Previous: Unacknowledged ErrorsNext: >