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