495b8d4b973a4b183b4f03e53809c770ef6055a7
[ibg.git] / chapters / 06.rst
1 ==============================
2  William Tell: a tale is born
3 ==============================
4
5 .. highlight:: inform
6
7 .. epigraph::
8
9    | |CENTER| *K was King William, once governed the land;*
10    | |CENTER| *L was a lady, who had a white hand.*
11
12 .. only:: html
13
14    .. image:: /images/picK.png
15       :align: left
16
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.
24
25 Initial setup
26 =============
27
28 Our starting point is much the same as last time.  Here's a basic
29 ``Tell.inf``::
30
31    !% -SD
32    !===========================================================================
33    Constant Story "William Tell";
34    Constant Headline
35                "^A simple Inform example
36                 ^by Roger Firth and Sonja Kesserich.^";
37    Release 3; Serial "040804";     ! for keeping track of public releases
38
39    Constant MAX_SCORE = 3;
40
41    Include "Parser";
42    Include "VerbLib";
43
44    !===========================================================================
45    ! Object classes
46
47    !===========================================================================
48    ! The game objects
49
50    !===========================================================================
51    ! The player's possessions
52
53    !===========================================================================
54    ! Entry point routines
55
56    [ Initialise;
57        location = street;
58        lookmode = 2;           ! like the VERBOSE command
59        move bow to player;
60        move quiver to player; give quiver worn;
61        player.description =
62            "You wear the traditional clothing of a Swiss mountaineer.";
63        print_ret "^^
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.
70                ^^
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.
76                ^^
77                It's market-day: the town is packed with people from the
78                surrounding villages and settlements.^";
79    ];
80
81    !===========================================================================
82    ! Standard and extended grammar
83
84    Include "Grammar";
85
86    !===========================================================================
87
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
91 pieces:
92
93 * If you look at a game's banner, you'll see two pieces of information:
94   "Release" and "Serial number".
95
96   .. code-block:: transcript
97
98      William Tell
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
102
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::
113
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
117
118 * We'll be implementing a simple system of awarding points when the player
119   gets something right, so we define top marks::
120
121      Constant MAX_SCORE = 3;
122
123 * The ``Initialise`` routine that we wrote last time contained only one
124   statement, to set the player's initial ``location``.  We do that here as
125   well, but we also do some other stuff.
126
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.
135
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::
140
141      move bow to player;
142      move quiver to player;
143
144   and indeed this is the clearest way to place objects in the player's
145   inventory at the beginning of any game.
146
147   .. note::
148
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
152      the header::
153
154         Object bird "baby bird" forest
155
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 ``selfobj``; ``player`` is a
159      variable whose value is that identifier.  Rather than worry all about
160      this, it's easier to use the ``move`` statements.
161
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   ``worn``.  Normally the interpreter would apply this automatically, while
165   handling a command like WEAR QUIVER, but since we've moved the quiver
166   ourselves, we also need to set the quiver's ``worn`` attribute.  The
167   ``give`` statement does the job::
168
169      give quiver worn;
170
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".)
174
175 * If the player types EXAMINE ME, the interpreter displays the
176   ``description`` property of the ``player`` object.  The default value is
177   "As good-looking as ever", a bit of a cliché in the world of Inform
178   games.  It's easy to change, though, once you realise that, since the
179   properties of an object are variables, you can assign new values to them
180   just as you'd assign new values to ``location`` and ``lookmode``.  The
181   only problem is getting the syntax right; you can't say just::
182
183      description = "You wear the traditional clothing of a Swiss mountaineer.";
184
185   because there are dozens of objects in the game, each with its own
186   ``description`` property; you need to be a little more explicit.  Here's
187   what to type::
188
189      player.description =
190              "You wear the traditional clothing of a Swiss mountaineer.";
191
192 * Finally, the ``Initialise`` routine ends with a lengthy ``print_ret``
193   statement.  Since the interpreter calls ``Initialise`` right at the start
194   of the game, that's the point at which this material is displayed, so
195   that it acts as a scene-setting preamble before the game gets under way.
196   In fact, everything you want set or done at the very beginning of the
197   game, should go into the ``Initialise`` routine.
198
199 The game won't compile in this state, because it contains references to
200 objects which we haven't yet defined.  In any case, we don't intend to
201 build up the game in layers as we did last time, but rather to talk about
202 it in logically related chunks.  To see (and if you wish, to type) the
203 complete source, go to :doc:`/appendices/c`.
204
205 Object classes
206 ==============
207
208 Remember how we defined the rooms in "Heidi"?  Our first attempt started
209 like this::
210
211    Object  "In front of a cottage"
212      with  description
213                "You stand outside a cottage. The forest stretches east.",
214       has  light;
215
216    Object  "Deep in the forest"
217      with  description
218                "Through the dense foliage, you glimpse a building to the west.
219                 A track heads to the northeast.",
220       has  light;
221
222    ...
223
224 and we explained that just about *every* room needs that ``light``
225 attribute, or else the player would be literally in the dark.  It's a bit
226 of a nuisance having to specify that same attribute each time; what would
227 be neater would be to say that *all* rooms are illuminated.  So we can
228 write this::
229
230    Class  Room
231      has  light;
232
233     Room  "In front of a cottage"
234     with  description
235                "You stand outside a cottage. The forest stretches east.",
236      has  ;
237
238     Room  "Deep in the forest"
239     with  description
240                "Through the dense foliage, you glimpse a building to the west.
241                 A track heads to the northeast.",
242      has  ;
243
244     ...
245
246 We've done four things:
247
248 #. We've said that some of the objects in our game are going to be defined
249    by the specialised word ``Room`` rather than the general-purpose word
250    ``Object``.  In effect, we've taught Inform a new word specially for
251    defining objects, which we can now use as though it had been part of the
252    language all along.
253
254 #. We've furthermore said that every object which we define using ``Room``
255    is automatically going to have the ``light`` attribute.
256
257 #. We've changed the way in which we define the four room objects, by
258    starting them with our specialised word ``Room``.  The remainder of the
259    definition for these objects -- the header information, the block of
260    properties, the block of attributes and the final semicolon -- remains
261    the same; except that:
262
263 #. We don't need to explicitly include the ``light`` attribute each time;
264    every ``Room`` object has it automatically.
265
266 A :term:`class` is a family of closely related objects, all of which behave
267 in the same way.  Any properties defined for the class, and any attributes
268 defined for the class, are automatically given to objects which you specify
269 as belonging to that class; this process of acquisition just by being a
270 member of a class is called :term:`inheritance`.  In our example, we've
271 defined a ``Room`` class with a ``light`` attribute, and then we've
272 specified four objects each of which is a member of that class, and each of
273 which gets given a ``light`` attribute as a result of that membership.
274
275 Why have we gone to this trouble?  Three main reasons:
276
277 * By moving the common bits of the definitions from the individual objects
278   to the class definition which they share, those object definitions
279   become shorter and simpler.  Even if we had a hundred rooms, we'd still
280   need to specify ``has light`` only once.
281
282 * By creating a specialised word to identify our class of objects, we make
283   our source file easier to read.  Rather than absolutely everything being
284   an anonymous ``Object``, we can now immediately recognise that some are
285   ``Room`` objects (and others belong to the different classes that we'll
286   create soon).
287
288 * By collecting the common definitions into one place, we make it much
289   easier to make widespread modifications in future.  If we need to make
290   some change to the definition of all our rooms, we just modify the
291   ``Room`` class, and all of the class members inherit the change.
292
293 For these reasons, the use of classes is an incredibly powerful technique,
294 easier than it may look, and very well worth mastering.  From now on, we'll
295 be defining object classes whenever it makes sense (which is generally when
296 two or more objects are meant to behave in exactly the same way).
297
298 You may be wondering: suppose I want to define a room which for some reason
299 *doesn't* have ``light``; can I still use the ``Room`` class?  Sure you
300 can::
301
302    Room    cellar "Gloomy cellar"
303      with  description "Your torch shows only cobwebby brick walls.",
304      has   ~light;
305
306 This illustrates another nice feature of inheritance: the object definition
307 can override the class definition.  The class says ``has light``, but the
308 object itself says ``has ~light`` (read that as "has no light") and the
309 object wins.  The cellar is dark, and the player will need a torch to see
310 what's in it.
311
312 In fact, for any object both the block of properties and the block of
313 attributes are optional and can be omitted if there's nothing to be
314 specified.  Now that the ``light`` attribute is being provided
315 automatically and there aren't any other attributes to set, the word
316 ``has`` can be left out.  Here's the class again::
317
318    Class  Room
319      has  light;
320
321 and here is how we could have used it in "Heidi"::
322
323    Room    "In front of a cottage"
324      with  description
325                "You stand outside a cottage. The forest stretches east.";
326
327    Room    "Deep in the forest"
328      with  description
329                "Through the dense foliage, you glimpse a building to the west.
330                 A track heads to the northeast.";
331
332    ...
333
334 You'll notice that, if an object has no block of attributes, the semicolon
335 which terminates its definition simply moves to the end of its last
336 property.
337
338 .. _props-class:
339
340 A class for props
341 -----------------
342
343 We use the ``Room`` class in "William Tell", and a few other classes
344 besides.  Here's a ``Prop`` class (that's "Prop" in the sense of a
345 theatrical property rather than a supportive device), useful for scenic
346 items whose only role is to sit waiting in the background on the off-chance
347 that the player might think to EXAMINE them::
348
349    Class    Prop
350      with   before [;
351                Examine:
352                  return false;
353                default:
354                  print_ret "You don't need to worry about ", (the) self, ".";
355             ],
356       has   scenery;
357
358 All objects of this class inherit the ``scenery`` attribute, so they're
359 excluded from room descriptions.  Also, there's a ``before`` property; one
360 that's more complex than our previous efforts.  You'll remember that the
361 first ``before`` we met looked like this::
362
363    before [;
364       Listen:
365         print "It sounds scared and in need of assistance.^";
366         return true;
367    ],
368
369 The role of that original ``before`` was to intercept ``Listen`` actions,
370 while leaving all others well alone.  The role of the ``before`` in the
371 ``Prop`` class is broader: to intercept (a) ``Examine`` actions, and (b)
372 all the rest.  If the action is ``Examine``, then the ``return false``
373 statement means that the action carries on.  If the action is ``default``
374 -- none of those explicitly listed, which in this instance means *every*
375 action apart from ``Examine`` -- then the ``print_ret`` statement is
376 executed, after which the interpreter does nothing further.  So, a ``Prop``
377 object can be EXAMINEd, but any other action addressed to it results in a
378 "no need to worry" message.
379
380 That message is also more involved than anything we've so far displayed.
381 The statement which produces it is::
382
383    print_ret "You don't need to worry about ", (the) self, ".";
384
385 which you should read as doing this:
386
387 #. display the string "You don't need to worry about ",
388
389 #. display a definite article (usually "the") followed by a space and the
390    external name of the object concerned,
391
392 #. display a period, and
393
394 #. display a newline and return true in the usual way for a ``print_ret``
395    statement.
396
397 The interesting things that this statement demonstrates are:
398
399 * The ``print`` and ``print_ret`` statements aren't restricted to
400   displaying a single piece of information: they can display a list of
401   items which are separated by commas.  The statement still ends with a
402   semicolon in the usual way.
403
404 * As well as displaying strings, you can also display the names of objects:
405   given the ``nest`` object from our first game, ``(the) nest`` would
406   display "the bird's nest", ``(The) nest`` would display "The bird's
407   nest", ``(a) nest`` would display "a bird's nest", ``(A) nest`` would
408   display "A bird's nest" and ``(name) nest`` would display just "bird's
409   nest".  This use of a word in parentheses, telling the interpreter how to
410   display the following object's internal ID, is called a :term:`print
411   rule`.
412
413 * There's a library variable ``self`` which always contains the internal ID
414   of the current object, and is really convenient when using a ``Class``.
415   By using this variable in our ``print_ret`` statement, we ensure that the
416   message contains the name of the appropriate object.
417
418 Let's see an example of this in action; here's a ``Prop`` object from
419 "William Tell"::
420
421    Prop    "south gate" street
422      with  name 'south' 'southern' 'wooden' 'gate',
423            description "The large wooden gate in the town walls is wide open.",
424            ...
425
426 If players type EXAMINE GATE, they'll see "The large wooden gate..."; if
427 they type CLOSE GATE then the gate's ``before`` property will step in and
428 display "You don't need to worry about the south gate", neatly picking up
429 the name of the object from the ``self`` variable.
430
431 The reason for doing all this, rather than just creating a simple scenery
432 object like Heidi's ``tree`` and ``cottage``, is to support EXAMINE for
433 increased realism, while clearly hinting to players that trying other verbs
434 would be a waste of time.
435
436 A class for furniture
437 ---------------------
438
439 The last class for now -- we'll talk about the ``Arrow`` and ``NPC``
440 classes in the next chapter -- is for furniture-like objects.  If you label
441 an object with the ``static`` attribute, an attempt to TAKE it results in
442 "That's fixed in place" -- acceptable in the case of Heidi's branch object
443 (which is indeed supposed to be part of the tree), less so for items which
444 are simply large and heavy.  This ``Furniture`` class might sometimes be
445 more appropriate::
446
447    Class    Furniture
448      with   before [;
449                Take,Pull,Push,PushDir:
450                  print_ret (The) self, " is too heavy for that.";
451             ],
452       has   static supporter;
453
454 Its structure is similar to that of our ``Prop`` class: some appropriate
455 attributes, and a ``before`` property to trap actions directed at it.
456 Again, we display a message which is "personalised" for the object
457 concerned by using a ``(The) self`` print rule.  This time we're
458 intercepting four actions; we *could* have written the property like this::
459
460    before [;
461        Take: print_ret (The) self, " is too heavy for that.";
462        Pull: print_ret (The) self, " is too heavy for that.";
463        Push: print_ret (The) self, " is too heavy for that.";
464        PushDir: print_ret (The) self, " is too heavy for that.";
465    ],
466
467 but since we're giving exactly the same response each time, it's better to
468 put all of those actions into one list, separated by commas.  ``PushDir``,
469 if you were wondering, is the action triggered by a command like PUSH THE
470 TABLE NORTH.
471
472 Incidentally, another bonus of defining classes like these is that you can
473 probably reuse them in your next game.
474
475 Now that most of our class definitions are in place, we can get on with
476 defining some real rooms and objects.  First, though, if you're typing in
477 the "William Tell" game as you read through the guide, you'd probably like
478 to check that what you've entered so far is correct;
479 :ref:`compile-as-you-go` explains how to compile the game in its current --
480 incomplete -- state.