1 ==============================
2 William Tell: a tale is born
3 ==============================
9 | |CENTER| *K was King William, once governed the land;*
10 | |CENTER| *L was a lady, who had a white hand.*
14 .. image:: /images/picK.png
17 |K|\eeping up the momentum, this chapter (and the three which follow) works
18 steadily through the design of the "William Tell" game that we encountered
19 right at the start of this guide. Many of the principles are the same as
20 the ones we explained when designing Heidi and her forest, so we'll not
21 linger on what should be familiar ground. "William Tell" is a slightly
22 longer and more complex game, so we'll move as swiftly as possible to
23 examine the features which are new.
28 Our starting point is much the same as last time. Here's a basic
32 !===========================================================================
33 Constant Story "William Tell";
35 "^A simple Inform example
36 ^by Roger Firth and Sonja Kesserich.^";
37 Release 3; Serial "040804"; ! for keeping track of public releases
39 Constant MAX_SCORE = 3;
44 !===========================================================================
47 !===========================================================================
50 !===========================================================================
51 ! The player's possessions
53 !===========================================================================
54 ! Entry point routines
58 lookmode = 2; ! like the VERBOSE command
60 move quiver to player; give quiver worn;
62 "You wear the traditional clothing of a Swiss mountaineer.";
64 The place: Altdorf, in the Swiss canton of Uri. The year is 1307,
65 at which time Switzerland is under rule by the Emperor Albert of
66 Habsburg. His local governor -- the vogt -- is the bullying
67 Hermann Gessler, who has placed his hat atop a wooden pole in
68 the centre of the town square; everybody who passes through the
69 square must bow to this hated symbol of imperial might.
71 You have come from your cottage high in the mountains,
72 accompanied by your younger son, to purchase provisions. You are
73 a proud and independent man, a hunter and guide, renowned both
74 for your skill as an archer and, perhaps unwisely (for his soldiers
75 are everywhere), for failing to hide your dislike of the vogt.
77 It's market-day: the town is packed with people from the
78 surrounding villages and settlements.^";
81 !===========================================================================
82 ! Standard and extended grammar
86 !===========================================================================
88 You'll see that we've marked a couple of extra divisions in the file, to
89 help organise the stuff we'll add later, but the overall structure is
90 identical to our first game. Let's quickly point out some extra bits and
93 * If you look at a game's banner, you'll see two pieces of information:
94 "Release" and "Serial number".
96 .. code-block:: transcript
99 A simple Inform example
100 by Roger Firth and Sonja Kesserich.
101 Release 3 / Serial number 040804 / Inform v6.30 Library 6/11 SD
103 These two fields are automatically written by the compiler, which sets by
104 default Release to 1 and the Serial Number to today's date. However, we
105 can explicitly override this behaviour using ``Release`` and ``Serial``,
106 to keep track of different versions of our game. Typically, we will
107 publish several updates of our games over time, each version fixing
108 problems which were found in the previous release. If somebody else
109 reports a problem with a game, we'd like to know exactly which version
110 they were using; so, rather than take the default values, we set our own.
111 When it's time to release a new version, all we have to do is comment out
112 the previous lines and add another below them::
114 !Release 1; Serial "020128"; ! First beta-test release
115 !Release 2; Serial "020217"; ! Second beta-test release
116 Release 3; Serial "020315"; ! IF Library competition entry
118 * We'll be implementing a simple system of awarding points when the player
119 gets something right, so we define top marks::
121 Constant MAX_SCORE = 3;
123 * The ``Initialise`` routine that we wrote last time contained only one
124 statement, to set the player's initial :var:`location`. We do that here
125 as well, but we also do some other stuff.
127 * The first thing is to assign 2 to the library variable ``lookmode``.
128 Inform's default mode for displaying room descriptions is BRIEF (a
129 description is displayed only when a room is visited for the first time)
130 and, by changing this variable's value, we set it to VERBOSE
131 (descriptions are displayed on *every* visit). Doing this is largely a
132 matter of personal preference, and in any case it's nothing more than a
133 convenience; it just saves having to remember to type VERBOSE each time
134 that we test the game.
136 * At the start of the game, we want Wilhelm to be equipped with his bow and
137 quiver of arrows. The recommended way of making this happen is to
138 perform the necessary object tree rearrangement with a couple of ``move``
139 statements in the ``Initialise`` routine::
142 move quiver to player;
144 and indeed this is the clearest way to place objects in the player's
145 inventory at the beginning of any game.
149 Wait! you say. In the previous chapter, to make an object the child
150 of another object all we needed to do was to define the child object
151 with the internal identification of the parent object at the end of
154 Object bird "baby bird" forest
156 Why not do that with the player? Because the object which represents
157 the player is defined by the library (rather than as part of our
158 game), and actually has an internal ID of :obj:`selfobj`;
159 :var:`player` is a variable whose value is that identifier. Rather
160 than worry all about this, it's easier to use the ``move`` statements.
162 There's one other task associated with the quiver; it's an article of
163 clothing which Wilhelm is "wearing", a state denoted by the attribute
164 :attr:`worn`. Normally the interpreter would apply this automatically,
165 while handling a command like WEAR QUIVER, but since we've moved the
166 quiver ourselves, we also need to set the quiver's :attr:`worn`
167 attribute. The ``give`` statement does the job::
171 (To clear the attribute, by the way, you'd use the statement ``give
172 quiver ~worn`` -- read that as "give the quiver not-worn"; Inform often
173 uses ``~`` to mean "not".)
175 .. Generated by autoindex
177 pair: description; library property
179 * If the player types EXAMINE ME, the interpreter displays the
180 :prop:`description` property of the :var:`player` object. The default
181 value is "As good-looking as ever", a bit of a cliché in the world of
182 Inform games. It's easy to change, though, once you realise that, since
183 the properties of an object are variables, you can assign new values to
184 them just as you'd assign new values to :var:`location` and ``lookmode``.
185 The only problem is getting the syntax right; you can't say just::
187 description = "You wear the traditional clothing of a Swiss mountaineer.";
189 because there are dozens of objects in the game, each with its own
190 :prop:`description` property; you need to be a little more explicit.
191 Here's what to type::
194 "You wear the traditional clothing of a Swiss mountaineer.";
196 * Finally, the ``Initialise`` routine ends with a lengthy ``print_ret``
197 statement. Since the interpreter calls ``Initialise`` right at the start
198 of the game, that's the point at which this material is displayed, so
199 that it acts as a scene-setting preamble before the game gets under way.
200 In fact, everything you want set or done at the very beginning of the
201 game, should go into the ``Initialise`` routine.
203 The game won't compile in this state, because it contains references to
204 objects which we haven't yet defined. In any case, we don't intend to
205 build up the game in layers as we did last time, but rather to talk about
206 it in logically related chunks. To see (and if you wish, to type) the
207 complete source, go to :doc:`/appendices/c`.
212 Remember how we defined the rooms in "Heidi"? Our first attempt started
215 Object "In front of a cottage"
217 "You stand outside a cottage. The forest stretches east.",
220 Object "Deep in the forest"
222 "Through the dense foliage, you glimpse a building to the west.
223 A track heads to the northeast.",
228 and we explained that just about *every* room needs that :attr:`light`
229 attribute, or else the player would be literally in the dark. It's a bit
230 of a nuisance having to specify that same attribute each time; what would
231 be neater would be to say that *all* rooms are illuminated. So we can
237 Room "In front of a cottage"
239 "You stand outside a cottage. The forest stretches east.",
242 Room "Deep in the forest"
244 "Through the dense foliage, you glimpse a building to the west.
245 A track heads to the northeast.",
250 We've done four things:
252 #. We've said that some of the objects in our game are going to be defined
253 by the specialised word ``Room`` rather than the general-purpose word
254 ``Object``. In effect, we've taught Inform a new word specially for
255 defining objects, which we can now use as though it had been part of the
258 #. We've furthermore said that every object which we define using ``Room``
259 is automatically going to have the :attr:`light` attribute.
261 #. We've changed the way in which we define the four room objects, by
262 starting them with our specialised word ``Room``. The remainder of the
263 definition for these objects -- the header information, the block of
264 properties, the block of attributes and the final semicolon -- remains
265 the same; except that:
267 #. We don't need to explicitly include the :attr:`light` attribute each
268 time; every ``Room`` object has it automatically.
270 A :term:`class` is a family of closely related objects, all of which behave
271 in the same way. Any properties defined for the class, and any attributes
272 defined for the class, are automatically given to objects which you specify
273 as belonging to that class; this process of acquisition just by being a
274 member of a class is called :term:`inheritance`. In our example, we've
275 defined a ``Room`` class with a :attr:`light` attribute, and then we've
276 specified four objects each of which is a member of that class, and each of
277 which gets given a :attr:`light` attribute as a result of that membership.
279 Why have we gone to this trouble? Three main reasons:
281 * By moving the common bits of the definitions from the individual objects
282 to the class definition which they share, those object definitions
283 become shorter and simpler. Even if we had a hundred rooms, we'd still
284 need to specify ``has light`` only once.
286 * By creating a specialised word to identify our class of objects, we make
287 our source file easier to read. Rather than absolutely everything being
288 an anonymous ``Object``, we can now immediately recognise that some are
289 ``Room`` objects (and others belong to the different classes that we'll
292 * By collecting the common definitions into one place, we make it much
293 easier to make widespread modifications in future. If we need to make
294 some change to the definition of all our rooms, we just modify the
295 ``Room`` class, and all of the class members inherit the change.
297 For these reasons, the use of classes is an incredibly powerful technique,
298 easier than it may look, and very well worth mastering. From now on, we'll
299 be defining object classes whenever it makes sense (which is generally when
300 two or more objects are meant to behave in exactly the same way).
302 You may be wondering: suppose I want to define a room which for some reason
303 *doesn't* have :attr:`light`; can I still use the ``Room`` class? Sure you
306 Room cellar "Gloomy cellar"
307 with description "Your torch shows only cobwebby brick walls.",
310 This illustrates another nice feature of inheritance: the object definition
311 can override the class definition. The class says ``has light``, but the
312 object itself says ``has ~light`` (read that as "has no light") and the
313 object wins. The cellar is dark, and the player will need a torch to see
316 In fact, for any object both the block of properties and the block of
317 attributes are optional and can be omitted if there's nothing to be
318 specified. Now that the :attr:`light` attribute is being provided
319 automatically and there aren't any other attributes to set, the word
320 ``has`` can be left out. Here's the class again::
325 and here is how we could have used it in "Heidi"::
327 Room "In front of a cottage"
329 "You stand outside a cottage. The forest stretches east.";
331 Room "Deep in the forest"
333 "Through the dense foliage, you glimpse a building to the west.
334 A track heads to the northeast.";
338 You'll notice that, if an object has no block of attributes, the semicolon
339 which terminates its definition simply moves to the end of its last
347 We use the ``Room`` class in "William Tell", and a few other classes
348 besides. Here's a ``Prop`` class (that's "Prop" in the sense of a
349 theatrical property rather than a supportive device), useful for scenic
350 items whose only role is to sit waiting in the background on the off-chance
351 that the player might think to EXAMINE them::
358 print_ret "You don't need to worry about ", (the) self, ".";
362 All objects of this class inherit the :attr:`scenery` attribute, so they're
363 excluded from room descriptions. Also, there's a :prop:`before` property;
364 one that's more complex than our previous efforts. You'll remember that
365 the first :prop:`before` we met looked like this::
369 print "It sounds scared and in need of assistance.^";
373 .. Generated by autoindex
375 pair: Examine; library action
376 pair: Listen; library action
378 The role of that original :prop:`before` was to intercept :act:`Listen`
379 actions, while leaving all others well alone. The role of the
380 :prop:`before` in the ``Prop`` class is broader: to intercept (a)
381 :act:`Examine` actions, and (b) all the rest. If the action is
382 :act:`Examine`, then the ``return false`` statement means that the action
383 carries on. If the action is ``default`` -- none of those explicitly
384 listed, which in this instance means *every* action apart from
385 :act:`Examine` -- then the ``print_ret`` statement is executed, after which
386 the interpreter does nothing further. So, a ``Prop`` object can be
387 EXAMINEd, but any other action addressed to it results in a "no need to
390 That message is also more involved than anything we've so far displayed.
391 The statement which produces it is::
393 print_ret "You don't need to worry about ", (the) self, ".";
395 which you should read as doing this:
397 #. display the string "You don't need to worry about ",
399 #. display a definite article (usually "the") followed by a space and the
400 external name of the object concerned,
402 #. display a period, and
404 #. display a newline and return true in the usual way for a ``print_ret``
407 The interesting things that this statement demonstrates are:
409 * The ``print`` and ``print_ret`` statements aren't restricted to
410 displaying a single piece of information: they can display a list of
411 items which are separated by commas. The statement still ends with a
412 semicolon in the usual way.
414 * As well as displaying strings, you can also display the names of objects:
415 given the ``nest`` object from our first game, ``(the) nest`` would
416 display "the bird's nest", ``(The) nest`` would display "The bird's
417 nest", ``(a) nest`` would display "a bird's nest", ``(A) nest`` would
418 display "A bird's nest" and ``(name) nest`` would display just "bird's
419 nest". This use of a word in parentheses, telling the interpreter how to
420 display the following object's internal ID, is called a :term:`print
423 .. Generated by autoindex
425 pair: self; library variable
427 * There's a library variable :var:`self` which always contains the internal
428 ID of the current object, and is really convenient when using a
429 ``Class``. By using this variable in our ``print_ret`` statement, we
430 ensure that the message contains the name of the appropriate object.
432 Let's see an example of this in action; here's a ``Prop`` object from
435 Prop "south gate" street
436 with name 'south' 'southern' 'wooden' 'gate',
437 description "The large wooden gate in the town walls is wide open.",
440 If players type EXAMINE GATE, they'll see "The large wooden gate..."; if
441 they type CLOSE GATE then the gate's :prop:`before` property will step in
442 and display "You don't need to worry about the south gate", neatly picking
443 up the name of the object from the :var:`self` variable.
445 The reason for doing all this, rather than just creating a simple scenery
446 object like Heidi's ``tree`` and ``cottage``, is to support EXAMINE for
447 increased realism, while clearly hinting to players that trying other verbs
448 would be a waste of time.
450 A class for furniture
451 ---------------------
453 .. Generated by autoindex
456 pair: static; library attribute
458 The last class for now -- we'll talk about the ``Arrow`` and ``NPC``
459 classes in the next chapter -- is for furniture-like objects. If you label
460 an object with the :attr:`static` attribute, an attempt to TAKE it results
461 in "That's fixed in place" -- acceptable in the case of Heidi's branch
462 object (which is indeed supposed to be part of the tree), less so for items
463 which are simply large and heavy. This ``Furniture`` class might sometimes
464 be more appropriate::
468 Take,Pull,Push,PushDir:
469 print_ret (The) self, " is too heavy for that.";
471 has static supporter;
473 Its structure is similar to that of our ``Prop`` class: some appropriate
474 attributes, and a :prop:`before` property to trap actions directed at it.
475 Again, we display a message which is "personalised" for the object
476 concerned by using a ``(The) self`` print rule. This time we're
477 intercepting four actions; we *could* have written the property like this::
480 Take: print_ret (The) self, " is too heavy for that.";
481 Pull: print_ret (The) self, " is too heavy for that.";
482 Push: print_ret (The) self, " is too heavy for that.";
483 PushDir: print_ret (The) self, " is too heavy for that.";
486 .. Generated by autoindex
488 pair: PushDir; library action
490 but since we're giving exactly the same response each time, it's better to
491 put all of those actions into one list, separated by commas.
492 :act:`PushDir`, if you were wondering, is the action triggered by a command
493 like PUSH THE TABLE NORTH.
495 Incidentally, another bonus of defining classes like these is that you can
496 probably reuse them in your next game.
498 Now that most of our class definitions are in place, we can get on with
499 defining some real rooms and objects. First, though, if you're typing in
500 the "William Tell" game as you read through the guide, you'd probably like
501 to check that what you've entered so far is correct;
502 :ref:`compile-as-you-go` explains how to compile the game in its current --