1
<HTML><HEAD><TITLE>Section 21: Extending and redefining the Library</TITLE></HEAD>
2
<BODY BGCOLOR="#FFFFFF">
5
<TR><TD Valign="top"><A HREF="contents.html">Contents</A><BR><A HREF="section20.html">Back</A><BR><A HREF="chapter5.html">Forward</A><TD bgcolor="#F5DEB3"><BLOCKQUOTE><H3>21. Extending and redefining the Library</H3></BLOCKQUOTE><TR><TD><TD>
9
A circulating library in a town is as an ever-green
10
tree of diabolical knowledge! It blossoms through the year!
11
<P>...R. B. Sheridan (<B>1751</B>--<B>1816</B>), <I>The Rivals</I></BLOCKQUOTE>
15
Most large games will need to enrich the 'model world': for
16
instance, by creating a new concept such as "magic amulets''. The game
17
might contain a dozen of these, each with the power to cast a different
18
spell. So it will need routines which can tell whether or not a given
19
object is an amulet, and what to do when the spell is cast.
22
To do this, a game should make a class definition for amulets:
23
called <TT>Amulet</TT>, say. Then
25
if (noun ofclass Amulet) ...
28
will test to see if <TT>noun</TT> is one of the amulets, for instance.
31
The amulet's spell will be represented by the property <TT>amulet_spell</TT>.
32
Typical values for this might be:
34
amulet_spell "The spell fizzles out with a dull phut! sound.",
36
[; if (location == thedark)
37
{ give real_location light;
38
"There is a burst of magical light!";
41
amulet_spell HiddenVault,
43
[; return random(LeadRoom, SilverRoom, GoldRoom);
47
Then the process of casting the spell for amulet <TT>X</TT> is a matter of
53
which will reply with either: false, meaning nothing has happened;
54
true, meaning that something did happen; or an object, a room to
55
teleport the player to. Here is a routine which deals with it all:
57
[ CastSub destination;
58
if (noun ofclass Amulet)
59
{ if (~~(noun provides amulet_spell))
60
"[Ooops. Forgot to program this amulet_spell.]";
61
destination = noun.amulet_spell();
63
{ false: "Nothing happens.";
65
default: print "You are magically teleported to...^";
66
PlayerTo(destination);
69
else "You only know how to cast spells with amulets.";
75
An elaborate library extension will end up defining many classes,
76
grammar, actions and verb definitions. These may neatly be packaged
77
up into an <TT>Include</TT> file and placed with the other library
81
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> If this file contains the directive <TT>System_file;</TT> then it will
82
even be possible for games to <TT>Replace</TT> routines from it
87
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The ordinary Library's own properties, such as <TT>description</TT>
88
or <TT>e_to</TT>, are called "common properties''. They are special for the
89
following reason: if an object <TT>O</TT> does not give any value for common
90
property <TT>P</TT>, then <TT>O.P</TT> can still be looked up, though it can't be
91
set to something else. (If you tried this with a property of your
92
own invention, such as <TT>amulet_spell</TT> above, an error would be printed
93
out at run-time.) The value of <TT>O.P</TT> is just the "default value''
94
provided by the Library for property <TT>P</TT>: for example, the default
95
value of <TT>cant_go</TT> is "You can't go that way.''
99
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> But you can change this default value during play, using the
100
library's <TT>ChangeDefault</TT> routine. For instance, at a late stage
103
ChangeDefault(cant_go, "You're a Master Adventurer now, and still
104
you walk into walls!");
107
Of course this cannot change defaults for properties of your own
108
invention, because they haven't got default values.
112
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> Common properties are also slightly faster to perform
113
calculations with: the down side is that there's a strictly limited
114
supply of them (63 in all), of which the library uses up half
115
already. To indicate that a property needs to be a common property,
116
use the <TT>Property</TT> directive. For example:
119
Property capacity 100;
120
Property cant_go "You can't go that way.";
123
In the latter cases we are giving default values: in the former case,
124
the default value will just be 0.
130
Major library extensions are rarely needed.
131
More often, one would like simply to change the stock of
132
standard messages, such as the "Nothing is on sale.'' which tends
133
to be printed when the player asks to buy something, or the "Taken.''
134
printed when something is picked up.
137
This facility is available as follows. Provide a special
138
object called <TT>LibraryMessages</TT>, which must be defined <I> between</I>
139
the inclusion of the "Parser" and "VerbLib" library files.
140
This object should have just one property, a <TT>before</TT> rule. For
143
Object LibraryMessages
145
[; Jump: "You jump and float uselessly for a while in
146
the zero gravity here on Space Station Alpha.";
149
{ print "You power up ", (the) lm_o, "."; }
153
The object never physically appears in the game, of course. The idea
154
is that the <TT>before</TT> rule is consulted before any message is printed:
155
if it returns false, the standard message is printed; if true, then
156
nothing is printed, as it's assumed that this has already happened.
159
The <TT>Jump</TT> action only ever prints one message (usually "You jump on
160
the spot.''), but more elaborate actions such as <TT>SwitchOn</TT> have
161
several (the extreme case is <TT>Take</TT>, with 13). <TT>lm_n</TT> holds the
162
message number, which counts upwards from 1. The messages and
163
numbers are given in <A HREF="sectionA9.html">Appendix A9</A>. New message numbers may possibly be
164
added in future, but old ones will not be renumbered.
167
An especially useful library message to change is the prompt, normally
168
set to <TT>"^>"</TT> (new-line followed by <TT>></TT>). This is printed under the
169
action <TT>Prompt</TT> (actually a fake action existing for exactly this
170
purpose). In this way, the game's prompt can be made context-sensitive,
171
or the "skipped line on screen each turn'' convention can be removed.
174
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL>
175
This prompt is only used in ordinary game play, and not at such keyboard
176
inputs as yes/no questions or the RESTART/RESTORE/QUIT game over
181
<P><TR><TD Valign="top"><IMG SRC="icons/exercise.gif" ALT="??"><TD bgcolor="#FBB9AC"><A NAME="ex47"><B>EXERCISE 47:</B><BR>(link to <A HREF="answers1/answer47.html">the answer</A>)<TR><TD><TD> Infocom's game 'The Witness' has the prompt "What should you,
182
the detective, do next?'' on turn one and "What next?'' subsequently.
188
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> An amusing way to see the system in action is to put
190
Object LibraryMessages
192
[; print "[", sw__var, ", ", lm_n, "] ";
196
into your game (arcane note: <TT>sw__var</TT>, the "switch variable'', in
197
this case holds the action number). Another amusing effect is to
198
simply write <TT>rtrue;</TT> for the <TT>before</TT> routine, which results in an
199
alarmingly silent game -- blindfold Adventure, perhaps.
203
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL>
204
Note that <TT>LibraryMessages</TT> can be used as a sneaky way to add extra
205
rules onto the back of actions, since there's nothing to stop you
206
doing real processing in a call to it; or, more happily,
207
to make messages more sensitive to game context, so that "Nothing is
208
on sale.'' might become "That's not one of the goods on sale.''
209
inside a shopping mall.
213
<P><TR><TD Valign="top"><IMG SRC="icons/ddexercise.gif" ALT="??/\/\"><TD bgcolor="#FBB9AC"><A NAME="ex48"><B>EXERCISE 48:</B><BR>(link to <A HREF="answers1/answer48.html">the answer</A>)<TR><TD><TD>
214
Write an Inform game in Occitan (a dialect of medieval French
220
The Library is itself written in Inform, and with experience it's not
221
too hard to alter it if need be. But this is an inconvenience and an
222
inelegant way to carry on. So here is the last resort in library
223
modification: work out which routine is giving trouble, and <TT>Replace</TT>
224
it. For example, if the directive
229
is placed in your file <I> before the library files are included</I>,
230
Inform ignores the definition of <TT>BurnSub</TT> in the library files.
231
You then have to define a routine called <TT>BurnSub</TT> yourself.
232
It would be normal to copy the definition of <TT>BurnSub</TT> out of the
233
library files into your own code, and then modify that copy as needed.
236
The most popular routine to replace is <TT>DrawStatusLine</TT>: see <A HREF="section33.html">Section 33</A> for
240
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL>
241
Inform even allows you to <TT>Replace</TT> "hardware'' functions like <TT>random</TT>,
242
which would normally be translated directly to machine opcodes. Obviously,
243
replacing something like <TT>child</TT> with a software routine will impose an
244
appreciable speed penalty and slightly increase object code size. Replacing
245
<TT>random</TT> may however be useful when fixing the random number generator for
246
game-testing purposes.
253
<P><TR><TD Valign="top"><IMG SRC="icons/refs.gif" ALT="*"><TD bgcolor="#EEEEEE"><B>REFERENCES:</B><BR><SMALL>
254
'Balances' contains a section of code (easily extractable to
255
other games) implementing the 'Enchanter' trilogy's magic
256
system by methods like the above.
258
There are several formal library extension files in existence,
259
mostly small: see the Inform home page on the WWW.
261
by Andrew Clover makes large-scale use of <TT>LibraryMessages</TT>
262
to ensure that the library always uses words like "those''
263
instead of "that'' when talking about objects with names like
264
"a heap of magazines''.
266
<HR><A HREF="contents.html">Contents</A> / <A HREF="section20.html">Back</A> / <A HREF="chapter5.html">Forward</A> <BR>
267
<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>