In addition, the new debugger works with the HTML-enabled TADS interpreter, so you can debug games that take advantage of the new HTML features. Of course, you can also use the new debugger with traditional TADS games; the new debugger (like HTML TADS itself) is fully compatible with TADS games that don't use HTML.
This overview is intended primarily for people who already know how to use the TADS Debugger on another platform. The information presented here is meant to help you figure out how to perform an operation with the new debugger that you already know how to perform in another version.
Before using the new Windows debugger, you may find it helpful to become familiar with the general features of the TADS Debugger, as described in the TADS Author's Manual. The core functionality of the new debugger is the same as that of the debugger on other platforms, and the concepts are all the same.
In addition, the DOS version switched the entire display back and forth between the debugger and the game screen. When the game was active, the game completely took over the display screen; when the debugger was active, the game screen was entirely replaced with the debugger screen. The debugger also had a command that let you manually switch to the game screen while the debugger was active.
The new Windows version of the debugger uses windows (naturally) for the different display areas. These windows come and go as needed, and you can move and resize them to lay out the screen as you like. The game window and the debugger windows can share the screen, so the screen switching that the DOS version did is unnecessary in the Windows version.
The debugger uses the following types of windows:
The Windows version, in contrast, has no command line. Instead, you enter commands using the control window's menu or toolbar, or using function keys, or using context menus.
Here's a brief listing of the Windows version's equivalents of the commands from the DOS version.
Ctrl-Home (show next line to be executed). Use the "Show Next Line" item on the "Debug" menu. The debugger will bring the appropriate window to the front and show the correct source line, with a little arrow in the left margin pointing to the line. You can also double-click on the current line (which is always the first line) in the stack window.
You can also go to a line in an enclosing stack frame by double-clicking on the line in the stack window. This will show the source line with a triangular green arrow (to indicate that it's the current line in an enclosing frame, not in the active frame), and will also activate the enclosing frame's context, which means that you can evaluate expressions using the frame's local variables, and that the debugger will display the frame's local variables in the "Locals" window.
g (Go).. Use the "Go" item on the "Debug" menu in the control window, or use the F5 key, or use the "Go" button in the control window toolbar.
t (Trace). Use the "Debug/Step into" menu item, or use the F11 key, or use the "Step into" button in the control window toolbar.
p (Procedure trace, or step over). Use the "Debug/Step over" menu item, or use the F10 key, or use the "Step over" button in the control window toolbar.
e (Evaluate) To evaluate an expression, select the "Evaluate" item on the "Debug" menu, or press Ctrl+E. The debugger will open a dialog that lets you type in an expression to evaluate. Type the expression and hit return, and the debugger will show you its value in the right column of the list box in the dialog. To type in a new expression, click on the expression in the left half of the list box; this opens the expression for editing. Type in a new expression and hit return, and the debugger will update the value displayed with the value of your new expression. Press the "Close" button when you're done with the dialog.
To make expression evaluation faster, the debugger automatically types in an expression for you according to the selected text in the active source window before opening the dialog. Activate a source window, use the mouse to place the caret on the name of a variable you want to evaluate, and press Ctrl+E (or use the menu) to open the dialog. Or, use the mouse to select a range of text containing an expression you want to evaluate, then open the dialog. The dialog will start off showing the expression you selected in the source window.
If the expression evaluates to an aggregate value, such as an object or a list, a small box with a plus sign will appear to the left of the expression. Click this to expand the object or list. When expanded, the list will show each property of the object or each item in the list.
If an expression can be assigned into (for example, if the expression is a local variable or a property of an object), you can edit the value of the expression. Click on the right half of the window, where the value is showing; the debugger will open the value for editing. Type in the new value that you want to set and press return; the debugger will immediately set the new value. This works both in the main expression and in the contents of an aggregate value.
The debugger also has something called "tooltip evaluation." This works like the little tooltip messages that appear in many Windows applications when you let the mouse hover over controls such as toolbar buttons. With tooltip evaluation, the debugger automatically displays the value of a variable when you let the mouse cursor hover for a few moments over the variable name in the active source window. In addition, you can use the mouse to select a range of text containing an expression; letting the mouse hover over the selected text will show pop up the value of the entire expression.
Note that tooltip evaluation will never evaluate an expression involving an assignment or a method or function call; this is because it would be too dangerous to have the debugger changing your game state just because you were moving the mouse over a source window. Tooltip evaluation is also limited by the fact that you can only use it to look at expressions that are already in your source files. It's not a substitute for the other evaluation mechanisms, but tooltip evaluation is often a convenient way to get a quick look at a variable or two in the current function.
ws, wd (set/delete watch expression). Watch expressions work much as they did in the DOS version, but it's simpler to add, change, and remove expressions. Rather than using commands, you can edit the expressions directly in the watch window itself.
To add an expression, go to the "Watch Expressions" window, and click on the blank line at the bottom of the list. This will highlight the line. Now click again in the left column; this will activate the column so that you can enter an expression. Hit return when you're done typing in the expression, and the debugger will immediately show you the value in the right column.
To remove an expression, click on the line containing the expression to highlight it, then press the Delete or Backspace key. The expression will disappear from the list.
To modify an expression, click on the line containing the expression, then click on the left column to activate the expression for editing. You can now change the expression or type in an entirely new expression.
Note that the watch window has the same features as the expression evaluation dialog, so you can open aggregate values to see their contents, and you can directly edit the values of the expressions.
In addition to the watch window, the debugger provides a "Locals" window, which shows the set of local variables for the current function or method. This window works very much like the watch window, except that the debugger automatically determines the current set of local variables, so you don't have to add them manually as expressions.
c (Call history). You can turn call history tracing on and off using the "Collect Call Trace" item in the "Debug" menu. When the debugger is collecting call history information, it will show this menu item as checked; selecting the menu item will switch it from off to on or from on to off. You can clear the contents of the call history log by selecting the "Clear Trace Log" item in the "Debug" menu.
Use the "Call Trace History" item in the "View" menu to open the history window. This window shows the current call history log; the debugger updates this window automatically as you step through your code.
bp, bc (Set/clear breakpoint). Open the source window containing the code where want to set the breakpoint, click on the line where you want the breakpoint set, and then use the "Set/clear breakpoint" item from the window's context menu (which you can access by clicking the right mouse button). Alternatively, you can click on the line where want the breakpoint and press the F9 key.
To set a global breakpoint (a breakpoint that's not associated with a line of code, but instead stops execution when a condition becomes true), select the "Edit breakpoints" item from the "Debug" menu. This will show the breakpoints dialog, which lists all of the breakpoints you currently have set. Click on the "New global" button, and type in the global expression condition that you want to use for your global breakpoint.
be, bd (Enable/disable breakpoint). Click on the line containing the breakpoint to enable or disable, and use the "Enable/disable breakpoint" item from the window's context menu.
You can also enable and disable breakpoints from within the breakpoints dialog. Select "Edit breakpoints" from the "Debug" menu; this will open a dialog that shows the list of breakpoints currently set. Select a breakpoint in the list, and click the "Enable" or "Disable" button (note that this is a single button -- it changes its function depending on whether the selected breakpoint is already enabled or disabled, so that you can reverse that status).
bl (List breakpoints). For the most part, you can see breakpoints directly (each one is marked by a red dot, or a white dots when it's disabled, in the left margin of the source window showing the file with the breakpoint). However, global breakpoints (breakpoints that are set only on expressions) obviously don't show up this way, and it's sometimes handy to be able to see all code breakpoints in one place, so the new debugger still lets you get a list of breakpoints.
To see all current breakpoints, select the "Edit Breakpoints" item from the "Debug" menu. This will display a dialog that lists all of the breakpoints.
Code breakpoints are shown with the file that contains the breakpoint and the character offset within the file of the line with the breakpoint. (Note that the offset is given in terms of characters, not line numbers.) Global breakpoints are shown simply as conditional expressions.
fl (List source files). The new debugger doesn't have an explicit command to list source files. Instead, you can simply bring up the File menu, and select the "Open Source File" item; this item will show a submenu that lists all of the source files in your game. To open one of these files, simply select the file from the submenu.
fv (View file). To open one of the source files in your game, bring up the File menu, select the "Open Source File" item, and select the file you want to open from the submenu. To open any other text file, select "Open..." from the File menu, and select the file you want to open using the normal Windows file dialog.
quit (Terminate debugging session). Select the "File/Quit" item from the control window's menu, or simply close the control window. The debugger will prompt for confirmation, since this will terminate the game and the debugger session.
k (Show call stack). The call stack is always displayed in the stack window, and the display is updated automatically as you step through your code, so the Windows debugger doesn't need a command to show the current stack. However, the "View/Stack" item on the control window's menu lets you re-open the stack window if you closed it, or simply bring the stack window to the foreground if you've lost it behind other windows.
\ (Show game screen). Since the game window and the debugger windows share the screen, there's no screen switching as there was in the DOS version. However, the "View/Game window" item on the control window's menu lets you bring the game window to the foreground if you've lost it behind other windows.
h (Toggle hidden output). Use the "Show hidden output" item on the "Debug" menu to control hidden output. When this menu item is checked, TADS will show hidden output in the game window, with special marker lines that indicate that the output was meant to be hidden. When this item is not checked, TADS keeps hidden output invisible, as it would during normal play.
/ (Search). Select the window that you want to search, then select the "Find" item on the "Edit" menu to bring up the search dialog. Type the string you want to find and click the "Find Next" button. The debugger will find the text and highlight in the source window.
To search again for the same string, use the "Find Next" item on the "Edit" menu (or just press function key F3). This will search again for the same string, starting at the current selection point in the window.
u, d (Change stack context levels up/down). To set the expression evaluation context, go to the stack window and double-click on the line in the stack that contains the context you want to set. The debugger will automatically open the source file containing that call context, and display a green arrow pointing at the line of code at which execution will resume when execution returns to that context level. (The green arrow will also be displayed in the stack window next to the same context level.) Expressions will now be evaulated in the context of the code at the green arrow, so you can access its local variables. Note that the evaluation context always reverts to the current line when you step to a new line.
When you've selected an enclosing frame, any expressions you evaluate will be evaluated in the selected frame's context, which means that you can access its local variables. In addition, the "Locals" window will show the selected frame's local variables, and the "Watch Expressions" window will evaluate its expressions in the selected frame's context.
Break into Debugger. This command (on the "Debug" menu), which is only active when the game is running, lets you switch back to the debugger without trying to coerce the game into reaching a breakpoint or a call to debugTrace(). This can be especially useful if you haven't coded a debugTrace() call in your game.
Run to Cursor. Position the cursor on a line of source code, then select this command (which you can access through the "Debug" menu, the right mouse button context menu in the source window, or by pressing function key F4). Execution will resume until it reaches the line of code that you selected (or until it reaches a breakpoint). This command is equivalent to setting a breakpoint on the selected line, resuming execution with the "Go" command, then clearing the breakpoint, but is obviously more convenient.
Set Next Statement. This command is accessed through the "Debug" menu, or through the context menu on the right mouse button in a source window. You can use this command to move the execution point, if you want to intervene in the sequence of execution of your code. This can be useful when you want to experiment with a slight change in the execution path, or when you want to avoid executing a line of code that will cause a run-time error. Move the caret to the line where you want execution to resume, then select the "Set Next Statement" command; the execution point will move to the new line you selected. Note that you can never move execution outside of the bounds of the function or method containing the current execution point.
Restart Game. This command (on the "File" menu) allows you to start the game over from the beginning from within the debugger. This command is provided mostly for convenience, since it's roughly the same as entering a "restart" command on the game's command line, but it does differ from the normal "restart" command within the game in that it completely clears the output window, including any prior pages that may have been displayed.
Abort Current Command. This command (on the "Debug" menu) has the same effect as executing the TADS abort statement in your game: it immediately terminates the current player command and starts the next turn in the game. This command can be useful when you're stepping through some code and decide that you don't want to let the code for the current command go any further (due to a bug in the code, for example). When you execute this command, the debugger will take control again at the first source line that's processed for the new turn, which usually means that the debugger will stop in the status line code (since the game will display its status line as part of setting up for the next turn).
With the DOS version, when a run-time error occurred in the course of executing your game, TADS stopped your game and activated the debugger at the source line containing the error. You could inspect variables, the call stack, and other conditions related to the error. When you resumed execution (with "go" or one of the "step" commands), the debugger aborted the current command and started a new turn.
The new Windows debugger behaves mostly the same way, but has one substantial difference: the new debugger does not abort the current command. Instead, it resumes execution at the start of the source line containing the error. This gives you a lot more flexibility in debugging code that encounters a run-time error: you can correct any variable values that led to the error, and try executing the line again with the new values; or, you can move the instruction pointer to a new line (for example, skipping the line with the error), and resume execution from that point; or, you can abort the command entirely using the "Abort Current Command" debugger command (which is what the old debugger would have done).
The purpose of this new behavior is to give you more flexibility while debugging; this new flexibility is made possible by the new commands available in this version. The old debugger didn't let you move the execution pointer, so if it resumed execution at the start of a source line containing an error, you could find yourself stuck in an infinite loop without any way of moving past the error. Since the new debugger lets you move the execution pointer, as well as explicitly aborting a player command, there's no danger that the game will get stuck re-executing an erroneous line of code: you can simply move past the line by moving the execution pointer, or you can abort the command entirely.
In the new Windows version, in contrast, the debugger takes control again when the game quits. You can set breakpoints, browse source code, and do a few of the other things you can do while the game is running, although you naturally can't inspect variables or other run-time state. You can, however, restart the game simply by using the "Go" or one of the "Step" commands; using any of these commands to resume execution will restart the game from the beginning.
Whenever you start a debugging session, the debugger looks for a .TDC file corresponding to the .GAM file you're debugging. If there isn't a .TDC file present, it's no problem; the debugger will simply use a default screen layout. If the .TDC file is present, though, the debugger will restore your session.
If for some reason you want to reset the debugger to default settings for your game, you can simply delete the .TDC file for your game before starting the debugger.
The debugger uses a separate .TDC file for each game file. This way, the debugger will remember a customized configuration for each game you debug, if you're working on several games at once.