1
<HTML><HEAD><TITLE>Section 30: Debugging verbs and tracing</TITLE></HEAD>
2
<BODY BGCOLOR="#FFFFFF">
4
<TR><TD Valign="top"><A HREF="contents.html">Contents</A><BR><A HREF="chapter6.html">Back</A><BR><A HREF="section31.html">Forward</A><TD bgcolor="#F5DEB3"><BLOCKQUOTE><H3>30. Debugging verbs and tracing</H3></BLOCKQUOTE><TR><TD><TD>
8
If builders built buildings the way programmers write programs,
9
the first woodpecker that came along would destroy civilisation.
10
<P>...old computing adage</BLOCKQUOTE>
14
Infocom claimed to have fixed nearly 2000 bugs in the course of writing
15
'Sorcerer', which is a relatively simple game today. Adventure games are
16
exhausting programs to test and debug because of the huge number of states
17
they can get into, many of which did not occur to the author. (For
18
instance, if the player solves the "last'' puzzle first, do the other
19
puzzles still work properly? Are they still fair?) The main source of
20
error is simply the designer not noticing that some states are possible. The
21
Inform library can't help with this, but it does contain features to help
22
the tester to quickly reproduce states (by moving objects around freely, for
23
instance) and to see what the current state actually is (by displaying the
24
tree of objects, for instance).
27
Inform provides a small suite of debugging verbs,
28
which will be added to any game compiled with the <TT>-D</TT> switch.
29
If you prefer, you can include them manually by writing
34
somewhere in the program before the library files are included.
35
(Just in case you forget having done this, the letter <TT>D</TT> appears
36
in the game banner to stop you releasing such a version by accident.)
39
You then get the following verbs, which can be used at any time in play:
41
showobj <anything>
42
purloin <anything>
43
abstract <anything> to <anything>
44
tree tree <anything>
45
scope scope <anything>
46
showverb <verb>
47
goto <number> gonear <anything>
48
actions actions on actions off
49
routines routines on routines off
50
messages messages on messages off
51
timers timers on timers off
52
trace trace on trace off trace <1 to 5>
53
recording recording on recording off
58
"showobj'' is very informative about the current state of an object.
59
You can "purloin" any item or items in your game at any time, wherever
60
you are. This clears <TT>concealed</TT> for anything it takes, if necessary.
61
You can likewise "abstract" any item to any other item (meaning:
62
move it to the other item). To get a listing of the objects in the game
63
and how they contain each other, use "tree", and to see the possessions of
64
one of them alone, use "tree <I><B><that></B></I>". The command "scope'' prints a
65
list of all the objects currently in scope, and can optionally be given
66
the name of someone else you want a list of the scope for (e.g., "scope
67
pirate''). "showverb'' will display the grammar being used when the
68
given verb is parsed. Finally, you can go anywhere, but since rooms don't
69
have names understood by the parser, you have to give either the object number,
70
which you can find out from the "tree'' listing, or the name of some object in
71
the room you want to go to (this is what "gonear'' does).
78
Turning on "actions" gives a trace of all the actions which take place in
79
the game (the parser's, the library's or yours); turning on "routines"
80
traces every object routine (such as <TT>before</TT> or <TT>life</TT>) that is ever
81
called, except for <TT>short_name</TT> (as this would look chaotic, especially on
82
the status line). It also describes all messages sent in the game, which is
83
why it can also be written as "messages''.
84
Turning on "timers'' shows the state of all active timers
85
and daemons each turn.
89
The commands you type can be transcribed to a file with the
90
"recording'' verb, and run back through with the "replay'' verb.
91
(This may not work under some implementations of the ITF interpreter.)
92
If you're going to use such recordings, you will need to fix the random
93
number generator, and the "random'' verb should render this
94
deterministic: i.e., after any two uses of "random'', the same stream
95
of random numbers results. Random number generation is poor on some
96
machines: you may want to <TT>Replace</TT> the random-number generator in
101
A source-level debugger for Inform, called Infix, has been planned
102
for some years, and may possibly be coming to fruition soon.
105
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> For the benefit of such tools, Inform (if compiling with the
106
<TT>-k</TT> option set) produces a file of "debugging information''
107
(cross-references of the game file with the source code),
108
and anyone interested in writing an Inform utility program may want
109
to know the format of this file: see the <I> Technical Manual</I> for
115
On most interpreters, though, run-time crashes can be mysterious, since
116
the interpreters were written on the assumption that they would only ever
117
play Infocom game files (which are largely error-free). A Standard
118
interpreter is better here and will usually tell you why and where the
119
problem is; given a game file address you can work back to the problem
120
point in the source either with Mark Howell's txd (disassembler)
121
or by running Inform with the assembler trace option on.
124
Here are all the ways I know to crash an interpreter at run-time (with
125
high-level Inform code, that is; if you insist on using
126
assembly language or the <TT>indirect</TT> function you're raising the stakes),
127
arranged in decreasing order of likelihood:
130
<P> -- Writing to a property which an object hasn't got;
131
<P> -- Dividing by zero, possibly by calling <TT>random(0)</TT>;
132
<P> -- Giving a string or numerical value for a property which can
133
only legally hold a routine, such as <TT>before</TT>, <TT>after</TT> or <TT>life</TT>;
134
<P> -- Applying <TT>parent</TT>, <TT>child</TT> or <TT>children</TT> to the <TT>nothing</TT>
136
<P> -- Using <TT>print object</TT> on the <TT>nothing</TT> object, or for some
137
object which doesn't exist (use <TT>print (name)</TT>, <TT>print (the)</TT> etc., instead
138
as these are safeguarded);
139
<P> -- Using <TT>print (string)</TT> or <TT>print (address)</TT> to
140
print from an address outside the memory map of the game file, or an address
141
at which no string is present (this will result in random text appearing,
142
possibly including unprintable characters, which might crash the
144
<P> -- Running out of stack space in a recursive loop.
148
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL>
149
There are times when it's hard to work out what the parser is up to and why
150
(actually, most times are like this). The parser is written in levels, the
151
lower levels of which are murky indeed. Most of the interesting things
152
happen in the middle levels, and these are the ones for which tracing is
153
available. The levels which can be traced are:
155
<BR><TABLE Border><TR><TD> Level 1 <TD> Grammar lines
156
<TR><TD> Level 2 <TD> Individual tokens
157
<TR><TD> Level 3 <TD> Object list parsing
158
<TR><TD> Level 4 <TD> Resolving ambiguities and making choices of object(s)
159
<TR><TD> Level 5 <TD> Comparing text against an individual object
161
"trace" or "trace on" give only level 1 tracing. Be warned: "trace five"
162
can produce reams of text when you try anything at all complicated: but you
163
do sometimes want to see it, to get a list of exactly everything that is in
164
scope and when. There are two levels lower than that but they're too busy
165
doing dull spade-work to waste time on looking at <TT>parser_trace</TT>. There's
166
also a level 0, but it consists mostly of making arrangements for level 1,
167
and isn't very interesting.
171
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL>
172
Finally, though this is a drastic measure, you can always compile your game
173
<TT>-g</TT> ('debugging code') which gives a listing of every routine ever
174
called and their parameters. This produces an enormous melèe of output.
175
More usefully you can declare a routine with an asterisk <TT>*</TT> as its first
176
local variable, which produces such tracing only for that one routine.
179
[ ParseNoun * obj n m;
182
results in the game printing out lines like
184
[ParseName, obj=26, n=0, m=0]
187
every time the routine is called.
191
<P><TR><TD Valign="top"><IMG SRC="icons/refs.gif" ALT="*"><TD bgcolor="#EEEEEE"><B>REFERENCES:</B><BR><SMALL> A simple debugging verb called "xdeterm'' is defined in the
192
<TT>DEBUG</TT> version of 'Advent', to make the game deterministic (i.e.,
193
not dependant on what the random number generator produces).
199
<HR><A HREF="contents.html">Contents</A> / <A HREF="chapter6.html">Back</A> / <A HREF="section31.html">Forward</A> <BR>
200
<A HREF="chapter1.html">Chapter I</A> / <A HREF="chapter2.html">Chapter II</A> / <A HREF="chapter3.html">Chapter III</A> / <A HREF="chapter4.html">Chapter IV</A> / <A HREF="chapter5.html">Chapter V</A> / <A HREF="chapter6.html">Chapter VI</A> / <A HREF="chapterA.html">Appendix</A><HR><SMALL><I>Mechanically translated to HTML from third edition as revised 16 May 1997. Copyright © Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.</I></SMALL></BODY></HTML>