c7a8ad0494f61745af2ea25de1598e2087a541b3
[ibg.git] / chapters / 07.rst
1 ===============================
2  William Tell: the early years
3 ===============================
4
5 .. highlight:: inform
6
7 .. epigraph::
8
9    | |CENTER| *M was a miser, and hoarded up gold;*
10    | |CENTER| *N was a nobleman, gallant and bold.*
11
12 .. only:: html
13
14    .. image:: /images/picM.png
15       :align: left
16
17 |M|\oving along swiftly, we'll define the first two rooms and populate them
18 with assorted townspeople and street furniture, we'll equip Wilhelm with
19 his trusty bow and quiver of arrows, and we'll introduce Helga the friendly
20 stallholder.
21
22 Defining the street
23 ===================
24
25 This is the street room, the location where the game starts::
26
27    Room     street "A street in Altdorf"
28      with   description [;
29                  print "The narrow street runs north towards the town square.
30                      Local folk are pouring into the town through the gate to the
31                      south, shouting greetings, offering produce for sale,
32                      exchanging news, enquiring with exaggerated disbelief about
33                      the prices of the goods displayed by merchants whose stalls
34                      make progress even more difficult.^";
35                  if (self hasnt visited)
36                      print "^~Stay close to me, son,~ you say,
37                          ~or you'll get lost among all these people.~^";
38             ],
39             n_to below_square,
40             s_to
41                  "The crowd, pressing north towards the square,
42                   makes that impossible.";
43
44 We're using our new ``Room`` class, so there's no need for a :attr:`light`
45 attribute.  The :prop:`n_to` and :prop:`s_to` properties, whose values are
46 an internal ID and a string respectively, are techniques we've used before.
47 The only innovation is that the :prop:`description` property has an
48 embedded routine as its value.
49
50 The first thing in that routine is a ``print`` statement, displaying
51 details of the street surroundings.  If that was all that we wanted to do,
52 we could have supplied those details by making the :prop:`description`
53 value a string; that is, these two examples behave identically::
54
55    description [;
56        print "The narrow street runs north towards the town square.
57            Local folk are pouring into the town through the gate to the
58            south, shouting greetings, offering produce for sale,
59            exchanging news, enquiring with exaggerated disbelief about
60            the prices of the goods displayed by merchants whose stalls
61            make progress even more difficult.^";
62    ],
63
64    description
65        "The narrow street runs north towards the town square.
66         Local folk are pouring into the town through the gate to the
67         south, shouting greetings, offering produce for sale,
68         exchanging news, enquiring with exaggerated disbelief about
69         the prices of the goods displayed by merchants whose stalls
70         make progress even more difficult.",
71
72 However, that *isn't* all that we want to do.  Having presented the basic
73 description, we're going to display that little line of dialogue, where
74 Wilhelm tells his son to be careful.  And we want to do that only once, the
75 very first time that the street's description is displayed.  If the player
76 types LOOK a few times, or moves north and then returns south to the
77 street, we're happy to see the surroundings described -- but we don't want
78 that dialogue again.  This is the pair of statements that makes it happen::
79
80    if (self hasnt visited)
81        print "^~Stay close to me, son,~ you say,
82            ~or you'll get lost among all these people.~^";
83
84 The line of dialogue is produced by the ``print`` statement, the ``print``
85 statement is controlled by the ``if`` statement, and the ``if`` statement
86 is performing the test ``self hasnt visited``.  In detail:
87
88 * :attr:`visited` is an attribute, but not one that you'd normally give to an
89   object yourself.  It's automatically applied to a room object by the
90   interpreter, but only after that room has been visited for the first
91   time by the player.
92
93 * ``hasnt`` (and ``has``) are available for testing whether a given
94   attribute is currently set for a given object.  :samp:`{X} has {Y}` is
95   true if object :samp:`{X}` currently has attribute :samp:`{Y}`, false if
96   it doesn't.  To make the test in reverse, :samp:`{X} hasnt {Y}` is true
97   if object :samp:`{X}` currently does not have attribute :samp:`{Y}`,
98   false if it does.
99
100 * :var:`self`, which we met in the previous chapter, is that useful variable
101   which, within an object, always refers to that object.  Since we're using
102   it in the middle of the ``street`` object, that's what it refers to.
103
104 So, putting it all together, ``self hasnt visited`` is true (and therefore
105 the ``print`` statement is executed) only while the ``street`` object has
106 *not* got a :attr:`visited` attribute.  Because the interpreter
107 automatically gives rooms a :attr:`visited` attribute as soon as the player
108 has been there once, this test will be true only for one turn.  Therefore,
109 the line of dialogue will be displayed only once: the first time the player
110 visits the street, at the very start of the game.
111
112 Although the primary importance of :var:`self` is within class definitions,
113 it can also be convenient to use it simply within an object.  Why didn't we
114 just write this? ::
115
116    if (street hasnt visited)
117        print "^~Stay close to me, son,~ you say,
118            ~or you'll get lost among all these people.~^";
119
120 It's true that the effect is identical, but there are a couple of good
121 reasons for using :var:`self`.  One: it's an aid to understanding your code
122 days or weeks after writing it.
123
124 If you read the line ``if (street hasnt visited)``, you need to think for a
125 moment about which object is being tested; oh, it's this one.  When you
126 read ``if (self hasnt visited)``, you immediately *know* which object we're
127 talking about.
128
129 Another reason is auto-plagiarism.  Many times you'll find that a chunk of
130 code is useful in different situations (say, you want to repeat the
131 mechanics of the street description in another room).  Rather than writing
132 everything from scratch, you'll typically use copy-and-paste to repeat the
133 routine, and then all you have to do is compose the appropriate descriptive
134 strings for the new room.  If you've used :var:`self`, the line ``if (self
135 hasnt visited)`` is still good; if you've written instead ``if (street
136 hasnt visited)``, you'll have to change that as well.  Worse, if you
137 *forget* to change it, the game will still work -- but not in the way you'd
138 intended, and the resulting bug will be quite difficult to track down.
139
140 .. _adding-props:
141
142 Adding some props
143 =================
144
145 The street's description mentions various items -- the gate, the people,
146 etc. -- which ought to exist within the game (albeit only in minimal form)
147 to sustain the illusion of hustle and bustle.  Our ``Prop`` class is ideal
148 for this::
149
150    Prop     "south gate" street
151      with   name 'south' 'southern' 'wooden' 'gate',
152             description "The large wooden gate in the town walls is wide open.";
153
154    Prop     "assorted stalls"
155      with   name 'assorted' 'stalls',
156             description "Food, clothing, mountain gear; the usual stuff.",
157             found_in street below_square,
158      has    pluralname;
159
160    Prop     "produce"
161      with   name 'goods' 'produce' 'food' 'clothing' 'mountain' 'gear' 'stuff',
162             description "Nothing special catches your eye.",
163             found_in street below_square,
164      has    pluralname;
165
166    Prop     "merchants"
167      with   name 'merchant' 'merchants' 'trader' 'traders',
168             description
169                 "A few crooks, but mostly decent traders touting their wares
170                  with raucous overstatement.",
171             found_in street below_square,
172      has    animate pluralname;
173
174    Prop     "local people"
175      with   name 'people' 'folk' 'local' 'crowd',
176             description "Mountain folk, just like yourself.",
177             found_in [; return true; ],
178      has    animate pluralname;
179
180 .. note:: 
181
182    Because these objects are not referenced by other objects, we haven't
183    bothered to given them internal :samp:`{obj_ids}` (though we could have;
184    it wouldn't make any difference).  However, we *have* provided
185    :samp:`{external_names}`, because these are used by the ``Prop`` class's
186    ``print_ret ... (the) self`` statement.
187
188 You'll see a couple of new attributes: :attr:`animate` marks an object as
189 being "alive", while :attr:`pluralname` specifies that its external name is
190 plural rather than singular.  The interpreter uses these attributes to
191 ensure that messages about such objects are grammatical and appropriate
192 (for example, it will now refer to "some merchants" rather than "a
193 merchants").  Because the library handles so many situations automatically,
194 it's hard to be sure exactly what messages players may trigger; the best
195 approach is to play safe and always give an object the relevant set of
196 attributes, even when, as here, they probably won't be needed.
197
198 You'll also see a new :prop:`found_in` property, which specifies the rooms
199 -- and only the rooms; :prop:`found_in` shouldn't be used to place objects
200 inside containers or supporters -- where this object is to appear.  The
201 stalls, for example, can be EXAMINEd both in the street and below the
202 square, so we *could* have created a ``Prop`` object in each room::
203
204    Prop       "assorted stalls" street
205      with     name 'assorted' 'stalls',
206               description "Food, clothing, mountain gear; the usual stuff.",
207       has     pluralname;
208
209    Prop       "assorted stalls" below_square
210      with     name 'assorted' 'stalls',
211               description "Food, clothing, mountain gear; the usual stuff.",
212       has     pluralname;
213
214 but :prop:`found_in` does the same job more neatly -- there's only one
215 object, but it appears in both the ``street`` and ``below_square`` rooms
216 while the player's there.  The local people are even more ubiquitous.  In
217 this case the :prop:`found_in` value is an embedded routine rather than a
218 list of rooms; such a routine would generally test the value of the current
219 location and ``return true`` if it wants to be present here, or
220 :const:`false` if not.  Since we'd like the local people *always* to be
221 present, in every room, we ``return true`` without bothering to examine
222 :var:`location`.  It's as though we'd written any of these, but simpler and
223 less error prone::
224
225    Prop       "local people"
226      with     name 'people' 'folk' 'local' 'crowd',
227               description "Mountain folk, just like yourself.",
228               found_in street below_square south_square mid_square north_square
229                   marketplace,
230       has     animate pluralname;
231
232    Prop       "local people"
233      with     name 'people' 'folk' 'local' 'crowd',
234               description "Mountain folk, just like yourself.",
235               found_in [;
236                   if (location == street       || location == below_square ||
237                       location == south_square || location == mid_square ||
238                       location == north_square || location == marketplace)
239                       return true;
240                   return false;
241               ],
242       has     animate pluralname;
243
244    Prop     "local people"
245      with   name 'people' 'folk' 'local' 'crowd',
246             description "Mountain folk, just like yourself.",
247             found_in [;
248                 if (location == street or below_square or south_square or
249                     mid_square or north_square or marketplace) return true;
250                 return false;
251             ],
252      has    animate pluralname;
253
254 In the second example, you'll see the ``||`` operator, to be read as "or",
255 which we mentioned near the end of "Heidi"; it combines the various
256 :samp:`location == {some_room}` comparisons so that the ``if`` statement is
257 true if *any* of those individual tests is true.  And in the third example
258 we introduce the ``or`` keyword, which is a more succinct way of achieving
259 exactly the same result.
260
261 .. _possessions:
262
263 The player's possessions
264 ========================
265
266 Since our ``Initialise`` routine has already mentioned them, we might as
267 well define Wilhelm's bow and arrows::
268
269    Object   bow "bow"
270      with   name 'bow',
271             description "Your trusty yew bow, strung with flax.",
272             before [;
273                Drop,Give,ThrowAt:
274                  print_ret "You're never without your trusty bow.";
275             ],
276      has    clothing;
277
278    Object   quiver "quiver"
279      with   name 'quiver',
280             description
281                  "Made of goatskin, it usually hangs over your left shoulder.",
282             before [;
283                Drop,Give,ThrowAt:
284                  print_ret "But it was a present from Hedwig, your wife.";
285             ],
286      has    container open clothing;
287
288 Both of these are straightforward objects, with the ``Drop``, ``Give`` and
289 ``ThrowAt`` actions being intercepted to ensure that Wilhelm is never
290 without them.  The :attr:`clothing` attribute makes its first appearance,
291 marking both the quiver and the bow as capable of being worn (as the result
292 of a WEAR BOW command, for instance); you'll remember that our
293 ``Initialise`` routine goes on to add a :attr:`worn` attribute to the
294 quiver.
295
296 An empty quiver is pretty useless, so here's the class used to define
297 Wilhelm's stock of arrows.  This class has some unusual features::
298
299    Class    Arrow
300      with   name 'arrow' 'arrows//p',
301             article "an",
302             plural "arrows",
303             description "Just like all your other arrows -- sharp and true.",
304             before [;
305                Drop,Give,ThrowAt:
306                  print_ret "Your arrows are sharp, and you guard them carefully.";
307             ];
308
309 The classes we've created so far -- ``Room``, ``Prop`` and ``Furniture`` --
310 are intended for objects which behave the same but are otherwise clearly
311 separate.  For example, a table, a bed and a wardrobe would generally have
312 their own individual characteristics -- a name, a description, maybe some
313 specialised properties -- while still inheriting the general behaviour of
314 ``Furniture`` objects.  The arrows aren't like this: not only do they
315 behave the same, but also they are indistinguishable one from another.
316 We're trying for this effect:
317
318 .. code-block:: transcript
319
320    >INVENTORY
321    You are carrying:
322      a quiver (being worn)
323        three arrows
324      a bow
325
326 where the interpreter lumps together our stock of three arrows, rather than
327 listing them individually in this clumsy fashion:
328
329 .. code-block:: transcript
330
331    >INVENTORY
332    You are carrying:
333      a quiver (being worn)
334        an arrow
335        an arrow
336        an arrow
337      a bow
338
339 The interpreter will do this for us if our objects are "indistinguishable",
340 best achieved by making them members of a class which includes both
341 :prop:`name` and :prop:`plural` properties.  We define the actual arrows
342 very simply, like this::
343
344    Arrow "arrow" quiver;
345    Arrow "arrow" quiver;
346    Arrow "arrow" quiver;
347
348 and you can see that we provide only two pieces of information for each
349 ``Arrow`` object: an external name in double quotes ("arrow" in each case)
350 which the interpreter uses when referring to the object, and an initial
351 location (in the quiver).  That's all: no block of properties, no set of
352 attributes, and no internal identifier, because we never need to refer to
353 the individual ``Arrow`` objects within the game.
354
355 The name property of the class definition has an odd-looking dictionary
356 word::
357
358    name 'arrow' 'arrows//p',
359
360 The word ``'arrow'`` refers to a single arrow.  So also would the word
361 ``'arrows'``, unless we specifically tell the interpreter that it's a
362 plural reference.  That ``//p`` marks ``'arrows'`` as being a potential
363 reference to more than one object at once, thus enabling players to type
364 TAKE ARROWS and thereby pick up as many arrows as happened to be available
365 (without it, TAKE ARROWS would have picked up one at random).
366
367 There are two other properties not seen previously::
368
369    article "an",
370    plural "arrows",
371
372 The :prop:`article` property lets you define the object's indefinite
373 article -- usually something like "a", "an" or "some" -- instead of letting
374 the library assign one automatically.  It's a belt-and-braces (OK,
375 belt-and-suspenders) precaution: because "arrow" starts with a vowel, we
376 need to display "an arrow" not "a arrow".  Most interpreters automatically
377 get this right, but just to be on the safe side, we explicitly define the
378 appropriate word.  And the :prop:`plural` property defines the word to be
379 used when lumping several of these objects together, as in the "three
380 arrows" inventory listing.  The interpreter can't just automatically slap
381 an "s" on the end; the plural of "slice of cake", for example, isn't "slice
382 of cakes".
383
384 Moving further along the street
385 ===============================
386
387 As Wilhelm moves north towards the square, he comes to this room::
388
389    Room     below_square "Further along the street"
390      with   description
391                 "People are still pushing and shoving their way from the southern
392                  gate towards the town square, just a little further north.
393                  You recognise the owner of a fruit and vegetable stall.",
394             n_to south_square,
395             s_to street;
396
397 No surprises there, nor in most of the supporting scenery objects. ::
398
399    Furniture   stall "fruit and vegetable stall" below_square
400      with name 'fruit' 'veg' 'vegetable' 'stall' 'table',
401            description
402                "It's really only a small table, with a big heap of potatoes,
403                 some carrots and turnips, and a few apples.",
404            before [; Search: <<Examine self>>; ],
405      has   scenery;
406
407    Prop     "potatoes" below_square
408      with   name 'potato' 'potatoes' 'spuds',
409             description
410                 "Must be a particularly early variety... by some 300 years!",
411      has    pluralname;
412
413    Prop     "fruit and vegetables" below_square
414      with   name 'carrot' 'carrots' 'turnip' 'turnips' 'apples' 'vegetables',
415             description "Fine locally grown produce.",
416      has    pluralname;
417
418 The only new thing here is the :prop:`before` property of the fruit'n'veg
419 stall.  The stall's description -- lots of items on a table -- may suggest
420 to players that they can SEARCH through the produce, maybe finding a lucky
421 beetroot or something else interesting.  No such luck -- and we might as
422 well trap the attempt.
423
424 Having intercepted a ``Search`` action, our plan is to respond with the
425 stall's description, as though the player has typed EXAMINE THE STALL.
426 There isn't an easy way for us to stealthily slide those literal words into
427 the interpreter, but we *can* simulate the effect which they'd cause: an
428 action of ``Examine`` applied to the object stall.  This rather cryptic
429 statement does the job::
430
431    <Examine stall>;
432
433 Having diverted the ``Search`` action into an ``Examine`` action, we must
434 tell the interpreter that it doesn't need to do anything else, because
435 we've handled the action ourselves.  We've done that before -- using
436 ``return true`` -- and so a first stab at the :prop:`before` action looks
437 like this::
438
439    before [; Search: <Examine stall>; return true; ],
440
441 The two-statement sequence ``<...>; return true`` is so common that there's
442 a single statement shortcut: ``<<...>>``.  Also, for exactly the same
443 reason as before, our code is clearer if we use :var:`self` instead of
444 ``stall``.  So this is how the property finally stands::
445
446    before [; Search: <<Examine self>>; ],
447
448 A couple of final observations before we leave this topic.  The example
449 here is of an action (``Examine``) applied to an object (:var:`self`,
450 though ``stall`` or :var:`noun` would also work at this point).  You can
451 also use the ``<...>`` and ``<<...>>`` statements for actions which affect
452 no objects::
453
454    <<Look>>;
455
456 (representing the command LOOK), or which affect two.  For example, the
457 command PUT THE BIRD IN THE NEST can be simulated with this statement::
458
459    <<Insert bird nest>>;
460
461 Introducing Helga
462 =================
463
464 One of the trickiest aspects of designing a good game is to provide
465 satisfying interaction with other characters.  It's hard enough to code
466 inanimate objects which provoke appropriate responses to whatever actions
467 the player character (PC) might attempt.  That all gets much worse once
468 those "other objects" are living creatures -- non-player characters (NPCs)
469 -- with, supposedly, minds of their own.  A good NPC might move around
470 independently, perform actions with a purpose, initiate conversations,
471 respond to what you say and do (and even to what you *don't* say or do); it
472 can be a real nightmare.
473
474 But not here: we've kept our three NPCs -- Helga, Walter and the vogt -- as
475 simple as possible.  Nevertheless, we can establish some fundamental
476 principles; here's the class upon which we base our NPCs::
477
478    Class    NPC
479      with   life [;
480                Answer,Ask,Order,Tell:
481                  print_ret "Just use T[ALK] [TO ", (the) self, "].";
482             ],
483      has    animate;
484
485 The most important thing here is the :attr:`animate` attribute -- that's
486 what defines an object as an NPC, and causes the interpreter to treat it a
487 little differently -- for example, TAKE HELGA results in "I don't suppose
488 Helga would care for that".
489
490 The :attr:`animate` attribute also brings into play nine extra actions
491 which can be applied only to animate objects: ``Answer``, ``Ask``,
492 ``Order`` and ``Tell`` are all associated with speech, and ``Attack``,
493 ``Kiss``, ``Show``, ``ThrowAt`` and ``WakeOther`` are associated with
494 non-verbal interaction.  Additionally, a new :prop:`life` property -- very
495 similar to :prop:`before` -- can be defined to intercept them.  Here we use
496 it to trap speech-related commands such as ASK HELGA ABOUT APPLE and TELL
497 WALTER ABOUT BABIES, telling players that in this game we've implemented
498 only a simpler TALK verb (which we describe in :ref:`verbs`).
499
500 Based on the NPC class we've created, here's Helga::
501
502    NPC      stallholder "Helga" below_square
503      with   name 'stallholder' 'greengrocer' 'monger' 'shopkeeper' 'merchant'
504                  'owner' 'Helga' 'dress' 'scarf' 'headscarf',
505             description
506                  "Helga is a plump, cheerful woman,
507                    concealed beneath a shapeless dress and a spotted headscarf.",
508             initial [;
509                  print "Helga pauses from sorting potatoes
510                       to give you a cheery wave.^";
511                  if (location hasnt visited) {
512                       move apple to player;
513                       print "^~Hello, Wilhelm, it's a fine day for trade! Is this
514                           young Walter? My, how he's grown. Here's an apple for him
515                           -- tell him to mind that scabby part, but the rest's good
516                           enough. How's Frau Tell? Give her my best wishes.~^";
517                  }
518             ],
519             times_spoken_to 0,         ! for counting the conversation topics
520             life [;
521                Talk:
522                  self.times_spoken_to = self.times_spoken_to + 1;
523                  switch (self.times_spoken_to) {
524                    1: score = score + 1;
525                       print_ret "You warmly thank Helga for the apple.";
526                    2: print_ret "~See you again soon.~";
527                    default:
528                       return false;
529                  }
530             ],
531      has    female proper;
532
533 The new attributes are :attr:`female` -- because we want the interpreter to
534 refer to Helga with the appropriate pronouns -- and :attr:`proper`.  The
535 latter signifies that this object's external name is a proper noun, and so
536 references to it should not be preceded by "a" or "the": you wouldn't want
537 to display "You can see a Helga here" or "I don't suppose the Helga would
538 care for that".  You may notice the library variable :var:`score` being
539 incremented.  This variable holds the number of points that the player has
540 scored; when it changes like this, the interpreter tells the player that
541 "Your score has just gone up by one point".
542
543 There are also :prop:`life` and :prop:`times_spoken_to` properties (which
544 we'll talk about in :doc:`09`) and an :prop:`initial` property.
545
546 :prop:`initial` is used when the interpreter is describing a room and listing
547 the objects initial you can see there.  If we *didn't* define it, you'd get
548 this:
549
550 .. code-block:: transcript
551
552    Further along the street
553    People are still pushing and shoving their way from the southern gate towards
554    the town square, just a little further north.  You recognise the owner of a fruit
555    and vegetable stall.
556
557    You can see Helga here.
558
559    >
560
561 but we want to introduce Helga in a more interactive manner, and that's
562 what the :prop:`initial` property is for: it replaces the standard "You can see
563 *object* here" with a tailored message of your own design.  The value of an
564 :prop:`initial` property can be either a string which is to be displayed or, as
565 here, an embedded routine.  This one is pretty similar to the
566 :prop:`description` property that we defined for the street: something that's
567 *always* printed (Helga pauses...) and something that's printed only on the
568 first occasion ("Hello, Wilhelm, it's a fine day... "):
569
570 .. code-block:: transcript
571
572    Further along the street
573    People are still pushing and shoving their way from the southern gate towards
574    the town square, just a little further north. You recognise the owner of a fruit
575    and vegetable stall.
576
577    Helga pauses from sorting potatoes to give you a cheery wave.
578
579    "Hello, Wilhelm, it's a fine day for trade! Is this young Walter? My, how he's
580    grown. Here's an apple for him -- tell him to mind that scabby part, but the
581    rest's good enough. How's Frau Tell? Give her my best wishes."
582
583    >
584
585 But it's not quite the same as the street's description routine.  First, we
586 need a slightly different ``if`` test: ``self hasnt visited`` works fine
587 for a room object, but this routine is part of an object *in* a room;
588 instead we could use either ``below_square hasnt visited`` or (better)
589 ``location hasnt visited`` -- since :var:`location` is the library variable
590 that refers to the room where the player currently is.  And second, some
591 curly braces ``{...}`` have appeared: why?
592
593 On Wilhelm's first visit to this room, we need to do two things:
594
595 * ensure that Wilhelm is in possession of an apple, because that's
596   mentioned when we...
597
598 * display Helga's cheery greeting.
599
600 The ``move`` statement does the first of those, and the ``print`` statement
601 does the second.  And both statements need to be controlled by the ``if``
602 statement.  So far, we've used an ``if`` statement twice, in both cases to
603 control a single following statement. ::
604
605   if (nest in branch) deadflag = 2;
606
607   if (self hasnt visited)
608       print "^~Stay close to me, son,~ you say,
609           ~or you'll get lost among all these people.~^";
610
611 That's what an ``if`` does -- it controls whether the following statement
612 is executed or not.  So how can we control two statements at once?  Well,
613 we *could* write two ``if`` statements::
614
615   if (location hasnt visited)
616       move apple to player;
617   if (location hasnt visited)
618       print "^~Hello, Wilhelm, it's a fine day for trade! Is this
619           young Walter? My, how he's grown. Here's an apple for him
620           -- tell him to mind that scabby part, but the rest's good
621           enough. How's Frau Tell? Give her my best wishes.~^";
622
623 but that's unbearably clumsy; instead, we use the braces to group the
624 ``move`` and ``print`` statement into a :term:`statement block` (sometimes
625 known as a code block) which counts as a single statement for the purposes
626 of control by the ``if`` statement. ::
627
628   if (location hasnt visited) {
629       move apple to player;
630       print "^~Hello, Wilhelm, it's a fine day for trade! Is this
631           young Walter? My, how he's grown. Here's an apple for him
632           -- tell him to mind that scabby part, but the rest's good
633           enough. How's Frau Tell? Give her my best wishes.~^";
634   }
635
636 A statement block can contain one, two, ten, a hundred statements; it
637 doesn't matter -- they're all treated as one unit by ``if`` (and by
638 ``objectloop``, which we meet later, and by ``do``, ``for`` and ``while``,
639 all of them loop statements that we don't encounter in this guide).
640
641 .. note::
642
643    The exact positioning of the braces is a matter of personal choice.  We
644    use this style::
645
646       if (condition) {
647           statement;
648           statement;
649           ...
650       }
651
652    but other designers have their own preferences, including::
653
654       if (condition) {
655           statement;
656           statement;
657           ...
658           }
659
660       if (condition)
661       {   statement;
662           statement;
663           ...
664       }
665
666       if (condition)
667           {
668           statement;
669           statement;
670           ...
671           }
672
673 Although we've not yet needed to use it, now would probably be a good time
674 to mention the ``else`` extension to the ``if`` statement.  Sometimes we
675 want to execute one statement block if a certain condition is true, and a
676 different statement block if it's not true.  Again, we *could* write two
677 ``if`` statements::
678
679    if (location has visited) {
680        statement;
681        statement;
682        ...
683    }
684    if (location hasnt visited) {
685        statement;
686        statement;
687        ...
688    };
689
690 but that's hardly an elegant approach; an ``else`` clause does the job more
691 neatly::
692
693    if (location has visited) {
694        statement;
695        statement;
696        ...
697    }
698    else {
699        statement;
700        statement;
701        ...
702    };
703
704 We've done a lot of scene-setting, but the real action is still to come.
705 Next, it's time to define the town square, and create a confrontation
706 between Wilhelm and the vogt's soldiers.  (But first, see again
707 :ref:`compile-as-you-go` if you're typing in the game as you read through
708 the guide.)