~ubuntu-branches/ubuntu/vivid/inform/vivid

« back to all changes in this revision

Viewing changes to html/section21.html

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2008-05-26 22:09:44 UTC
  • mfrom: (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526220944-ba7phz0d1k4vo7wx
Tags: 6.31.1+dfsg-1
* Remove a considerable number of files from the package
  due to unacceptable licensing terms.
* Repair library symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<HTML><HEAD><TITLE>Section 21: Extending and redefining the Library</TITLE></HEAD>
2
 
<BODY BGCOLOR="#FFFFFF">
3
 
<TABLE></SMALL>
4
 
<TR><TD><TD><P>
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>
6
 
<P>
7
 
 
8
 
<BLOCKQUOTE>
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>
12
 
<P>
13
 
 
14
 
 
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.
20
 
<P>
21
 
 
22
 
To do this, a game should make a class definition for amulets:
23
 
called <TT>Amulet</TT>, say.  Then
24
 
<PRE>
25
 
    if (noun ofclass Amulet) ...
26
 
</PRE>
27
 
 
28
 
will test to see if <TT>noun</TT> is one of the amulets, for instance.
29
 
<P>
30
 
 
31
 
The amulet's spell will be represented by the property <TT>amulet_spell</TT>.
32
 
Typical values for this might be:
33
 
<PRE>
34
 
    amulet_spell "The spell fizzles out with a dull phut! sound.",
35
 
    amulet_spell
36
 
    [;  if (location == thedark)
37
 
        {   give real_location light;
38
 
            "There is a burst of magical light!";
39
 
        }
40
 
    ],
41
 
    amulet_spell HiddenVault,
42
 
    amulet_spell
43
 
    [;  return random(LeadRoom, SilverRoom, GoldRoom);
44
 
    ],
45
 
</PRE>
46
 
 
47
 
Then the process of casting the spell for amulet <TT>X</TT> is a matter of
48
 
sending the message
49
 
<PRE>
50
 
    X.amulet_spell();
51
 
</PRE>
52
 
 
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:
56
 
<PRE>
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();
62
 
          switch(destination)
63
 
          {   false:   "Nothing happens.";
64
 
              true:    ;
65
 
              default: print "You are magically teleported to...^";
66
 
                       PlayerTo(destination);
67
 
          }
68
 
      }
69
 
      else "You only know how to cast spells with amulets.";
70
 
    ];
71
 
</PRE>
72
 
<P>
73
 
 
74
 
<P>
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
78
 
files.
79
 
<P>
80
 
 
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
83
 
(see below).
84
 
</SMALL>
85
 
<TR><TD><TD><P>
86
 
 
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.''
96
 
</SMALL>
97
 
<TR><TD><TD><P>
98
 
 
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
101
 
in the game:
102
 
<PRE>
103
 
ChangeDefault(cant_go, "You're a Master Adventurer now, and still
104
 
                        you walk into walls!");
105
 
</PRE>
106
 
 
107
 
Of course this cannot change defaults for properties of your own
108
 
invention, because they haven't got default values.
109
 
</SMALL>
110
 
<TR><TD><TD><P>
111
 
 
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:
117
 
<PRE>
118
 
    Property door_to;
119
 
    Property capacity 100;
120
 
    Property cant_go "You can't go that way.";
121
 
</PRE>
122
 
 
123
 
In the latter cases we are giving default values: in the former case,
124
 
the default value will just be 0.
125
 
</SMALL>
126
 
<TR><TD><TD><P>
127
 
 
128
 
<P>
129
 
 
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.
135
 
<P>
136
 
 
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
141
 
example:
142
 
<PRE>
143
 
Object LibraryMessages
144
 
  with before
145
 
       [;  Jump: "You jump and float uselessly for a while in
146
 
                  the zero gravity here on Space Station Alpha.";
147
 
           SwitchOn:
148
 
                 if (lm_n==3)
149
 
                 {   print "You power up ", (the) lm_o, "."; }
150
 
       ];
151
 
</PRE>
152
 
 
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.
157
 
<P>
158
 
 
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.
165
 
<P>
166
 
 
167
 
An especially useful library message to change is the prompt, normally
168
 
set to <TT>"^&#62;"</TT> (new-line followed by <TT>&#62;</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.
172
 
<P>
173
 
 
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
177
 
choice.
178
 
</SMALL>
179
 
<TR><TD><TD><P>
180
 
 
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.
183
 
Implement this.
184
 
 
185
 
<P>
186
 
 
187
 
 
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
189
 
<PRE>
190
 
Object LibraryMessages
191
 
  with before
192
 
       [;  print "[", sw__var, ", ", lm_n, "] ";
193
 
       ];
194
 
</PRE>
195
 
 
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.
200
 
</SMALL>
201
 
<TR><TD><TD><P>
202
 
 
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.
210
 
</SMALL>
211
 
<TR><TD><TD><P>
212
 
 
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
215
 
spoken in Provence).
216
 
 
217
 
<P>
218
 
 
219
 
<P>
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
225
 
<PRE>
226
 
Replace BurnSub;
227
 
</PRE>
228
 
 
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.
234
 
<P>
235
 
 
236
 
The most popular routine to replace is <TT>DrawStatusLine</TT>: see <A HREF="section33.html">Section 33</A> for
237
 
several examples.
238
 
<P>
239
 
 
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.
247
 
</SMALL>
248
 
<TR><TD><TD><P>
249
 
 
250
 
</SMALL><TR><TD><TD>
251
 
<P>
252
 
 
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.
257
 
<BR>
258
 
There are several formal library extension files in existence,
259
 
mostly small: see the Inform home page on the WWW.
260
 
<BR> "pluralobj.h''
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''.
265
 
</TABLE>
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 &#169; Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.</I></SMALL></BODY></HTML>