d8b32188d266fd499db60f90eee37fd7b06e3fea
[ibg.git] / chapters / 10.rst
1 ====================
2 Captain Fate: take 1
3 ====================
4
5 .. epigraph::
6
7    | *S was a sailor, and spent all he got;*
8    | *T was a tinker, and mended a pot.*
9
10 .. only:: html
11
12   .. image:: /images/picS.png
13      :align: left
14
15 .. raw:: latex
16
17    \dropcap{s}
18
19 imple though they are, our two games have covered most of the basic
20 functionality of Inform, providing enough solid ground underfoot
21 for you to start creating simple stories. Even if some of what you've
22 encountered doesn't make sense yet, you should be able to browse a
23 game's source code and form a general understanding of what is going on.
24
25 We'll now design a third game, to show you a few additional features and 
26 give you some more sample code to analyse. In "Heidi" we tried to make 
27 progress step by step, explaining every bit of code that went into the 
28 game as we laid the objects sequentially; in "William Tell" you'll have 
29 noticed that we took a few necessary explanatory detours, as the 
30 concepts grew more interesting and complicated. Here we'll organise the 
31 information in logical didactic chunks, defining some of the objects 
32 minimally at first and then adding complexity as need arises. Again, 
33 this means that you won't be able to compile for testing purposes after 
34 the addition of every code snippet, so, if you're typing in the game as 
35 you read, you’ll need to check the advice in :ref:`compile-as-you-go`.
36
37 A lot of what goes into this game we have already seen; you may deduce 
38 from this that the game design business is fairly repetitious and that 
39 most games are, when you reach the programming bottom line, another 
40 remake of the same old theme. Well, yes and no: you've got a camera and 
41 have seen some short home videos in the making, but it’s a long way from 
42 here to Casablanca. To stick with the analogy, we'll now construct the 
43 opening sequence of an indie B-movie, a tribute to the style of 
44 super-hero made famous by a childhood of comic books:
45
46 .. pull-quote::
47
48         "Impersonating mild mannered John Covarth, assistant help boy at 
49         an Impersonating insignificant drugstore, you suddenly STOP 
50         when your acute hearing deciphers a stray radio call from the 
51         POLICE. There’s some MADMAN attacking the population in Granary 
52         Park! You must change into your Captain FATE costume fast...!"
53
54 which won't be so easy to do. In this short example, players will win 
55 when they manage to change into their super-hero costume and fly away to 
56 meet the foe. The confrontation will -- perhaps -- take place in some 
57 other game, where we can but hope that Captain Fate will vanquish the 
58 forces of evil, thanks to his mysterious (and here unspecified) 
59 superpowers.
60
61 Fade up on: a nondescript city street
62 =====================================
63
64 The game starts with meek John Covarth walking down the street. We set 
65 up the game as usual:
66
67 .. code-block:: inform
68
69   !% -SD
70   !============================================================================
71   Constant Story "Captain Fate";
72   Constant Headline
73              "^A simple Inform example
74               ^by Roger Firth and Sonja Kesserich.^";
75   Release 3; Serial "040804";    ! for keeping track of public releases
76
77   Constant MANUAL_PRONOUNS;
78   Constant MAX_SCORE     2;
79   Constant OBJECT_SCORE  1;
80   Constant ROOM_SCORE    1;
81
82   Include "Parser";
83   Include "VerbLib";
84
85   !============================================================================
86   ! Object classes
87
88   Class  Room
89     with description "UNDER CONSTRUCTION",
90     has  light;
91
92   Class  Appliance
93     with before [;
94            Take,Pull,Push,PushDir:
95              "Even though your SCULPTED adamantine muscles are up to the task,
96               you don't favour property damage.";
97          ],
98     has  scenery;
99
100   !============================================================================
101   ! The game objects
102
103   Room    street "On the street"
104     with  name 'city' 'buildings' 'skyscrapers' 'shops' 'apartments' 'cars',
105           description
106               "On one side -- which your HEIGHTENED sense of direction
107                indicates is NORTH -- there's an open cafe now serving
108                lunch. To the south, you can see a phone booth.";
109
110   !============================================================================
111   ! The player's possessions
112
113   !============================================================================
114   ! Entry point routines
115
116   [ Initialise;
117       location = street;
118       lookmode = 2;
119       "^^Impersonating mild mannered John Covarth, assistant help boy at an
120        insignificant drugstore, you suddenly STOP when your acute hearing
121        deciphers a stray radio call from the POLICE. There's some MADMAN
122        attacking the population in Granary Park! You must change into your
123        Captain FATE costume fast...!^^";
124   ];
125
126   !============================================================================
127   ! Standard and extended grammar
128
129   Include "Grammar";
130   !============================================================================
131
132 Almost everything is familar, apart from a few details:
133
134 .. code-block:: inform
135
136   Constant MANUAL_PRONOUNS;
137   Constant MAX_SCORE     2;
138   Constant OBJECT_SCORE  1;
139   Constant ROOM_SCORE    1;
140
141 By default, Inform uses a system of automatic pronouns: as the player 
142 character moves into a room, the library assigns pronouns like IT and 
143 HIM to likely objects (if you play "Heidi" or "William Tell" and type 
144 PRONOUNS, you can see how the settings change). There is another option. 
145 If we declare the ``MANUAL_PRONOUNS`` onstant, we force the library to 
146 assign pronouns to objects only as the player mentions them (that is, IT 
147 will be unassigned until the player types, say, EXAMINE TREE, at which 
148 point, IT becomes the TREE ). The behaviour of pronoun assignment is a 
149 matter of personal taste; no system is objectively perfect.
150
151 Apart from the constant ``MAX_SCORE`` that we have seen in "William 
152 Tell", which defines the maximum number of points to be scored, we now 
153 see two more constants: ``OBJECT_SCORE`` and ``ROOM_SCORE``. There are 
154 several scoring systems predefined in Inform. In "William Tell" we've 
155 seen how you can manually add (or subtract) points by changing the value 
156 of the variable ``score``. Another approach is to award points to 
157 players on the first occasion that they (a) enter a particular room, or 
158 (b) pick up a particular object. To define that a room or object is 
159 indeed “particular”, all you have to do is give it the attribute 
160 ``scored``; the library take cares of the rest. The predefined scores 
161 are five points for finally reached rooms and four points for wondrous 
162 acquisition of objects. With the constants ``OBJECT_SCORE`` and 
163 ``ROOM_SCORE`` we can change those defaults; for the sake of example, 
164 we've decided to modestly award one point for each. By the way, the use 
165 of an equals sign ``=`` is optional with ``Constant``; these two lines 
166 have identical effect:
167
168 .. code-block:: inform
169
170   Constant ROOM_SCORE    1;
171
172   Constant ROOM_SCORE  = 1;
173
174 Another difference has to do with a special short-hand method that 
175 Inform provides for displaying strings of text. Until now, we have shown 
176 you:
177
178 .. code-block:: inform
179
180   print "And now for something completely different...^"; return true;
181   ...
182   print_ret "And now for something completely different...";
183
184 Both lines do the same thing: they display the quoted string, output a 
185 newline character, and return true. As you have seen in the previous 
186 example games, this happens quite a lot, so there is a yet shorter way 
187 of achieving the same result:
188
189 .. code-block:: inform
190
191   "And now for something completely different...";
192
193 That is, *in a routine* (where the compiler is expecting to find a 
194 collection of statements each terminated by a semicolon), a string in 
195 double quotes by itself, without the need for any explicit keywords, 
196 works exactly as if there were a ``print_ret`` in front of it. Remember 
197 that this way of displaying text implies a ``return true`` at the end 
198 (which therefore exits from the routine immediately). This detail 
199 becomes important if we *don't* want to return true after the string 
200 has been displayed on the screen -- we should use the explicit ``print`` 
201 statement instead.
202
203 You'll notice that -- unusually for a room -- our ``street`` object has 
204 a ``name`` property:
205
206 .. code-block:: inform
207
208   Room    street "On the street"
209     with  name 'city' 'buildings' 'skyscrapers' 'shops' 'apartments' 'cars',
210     ...
211
212 Rooms aren't normally referenced by name, so this may seem odd. In fact, 
213 we're illustrating a feature of Inform: the ability to define dictionary 
214 words as "known but irrelevant" in this location. If the player types 
215 EXAMINE CITY here, the interpreter will reply "That's not something you 
216 need to refer to in order to SAVE the day", rather than the misleading 
217 "You can't see any such thing". We mostly prefer to deal with such 
218 scenic words using classes like ``Prop`` and ``Furniture``, but 
219 sometimes a room's ``name`` property is a quick and convenient solution.
220
221 In this game, we provide a class named ``Appliance`` to take care of 
222 furniture and unmovable objects. You’ll notice that the starting room we 
223 have defined has no connections yet. The description mentions a phone 
224 booth and a café, so we might want to code those. While the café will be 
225 a normal room, it would seem logical that the phone booth is actually a 
226 big box on the sidewalk; therefore we define a ``container`` set in the 
227 street, which players may enter:
228
229 .. code-block:: inform
230
231   Appliance booth "phone booth" street
232     with name 'old' 'red' 'picturesque' 'phone' 'booth' 'cabin'
233              'telephone' 'box',
234          description
235              "It's one of the old picturesque models, a red cabin with room
236               for one caller.",
237          before [;
238            Open:
239              "The booth is already open.";
240            Close:
241              "There's no way to close this booth.";
242          ],
243          after [;
244            Enter:
245              "With implausible celerity, you dive inside the phone booth.";
246          ],
247     has  enterable container open;
248
249 What's interesting are the attributes at the end of the definition. 
250 You'll recall from Heidi's ``nest`` object that a ``container`` is an 
251 object capable of having other objects placed in it. If we make 
252 something ``enterable``, players count as one of those objects, so that 
253 they may squeeze inside. Finally, ``containers`` are, by default, 
254 supposed to be closed. You can make them ``openable`` if you wish 
255 players to be able to OPEN and CLOSE them at will, but this doesn't seem 
256 appropriate behaviour for a public cabin -- it would become tedious to 
257 have to type OPEN BOOTH and CLOSE BOOTH when these actions provide 
258 nothing special -- so we add instead the attribute ``open`` (as we did 
259 with the nest), telling the interpreter that the container is open from 
260 the word go. Players aren't aware of our design, of course; they may 
261 indeed try to OPEN and CLOSE the booth, so we trap those actions in a 
262 ``before`` property which just tells them that these are not relevant 
263 options. The ``after`` property gives a customised message to override 
264 the library’s default for commands like ENTER BOOTH or GO INSIDE BOOTH.
265
266 Since in the street's description we have told players that the phone 
267 booth is to the south, they might also try typing SOUTH. We must 
268 intercept this attempt and redirect it (while we're at it, we add a 
269 connection to the as-yet-undefined café room and a default message for 
270 the movement which is not allowed):
271
272 .. code-block:: inform
273
274   Room    street "On the street"
275     with  name city' 'buildings' 'skyscrapers' 'shops' 'apartments' 'cars',
276           description
277               "On one side -- which your HEIGHTENED sense of direction
278                indicates is NORTH -- there's an open cafe now serving
279                lunch. To the south, you can see a phone booth.",
280           n_to cafe,
281           s_to [; <<Enter booth>>; ],
282           cant_go
283               "No time now for exploring! You'll move much faster in your
284                Captain FATE costume.";
285
286 That takes care of entering the booth. But what about leaving it? 
287 Players may type EXIT or OUT while they are inside an enterable 
288 container and the interpreter will oblige but, again, they might type 
289 NORTH. This is a problem, since we are actually in the street (albeit 
290 inside the booth) and to the north we have the café. We may provide for 
291 this condition in the room's ``before`` property:
292
293 .. code-block:: inform
294
295   before [;
296     Go:
297       if (player in booth && noun == n_obj) <<Exit booth>>;
298   ],
299
300 Since we are outdoors and the booth provides a shelter, it's not 
301 impossible that a player may try just IN, which is a perfectly valid 
302 connection. However, that would be an ambiguous command, for it could 
303 also refer to the café, so we express our bafflement and force the 
304 player to try something else:
305
306 .. code-block:: inform
307
308   n_to cafe,
309   s_to [; <<Enter booth>>; ],
310   in_to "But which way?",
311
312 Now everything seems to be fine, except for a tiny detail. We've said 
313 that, while in the booth, the player character’s location is still the 
314 ``street`` room, regardless of being inside a ``container``; if players 
315 chanced to type LOOK, they'd get:
316
317 .. code-block:: transcript
318
319   On the street (in the phone booth)
320   On one side -- which your HEIGHTENED sense of direction indicates is NORTH --
321   there's an open cafe now serving lunch. To the south, you can see a 
322   phone booth.
323
324 Hardly an adequate description while *inside* the booth. There are 
325 several ways to fix the problem, depending on the result you wish to 
326 achieve. The library provides a property called ``inside_description`` 
327 which you can utilise with enterable containers. It works pretty much 
328 like the normal ``description`` property, but it gets printed only when 
329 the player is inside the container. The library makes use of this 
330 property in a very clever way, because for every LOOK action it checks 
331 whether we can see outside the container: if the container has the 
332 ``transparent`` attribute set, or if it happens to be ``open``, the 
333 library displays the normal ``description`` of the room first and then 
334 the ``inside_description`` of the container. If the library decides we 
335 can’t see outside the container, only the inside_description is 
336 displayed. Take for instance the following (simplified) example:
337
338 .. code-block:: inform
339
340   Room    stage "On stage"
341     with  description
342               "The stage is filled with David Copperfield's
343                magical contraptions.",
344           ...
345
346   Object  magic_box "magic box" stage
347     with  description
348               "A big elongated box decorated with silver stars, where
349                scantily clad ladies make a disappearing act.",
350           inside_description
351               "The inside panels of the magic box are covered with black
352                velvet. There is a tiny switch by your right foot.",
353           ...
354     has   container openable enterable light;
355
356 Now, the player would be able to OPEN BOX and ENTER BOX. A player who
357 tried a LOOK would get:
358
359 .. code-block:: transcript
360
361   On stage (in the magic box)
362   The stage is filled with David Copperfield's magical contraptions.
363
364   The inside panels of the magic box are covered with black velvet. There is a
365   tiny switch by your right foot.
366
367 If now the player closes the box and LOOKs:
368
369 .. code-block:: transcript
370
371   On stage (in the magic box)
372   The inside panels of the magic box are covered with black velvet. There is a
373   tiny switch by your right foot.
374
375 In our case, however, we don't wish the description of the street to be 
376 displayed at all (even if a caller is supposedly able to see the street 
377 while inside a booth). The problem is that we have made the booth an 
378 ``open`` container, so the street's description would be displayed every 
379 time. There is another solution. We can make the ``description`` 
380 property of the ``street`` room a bit more complex, and change its 
381 value: instead of a string, we write an embedded routine. Here's the 
382 (almost) finished room:
383
384 .. code-block:: inform
385
386   Room    street "On the street"
387     with  name 'city' 'buildings' 'skyscrapers' 'shops' 'apartments' 'cars',
388           description [;
389               if (player in booth)
390                   "From this VANTAGE point, you are rewarded with a broad view
391                    of the sidewalk and the entrance to Benny's cafe.";
392               else
393                   "On one side -- which your HEIGHTENED sense of direction
394                    indicates is NORTH -- there's an open cafe now serving
395                    lunch. To the south, you can see a phone booth.";
396           ],
397           before [;
398             Go:
399               if (player in booth && noun == n_obj) <<Exit booth>>;
400           ],
401           n_to cafe,
402           s_to [; <<Enter booth>>; ],
403           in_to "But which way?",
404           cant_go
405                "No time now for exploring! You'll move much faster in your
406                 Captain FATE costume.";
407
408 The description while inside the booth mentions the sidewalk, which 
409 might invite the player to EXAMINE it. No problem:
410
411 .. code-block:: inform
412
413   Appliance "sidewalk" street
414     with  name sidewalk' 'pavement' 'street',
415           article "the",
416           description
417               "You make a quick surveillance of the sidewalk and discover much
418                to your surprise that it looks JUST like any other sidewalk in
419                the CITY!";
420
421 Unfortunately, both descriptions also mention the café, which will be a 
422 room and therefore not, from the outside, an examinable object. The 
423 player may enter it and will get whatever description we code as the 
424 result of a LOOK action (which will have to do with the way the café 
425 looks from the *inside*); but while we are on the street we need 
426 something else to describe it:
427
428 .. code-block:: inform
429
430   Appliance outside_of_cafe "Benny's cafe" street
431     with  name 'benny^s' 'cafe' 'entrance',
432           description
433               "The town's favourite for a quick snack, Benny's cafe has a 50's
434                ROCKETSHIP look.",
435           before [;
436             Enter:
437               print "With an impressive mixture of hurry and nonchalance
438                   you step into the open cafe.^";
439               PlayerTo(cafe);
440               return true;
441           ],
442     has   enterable proper;
443
444 .. note::
445
446    although the text of our guide calls Benny's establishment a "café" 
447    -- note the acute "e" -- the game itself simplifies this to "cafe". 
448    We do this for clarity, not because Inform doesn't support accented 
449    characters. The *Inform Designer's Manual* explains in detail how to 
450    display these characters in "§1.11 *How text is printed*" and 
451    provides the whole Z-machine character set in Table 2. In our case, 
452    we could have displayed this::
453
454       The town's favourite for a quick snack, Benny's café has a 50's ROCKETSHIP look.
455
456    by defining the ``description`` property as any of these:
457
458    .. code-block:: inform
459
460      description
461          "The town's favourite for a quick snack, Benny's caf@'e has a 50's
462           ROCKETSHIP look.",
463
464      description
465          "The town's favourite for a quick snack, Benny's caf@@170 has a 50's
466           ROCKETSHIP look.",
467
468      description
469          "The town's favourite for a quick snack, Benny's caf@{E9} has a 50's
470           ROCKETSHIP look.",
471
472    However, all three forms are harder to read than the vanilla "cafe", so 
473    we've opted for the simple life.
474
475 Unlike the sidewalk object, we offer more than a mere description. Since 
476 the player may try ENTER CAFE as a reasonable way of access -- which 
477 would have confused the interpreter immensely -- we take the opportunity 
478 of making this object also ``enterable``, and we cheat a little. The 
479 attribute ``enterable`` has permitted the verb ENTER to be applied to 
480 this object, but this is not a ``container``; we want the player to be 
481 sent into the *real* café room instead. The ``before`` property handles 
482 this, intercepting the action, displaying a message and teleporting the 
483 player into the café. We ``return true`` to inform the interpreter that 
484 we have taken care of the ``Enter`` action ourselves, so it can stop 
485 right there.
486
487 As a final detail, note that we now have two ways of going into the 
488 café: the ``n_to`` property of the ``street`` room and the ``Enter`` 
489 action of the ``outside_of_cafe`` object. A perfectionist might point 
490 out that it would be neater to handle the actual movement of the player 
491 in just one place of our code, because this helps clarity. To achieve 
492 this, we redirect the street's ``n_to`` property thus:
493
494 .. code-block:: inform
495
496   n_to [; <<Enter outside_of_cafe>>; ],
497
498 You may think that this is unnecessary madness, but a word to the wise: in
499 a large game, you want action handling going on just in one place when
500 possible, because it will help you to keep track of where things are
501 a-happening if something goes *ploof* (as, believe us, it will; see
502 :doc:`16`). You don't need to be a perfectionist, just cautious.
503
504 A booth in this kind of situation is an open invitation for the player to
505 step inside and try to change into Captain Fate's costume. We won't let
506 this happen -- the player isn't Clark Kent, after all; later we'll explain
507 how we forbid this action -- and that will force the player to go inside
508 the café, looking for a discreet place to disrobe; but first, let's freeze
509 John Covarth outside Benny's and reflect about a fundamental truth.
510
511 A hero is not an ordinary person
512 ================================
513
514 Which is to say, normal actions won't be the same for him.
515
516 As you have probably inferred from the previous chapters, some of the 
517 library’s standard defined actions are less important than others in 
518 making the game advance towards one of its conclusions. The library 
519 defines PRAY and SING, for instance, which are of little consequence in 
520 a normal gaming situation; each displays an all-purpose message, 
521 sufficiently non-committal, and that's it. Of course, if your game 
522 includes a magic portal that will reveal itself only if the player lets 
523 rip with a snatch of Wagner, you may intercept the ``Sing`` action in a 
524 ``before`` property and alter its default, pretty useless behaviour. If 
525 not, it's "Your singing is abominable" for you.
526
527 All actions, useful or not, have a stock of messages associated with 
528 them (the messages are held in the ``english.h`` library file and listed 
529 in Appendix 4 of the *Inform Designer's Manual*). We have already seen 
530 one way of altering the player character's description -- "As good 
531 looking as ever" -- in "William Tell", but the other defaults may also 
532 be redefined to suit your tastes and circumstantial needs.
533
534 John Covarth, aka Captain Fate, could happily settle for most of these 
535 default messages, but we deem it worthwhile to give him some customised 
536 responses. If nothing else, this adds to the general atmosphere, a 
537 nicety that many players regard as important. For this mission, we make 
538 use of the ``LibraryMessages`` object.
539
540 .. code-block:: inform
541
542   Include "Parser";
543
544   Object  LibraryMessages         ! must be defined between Parser and VerbLib
545     with  before [;
546             Buy:    "Petty commerce interests you only on COUNTED occasions.";
547             Dig:    "Your keen senses detect NOTHING underground worth your
548                      immediate attention.";
549             Pray:   "You won't need to bother almighty DIVINITIES to save
550                      the day.";
551             Sing:   "Alas! That is not one of your many superpowers.";
552             Sleep:  "A hero is ALWAYS on the watch.";
553             Strong: "An unlikely vocabulary for a HERO like you.";
554             Swim:   "You quickly turn all your ATTENTION towards locating a
555                      suitable place to EXERCISE your superior strokes,
556                      but alas! you find none.";
557             Miscellany:
558               if (lm_n == 19)
559                   if (clothes has worn)
560                       "In your secret identity's outfit, you manage most
561                        efficaciously to look like a two-cent loser, a
562                        good-for-nothing wimp.";
563                   else
564                       "Now that you are wearing your costume, you project
565                        the image of power UNBOUND, of ballooned,
566                        multicoloured MUSCLE, of DASHING yet MODEST chic.";
567               if (lm_n == 38)
568                   "That's not a verb you need to SUCCESSFULLY save the day.";
569               if (lm_n == 39)
570                   "That's not something you need to refer to in order to
571                    SAVE the day.";
572         ];
573
574   Include "VerbLib";
575
576 If you provide it, the ``LibraryMessages`` object must be defined 
577 *between* the inclusion of ``Parser`` and ``VerbLib`` (it won't work 
578 otherwise and you’ll get a compiler error). The object contains a single 
579 property -- ``before`` -- which intercepts display of the default 
580 messages that you want to change. An attempt to SING, for example, will 
581 now result in "Alas! That is not one of your many superpowers" being 
582 displayed.
583
584 In addition to such verb-specific responses, the library defines other 
585 messages not directly associated with an action, like the default 
586 response when a verb is unrecognised, or if you refer to an object which 
587 is not in scope, or indeed many other things. Most of these messages can 
588 be accessed through the ``Miscellany entry``, which has a numbered list 
589 of responses. The variable ``lm_n`` holds the current value of the 
590 number of the message to be displayed, so you can change the default 
591 with a test like this:
592
593 .. code-block:: inform
594
595   if (lm_n == 39)
596       "That's not something you need to refer to in order to SAVE the day.";
597
598 where 39 is the number for the standard message "That's not something 
599 you need to refer to in the course of this game" -- displayed when the 
600 player mentions a noun which is listed in a room's name property, as we 
601 did for the ``street``.
602
603 .. note::
604
605    Remember that when we are testing for different values of the 
606    same variable, we can also use the switch statement. For the 
607    Miscellany entry, the following code would work just as nicely:
608
609    .. code-block:: inform
610
611      ...
612      Miscellany:
613        switch (lm_n) {
614          19:
615            if (clothes has worn)
616                "In your secret identity's outfit, you manage most
617                 efficaciously to look like a two-cent loser, a
618                 good-for-nothing wimp.";
619            else
620                "Now that you are wearing your costume, you project
621                 the image of power UNBOUND, of ballooned,
622                 multicoloured MUSCLE, of DASHING yet MODEST chic.";
623          38:
624            "That's not a verb you need to SUCCESSFULLY save the day.";
625          39:
626            "That's not something you need to refer to in order to SAVE the day.";
627        }
628
629 Not surprisingly, the default message for self-examination: "As good 
630 looking as ever" is a ``Miscellany`` entry -- it's number 19 -- so we 
631 can change it through the ``LibraryMessages`` object instead of, as 
632 before, assigning a new string to the ``player.description property``. 
633 In our game, the description of the player character has two states: 
634 with street clothes as John Covarth and with the super-hero outfit as 
635 Captain Fate; hence the ``if (clothes has worn)`` clause.
636
637 This discussion of changing our hero's appearance shows that there are 
638 different ways of achieving the same result, which is a common situation 
639 while designing a game. Problems may be approached from different 
640 angles; why use one technique and not another? Usually, the context tips 
641 the balance in favour of one solution, though it might happen that you 
642 opt for the not-so-hot approach for some overriding reason. Don't feel 
643 discouraged; choices like this become more common (and easier) as your 
644 experience grows.
645
646 .. todo::
647
648     That "whatever new look" below needs to be italicized and bolded for LaTeX
649
650 .. note::
651
652    going back to our example, an alternative approach would be to set 
653    the variable ``player.description`` in the ``Initialise`` routine (as we 
654    did with "William Tell") to the "ordinary clothes" string, and then 
655    later change it as the need arises. It is a variable, after all, and you 
656    can alter its value with another statement like ``player.description =`` 
657    *whatever new look* anywhere in your code. This alternative solution 
658    might be better if we intended changing the description of the player 
659    many times through the game. Since we plan to have only two states, the 
660    ``LibraryMessages`` approach will do just fine.
661
662 A final warning: as we explained when extending the standard verb 
663 grammars, you *could* edit the appropriate library file and change all 
664 the default messages, but that wouldn't be a sound practice, because 
665 your library file will probably not be right for the next game. Use of 
666 the ``LibraryMessages`` object is strongly advised.
667
668 If you're typing in the game, you'll probably want to read the brief
669 section on :ref:`compile-as-you-go` prior to performing a test compile.
670 Once everything's correct, it’s time that our hero entered that enticing
671 café.