0d51d8af1af731678b16581a11c6740dea18f357
[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 ``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 ``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 ``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 ``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 ``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 ``container`` is an 
247 object capable of having other objects placed in it. If we make 
248 something ``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 ``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 ``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 ``before`` property which just tells them that these are not relevant 
259 options. The ``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 ``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 ``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 ``inside_description`` 
323 which you can utilise with enterable containers. It works pretty much 
324 like the normal ``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 ``transparent`` attribute set, or if it happens to be ``open``, the 
329 library displays the normal ``description`` of the room first and then 
330 the ``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 ``open`` container, so the street's description would be displayed every 
375 time. There is another solution. We can make the ``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 .. note::
441
442    Although the text of our guide calls Benny's establishment a "café" --
443    note the acute "e" -- the game itself simplifies this to "cafe".  We do
444    this for clarity, not because Inform doesn't support accented
445    characters. The |DM4| explains in detail how to display these characters
446    in :dm4:`§1.11 <s1.html#s1_11>` "*How text is printed*" and provides the
447    whole Z-machine character set in Table 2. In our case, we could have
448    displayed this::
449
450       The town's favourite for a quick snack, Benny's café has a 50's ROCKETSHIP look.
451
452    by defining the ``description`` property as any of these:
453
454    .. code-block:: inform
455
456      description
457          "The town's favourite for a quick snack, Benny's caf@'e has a 50's
458           ROCKETSHIP look.",
459
460      description
461          "The town's favourite for a quick snack, Benny's caf@@170 has a 50's
462           ROCKETSHIP look.",
463
464      description
465          "The town's favourite for a quick snack, Benny's caf@{E9} has a 50's
466           ROCKETSHIP look.",
467
468    However, all three forms are harder to read than the vanilla "cafe", so 
469    we've opted for the simple life.
470
471 Unlike the sidewalk object, we offer more than a mere description. Since 
472 the player may try ENTER CAFE as a reasonable way of access -- which 
473 would have confused the interpreter immensely -- we take the opportunity 
474 of making this object also ``enterable``, and we cheat a little. The 
475 attribute ``enterable`` has permitted the verb ENTER to be applied to 
476 this object, but this is not a ``container``; we want the player to be 
477 sent into the *real* café room instead. The ``before`` property handles 
478 this, intercepting the action, displaying a message and teleporting the 
479 player into the café. We ``return true`` to inform the interpreter that 
480 we have taken care of the ``Enter`` action ourselves, so it can stop 
481 right there.
482
483 As a final detail, note that we now have two ways of going into the 
484 café: the ``n_to`` property of the ``street`` room and the ``Enter`` 
485 action of the ``outside_of_cafe`` object. A perfectionist might point 
486 out that it would be neater to handle the actual movement of the player 
487 in just one place of our code, because this helps clarity. To achieve 
488 this, we redirect the street's ``n_to`` property thus:
489
490 .. code-block:: inform
491
492   n_to [; <<Enter outside_of_cafe>>; ],
493
494 You may think that this is unnecessary madness, but a word to the wise: in
495 a large game, you want action handling going on just in one place when
496 possible, because it will help you to keep track of where things are
497 a-happening if something goes *ploof* (as, believe us, it will; see
498 :doc:`16`). You don't need to be a perfectionist, just cautious.
499
500 A booth in this kind of situation is an open invitation for the player to
501 step inside and try to change into Captain Fate's costume. We won't let
502 this happen -- the player isn't Clark Kent, after all; later we'll explain
503 how we forbid this action -- and that will force the player to go inside
504 the café, looking for a discreet place to disrobe; but first, let's freeze
505 John Covarth outside Benny's and reflect about a fundamental truth.
506
507 A hero is not an ordinary person
508 ================================
509
510 Which is to say, normal actions won't be the same for him.
511
512 As you have probably inferred from the previous chapters, some of the 
513 library’s standard defined actions are less important than others in 
514 making the game advance towards one of its conclusions. The library 
515 defines PRAY and SING, for instance, which are of little consequence in 
516 a normal gaming situation; each displays an all-purpose message, 
517 sufficiently non-committal, and that's it. Of course, if your game 
518 includes a magic portal that will reveal itself only if the player lets 
519 rip with a snatch of Wagner, you may intercept the ``Sing`` action in a 
520 ``before`` property and alter its default, pretty useless behaviour. If 
521 not, it's "Your singing is abominable" for you.
522
523 All actions, useful or not, have a stock of messages associated with them
524 (the messages are held in the ``english.h`` library file and listed in
525 :dm4:`Appendix 4 <sa4.html>` of the |DM4|). We have already seen one way of
526 altering the player character's description -- "As good looking as ever" --
527 in "William Tell", but the other defaults may also be redefined to suit
528 your tastes and circumstantial needs.
529
530 John Covarth, aka Captain Fate, could happily settle for most of these 
531 default messages, but we deem it worthwhile to give him some customised 
532 responses. If nothing else, this adds to the general atmosphere, a 
533 nicety that many players regard as important. For this mission, we make 
534 use of the ``LibraryMessages`` object.
535
536 .. code-block:: inform
537
538   Include "Parser";
539
540   Object  LibraryMessages         ! must be defined between Parser and VerbLib
541     with  before [;
542             Buy:    "Petty commerce interests you only on COUNTED occasions.";
543             Dig:    "Your keen senses detect NOTHING underground worth your
544                      immediate attention.";
545             Pray:   "You won't need to bother almighty DIVINITIES to save
546                      the day.";
547             Sing:   "Alas! That is not one of your many superpowers.";
548             Sleep:  "A hero is ALWAYS on the watch.";
549             Strong: "An unlikely vocabulary for a HERO like you.";
550             Swim:   "You quickly turn all your ATTENTION towards locating a
551                      suitable place to EXERCISE your superior strokes,
552                      but alas! you find none.";
553             Miscellany:
554               if (lm_n == 19)
555                   if (clothes has worn)
556                       "In your secret identity's outfit, you manage most
557                        efficaciously to look like a two-cent loser, a
558                        good-for-nothing wimp.";
559                   else
560                       "Now that you are wearing your costume, you project
561                        the image of power UNBOUND, of ballooned,
562                        multicoloured MUSCLE, of DASHING yet MODEST chic.";
563               if (lm_n == 38)
564                   "That's not a verb you need to SUCCESSFULLY save the day.";
565               if (lm_n == 39)
566                   "That's not something you need to refer to in order to
567                    SAVE the day.";
568         ];
569
570   Include "VerbLib";
571
572 If you provide it, the ``LibraryMessages`` object must be defined 
573 *between* the inclusion of ``Parser`` and ``VerbLib`` (it won't work 
574 otherwise and you’ll get a compiler error). The object contains a single 
575 property -- ``before`` -- which intercepts display of the default 
576 messages that you want to change. An attempt to SING, for example, will 
577 now result in "Alas! That is not one of your many superpowers" being 
578 displayed.
579
580 In addition to such verb-specific responses, the library defines other 
581 messages not directly associated with an action, like the default 
582 response when a verb is unrecognised, or if you refer to an object which 
583 is not in scope, or indeed many other things. Most of these messages can 
584 be accessed through the ``Miscellany entry``, which has a numbered list 
585 of responses. The variable ``lm_n`` holds the current value of the 
586 number of the message to be displayed, so you can change the default 
587 with a test like this:
588
589 .. code-block:: inform
590
591   if (lm_n == 39)
592       "That's not something you need to refer to in order to SAVE the day.";
593
594 where 39 is the number for the standard message "That's not something 
595 you need to refer to in the course of this game" -- displayed when the 
596 player mentions a noun which is listed in a room's name property, as we 
597 did for the ``street``.
598
599 .. note::
600
601    Remember that when we are testing for different values of the 
602    same variable, we can also use the switch statement. For the 
603    Miscellany entry, the following code would work just as nicely:
604
605    .. code-block:: inform
606
607      ...
608      Miscellany:
609        switch (lm_n) {
610          19:
611            if (clothes has worn)
612                "In your secret identity's outfit, you manage most
613                 efficaciously to look like a two-cent loser, a
614                 good-for-nothing wimp.";
615            else
616                "Now that you are wearing your costume, you project
617                 the image of power UNBOUND, of ballooned,
618                 multicoloured MUSCLE, of DASHING yet MODEST chic.";
619          38:
620            "That's not a verb you need to SUCCESSFULLY save the day.";
621          39:
622            "That's not something you need to refer to in order to SAVE the day.";
623        }
624
625 Not surprisingly, the default message for self-examination: "As good 
626 looking as ever" is a ``Miscellany`` entry -- it's number 19 -- so we 
627 can change it through the ``LibraryMessages`` object instead of, as 
628 before, assigning a new string to the ``player.description property``. 
629 In our game, the description of the player character has two states: 
630 with street clothes as John Covarth and with the super-hero outfit as 
631 Captain Fate; hence the ``if (clothes has worn)`` clause.
632
633 This discussion of changing our hero's appearance shows that there are 
634 different ways of achieving the same result, which is a common situation 
635 while designing a game. Problems may be approached from different 
636 angles; why use one technique and not another? Usually, the context tips 
637 the balance in favour of one solution, though it might happen that you 
638 opt for the not-so-hot approach for some overriding reason. Don't feel 
639 discouraged; choices like this become more common (and easier) as your 
640 experience grows.
641
642 .. Ugh.  Ghastly, but it does the job.
643
644 .. |WNL_LATEX| replace:: :latex:`\emph{\textbf{whatever new look}}`
645
646 .. |WNL_HTML|  replace:: :html:`<strong><em>whatever new look</em></strong>`
647
648 .. note::
649
650    Going back to our example, an alternative approach would be to set the
651    variable ``player.description`` in the ``Initialise`` routine (as we did
652    with "William Tell") to the "ordinary clothes" string, and then later
653    change it as the need arises. It is a variable, after all, and you can
654    alter its value with another statement like ``player.description =``
655    |WNL_LATEX| |WNL_HTML| anywhere in your code. This alternative solution
656    might be better if we intended changing the description of the player
657    many times through the game. Since we plan to have only two states, the
658    ``LibraryMessages`` approach will do just fine.
659
660 A final warning: as we explained when extending the standard verb 
661 grammars, you *could* edit the appropriate library file and change all 
662 the default messages, but that wouldn't be a sound practice, because 
663 your library file will probably not be right for the next game. Use of 
664 the ``LibraryMessages`` object is strongly advised.
665
666 If you're typing in the game, you'll probably want to read the brief
667 section on :ref:`compile-as-you-go` prior to performing a test compile.
668 Once everything's correct, it’s time that our hero entered that enticing
669 café.