1 ==============================
2 Heidi: our first Inform game
3 ==============================
7 | |CENTER| *E was an esquire, with pride on his brow;*
8 | |CENTER| *F was a farmer, and followed the plough.*
12 .. image:: /images/picE.png
15 |E|\ach of the three games in this guide is created step by step; you'll
16 get most benefit (especially to begin with) if you take an active part,
17 typing in the source code on your computer. Our first game, described in
18 this chapter and the two which follow, tells this sentimental little story:
20 "Heidi lives in a tiny cottage deep in the forest. One sunny day,
21 standing before the cottage, she hears the frenzied tweeting of baby
22 bird; its nest has fallen from the tall tree in the clearing! Heidi
23 puts the bird into the nest, and then climbs the tree to place the nest
26 It's a very simple tale, but even so we'll cover quite a lot of ground
27 before we have a finished Inform game. We'll get there in stages, first
28 making a very rough approximation of the story, and then successively
29 refining the details until it's good enough for an initial attempt (there's
30 time later for more advanced stuff).
32 Creating a basic source file
33 ============================
35 The first task is to create an Inform source file template. Every game
36 that we design will start out like this. Follow these steps:
38 #. Create an ``Inform\Games\Heidi`` folder (maybe by copying
39 ``Inform\Games\MyGame1``).
43 In this guide, we use the PC convention of placing a backslash
44 between folder names. On a Macintosh, use a regular slash:
45 ``Inform/Games/Heidi``.
47 #. In that folder, use your text editor to create this source file
50 .. include:: /config/typethis.rst
52 .. code-block:: inform
55 !============================================================================
56 Constant Story "Heidi";
58 "^A simple Inform example
59 ^by Roger Firth and Sonja Kesserich.^";
64 !============================================================================
67 !============================================================================
68 ! Entry point routines
72 !============================================================================
73 ! Standard and extended grammar
77 !============================================================================
79 Soon, we'll explain what this means. For now, just type it all in,
80 paying particular attention to those seven semicolons, and ensuring that
81 the double quotes "..." always come in pairs. The first line beginning
82 with "``!%``" is special, and we'll talk about it in a moment; the
83 remaining exclamation mark lines, on the other hand, are purely
84 decorative; they just make the file's structure a little easier to
87 Ensure the file is named ``Heidi.inf``, rather than ``Heidi.txt`` or
90 Remember that, throughout this guide, we place the "``TYPE``" symbol
91 alongside pieces of code that we recommend you to type into your own
92 game files as you read through the examples (which, conversely, means
93 that you *don't* need to type the unmarked pieces of code). You'll
94 learn Inform more quickly by trying it for yourself, rather than just
95 taking our word for how things work.
97 #. In the same folder, use your text editor to create the compilation
98 support file ``Heidi.bat`` (on a PC):
100 .. include:: /config/typethis.rst
104 ..\..\Lib\Base\Inform Heidi
105 +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib | more
107 pause "at end of compilation"
109 or ``Heidi.command`` (on a Macintosh):
111 .. include:: /config/typethis.rst
115 cd ~/Inform/Games/Heidi/
117 ../../Lib/Base/inform30_macosx Heidi
118 +include_path=./,../../Lib/Base,../../Lib/Contrib
120 Remember that there's just one space between "``Heidi``" and
123 Type in the file from scratch, or copy and edit ``MyGame1.bat`` (or
124 ``MyGame1.command``). At this point, you should have a ``Heidi`` folder
125 containing two files: ``Heidi.inf`` and either ``Heidi.bat`` or
128 #. Compile the source file ``Heidi.inf``; refer back to
129 :ref:`inform-windows` or :ref:`inform-apple` for guidance. If the
130 compilation works, a story file ``Heidi.z5`` appears in the folder. If
131 the compilation *doesn't* work, you've probably made a typing mistake;
132 check everything until you find it.
134 #. You can run the story file in your Inform interpreter; you should see
135 this (except that the Serial number will be different -- it's based on
138 .. code-block:: transcript
141 A simple Inform example
142 by Roger Firth and Sonja Kesserich.
143 Release 1 / Serial number 040804 / Inform v6.30 Library 6/11 SD
146 It is pitch dark, and you can't see a thing.
150 When you get that far, your template source file is correct. Let's explain
153 Understanding the source file
154 =============================
156 Although we've got a certain amount of freedom of expression, source files
157 tend to conform to a standard overall structure: these lines at the start,
158 that material next, those pieces coming at the end, and so on. What we're
159 doing here is mapping out a structure that suits us, giving ourselves a
160 clear framework onto which the elements of the game can be fitted. Having
161 a clear (albeit sparse) map at the start will help us to keep things
162 organised as the game evolves. We can infer several Inform rules just by
163 looking at the source file.
165 .. Generated by autoindex
169 * If the *very first line* (or lines) of the source file begin with the
170 characters "``!%``", then the compiler treats what follows on those lines
171 as control instructions to itself rather than as part of the game's
172 source. The instructions most commonly placed here are compiler
173 switches, a way of controlling detailed aspects of how the compiler
174 operates. These particular switches, two of many, are turning on
175 :term:`Strict mode`, which makes the game less likely to misbehave when
176 being played, and :term:`Debug mode`, which provides some extra commands
177 which can be helpful when tracking down problems.
181 Actually, the :option:`-S` is redundant, since Strict mode is already
182 on by default. We include it here as a reminder that (a) to turn
183 Strict mode *off*, you change this setting to :option:`-~S`, and (b)
184 alphabetic case matters here: :option:`-s` causes a display of
185 compiler statistics (and :option:`-~s` does nothing at all).
187 * Otherwise, when the compiler comes across an exclamation mark, it ignores
188 the rest of the line. If the ``!`` is at the start of a line, the whole
189 line is ignored; if the ``!`` is halfway along a line, the compiler takes
190 note of the first half, and then ignores the exclamation mark and
191 everything after it on that line. We call material following an
192 exclamation mark, not seen by anybody else, a :term:`comment`; it's often
193 a remark that we write to remind ourselves of how something works or why
194 we tackled a problem in a particular way. There's nothing special about
195 those equals signs: they just produce clear lines across the page.
197 It's always a good idea to comment code as you write it, for later it
198 will help you to understand what was going on at a particular spot.
199 Although it all seems clear in your head when you first write it, in a
200 few months you may suspect that a totally alien mind must have produced
201 that senseless gibberish.
203 By the way, the compiler *doesn't* give special treatment to exclamation
204 marks in quoted text: ``!`` within quotes "..." is treated as a normal
205 character. On this line, the first ``!`` is part of the sequence (or
206 :term:`string`) of characters to be displayed:
208 .. code-block:: inform
210 print "Hello world!"; ! <- is the start of this comment
212 * The compiler ignores blank lines, and treats lots of space like a single
213 space (except when the spaces are part of a character string). So, these
214 two rules tell us that we *could* have typed the source file like this:
216 .. code-block:: inform
218 Constant Story "Heidi";
220 "^A simple Inform example^by Roger Firth and Sonja Kesserich.^";
221 Include "Parser";Include "VerbLib";
225 We didn't type it that way because, though shorter, it's much harder to
226 read. When designing a game, you'll spend a lot of time studying what
227 you've typed, so it's worthwhile taking a bit of care to make it as
228 readable as possible.
230 * Every game should have the :term:`constant` definitions for ``Story``
231 (the game's name) and ``Headline`` (typically, information on the game's
232 theme, copyright, authorship and so on). These two :term:`string`
233 values, along with a release number and date, and details of the
234 compiler, compose the :term:`banner` which is displayed at the start of
237 * Every game needs the three lines which ``Include`` the standard library
238 files -- that is, they merge those files' contents into your source file:
240 .. code-block:: inform
247 They always have to be in this order, with ``Parser`` and ``VerbLib``
248 near the start of the file, and ``Grammar`` near the end.
250 * Every game needs to define an ``Initialise`` routine (note the British
253 .. code-block:: inform
257 The :term:`routine` that we've defined here doesn't do anything useful,
258 but it still needs to be present. Later, we'll come back to
259 ``Initialise`` and explain what a routine is and why we need this one.
261 * You'll notice that each of the items mentioned in the previous three
262 rules ends with a semicolon. Inform is very fussy about its punctuation,
263 and gets really upset if you forget a terminating semicolon. In fact,
264 the compiler just keeps reading your source file until it finds one;
265 that's why we were able to take three lines to define the ``Headline``
268 .. code-block:: inform
271 "^A simple Inform example
272 ^by Roger Firth and Sonja Kesserich.^";
274 Just to repeat what we said earlier: every game that you design will start
275 out from a basic source file like this (in fact, it might be sensible to
276 keep a copy of this template file in a safe place, as a starting point for
277 future games). Think of this stuff as the basic preparation which you'll
278 quickly come to take for granted, much as a landscape artist always begins
279 by sizing the canvas before starting to paint. So, now that we've taken a
280 quick tour of Inform's general needs, we can start thinking about what this
281 particular game requires.
283 Defining the game's locations
284 =============================
286 A good starting point in any game is to think about the locations which are
287 involved: this sketch map shows the four that we'll use:
289 .. image:: /images/heidi1.*
292 In IF, we talk about each of these locations as a :term:`room`, even though
293 in this example none of them has four walls. So let's use Inform to define
294 those rooms. Here's a first attempt:
296 .. code-block:: inform
298 Object "In front of a cottage"
300 "You stand outside a cottage. The forest stretches east.",
303 Object "Deep in the forest"
305 "Through the dense foliage, you glimpse a building to the west.
306 A track heads to the northeast.",
309 Object "A forest clearing"
311 "A tall sycamore stands in the middle of this clearing.
312 The path winds southwest through the trees.",
315 Object "At the top of the tree"
316 with description "You cling precariously to the trunk.",
319 Again, we can infer some general principles from these four examples:
321 * A room definition starts with the word ``Object`` and ends, about four
322 lines later, with a semicolon. Each of the components that appears in
323 your game -- not only the rooms, but also the people, the things that you
324 see and touch, intangibles like a sound, a smell, a gust of wind -- is
325 defined in this way; think of an "object" simply as the general term for
326 the myriad thingies which together comprise the model world which your
329 * The phrase in double quotes following the word ``Object`` is the name
330 that the interpreter uses to provide the player character with a list of
331 the objects around her: where she is, what she can see, what she's
336 We're using the word "player" to mean both the person who is playing
337 the game, and the principal protagonist (often known as the player
338 character) within the game itself. Since the latter -- Heidi -- is
339 female, we'll refer to the player as "she" while discussing this game.
341 * A keyword ``with`` follows, which simply tells the compiler what to
344 .. Generated by autoindex
346 pair: description; library property
348 * The word :prop:`description`, introducing another piece of text which
349 gives more detail about the object: in the case of a room, it's the
350 appearance of the surrounding environment when the player character is in
351 that room. The textual description is given in double quotes, and is
354 * Near the end, the keyword ``has`` appears, which again tells the compiler
355 to expect a certain kind of information.
357 .. Generated by autoindex
359 pair: light; library attribute
361 * The word :attr:`light` says that this object is a source of illumination,
362 and that therefore the player character can see what's happening here.
363 There has to be at least one light source in every room (unless you want
364 the player to be told that "It's pitch dark and you can't see a thing");
365 most commonly, that light source is the room itself.
367 A smidgeon of background may help set this into context (there's more in
368 the next chapter). An object can have both :term:`properties` (introduced
369 by the keyword ``with``) and :term:`attributes` (written after the word
370 ``has``). A property has both a name (like :prop:`description`) and a
371 value (like the character string "``You stand outside a cottage. The
372 forest stretches east.``"); an attribute has merely a name.
374 In a little while, when you play this game, you'll observe that it starts
377 .. code-block:: transcript
379 In front of a cottage
380 You stand outside a cottage. The forest stretches east.
382 And here you can see how the room's name (``In front of a cottage``) and
383 description (``You stand outside a cottage. The forest stretches east.``)
389 We said that this was a first attempt at defining the rooms; it's fine as
390 far as it goes, but a few bits of information are missing. If you look at
391 the game's sketch map, you can see how the rooms are intended to be
392 connected; from "Deep in the forest", for example, the player character
393 should be able to move west towards the cottage, or northeast to the
394 clearing. Now, although our descriptions mention or imply these available
395 routes, we also need to explicitly add them to the room definitions in a
396 form that the game itself can make sense of. Like this:
398 .. code-block:: inform
400 Object before_cottage "In front of a cottage"
402 "You stand outside a cottage. The forest stretches east.",
406 Object forest "Deep in the forest"
408 "Through the dense foliage, you glimpse a building to the west.
409 A track heads to the northeast.",
414 Object clearing "A forest clearing"
416 "A tall sycamore stands in the middle of this clearing.
417 The path winds southwest through the trees.",
422 Object top_of_tree "At the top of the tree"
423 with description "You cling precariously to the trunk.",
427 We've made two changes to the room objects.
429 * First, between the word ``Object`` and the object's name in double
430 quotes, we've inserted a different type of name: a private, internal
431 identification, never seen by the player; one that we can use *within*
432 the source file when one object needs to refer to another object. For
433 example, the first room is identified as ``before_cottage``, and the
434 second as ``forest``.
436 Unlike the external name contained in double quotes, the internal
437 identifier has to be a single word -- that is, without spaces. To aid
438 readability, we often use an underscore character to act as sort of
439 pseudo-space: ``before_cottage`` is a bit clearer than ``beforecottage``.
441 * Second, we've added lines after the object descriptions which use those
442 internal identifiers to show how the rooms are connected; one line for
443 each connection. The ``before_cottage`` object has this additional
448 This means that a player standing in front of the cottage can type GO
449 EAST (or EAST, or just E), and the game will transport her to the room
450 whose internal identification is ``forest``. If she tries to move in any
451 other direction from this room, she'll be told "You can't go that way".
453 What we've just defined is a *one-way* easterly connection:
454 ``before_cottage`` → ``forest``. The forest object has two additional
460 The first line defines a westerly connection ``forest`` →
461 ``before_cottage`` (thus enabling the player character to return to the
462 cottage), and the second defines a connection ``forest`` → ``clearing``
463 which heads off to the northeast.
465 .. Generated by autoindex
467 pair: d_to; library property
468 pair: e_to; library property
469 pair: in_to; library property
470 pair: n_to; library property
471 pair: ne_to; library property
472 pair: nw_to; library property
473 pair: out_to; library property
474 pair: s_to; library property
475 pair: se_to; library property
476 pair: sw_to; library property
477 pair: u_to; library property
478 pair: w_to; library property
480 Inform provides for eight "horizontal" connections (:prop:`n_to`,
481 :prop:`ne_to`, :prop:`e_to`, :prop:`se_to`, :prop:`s_to`, :prop:`sw_to`,
482 :prop:`w_to`, :prop:`nw_to`) two "vertical" ones (:prop:`u_to`,
483 :prop:`d_to`) and two specials :prop:`in_to`, and :prop:`out_to`. You'll
484 see some of these used for the remaining inter-room connections.
486 There's one last detail to attend to before we can test what we've done.
487 You'll recollect that our story begins with Heidi standing in front of her
488 cottage. We need to tell the interpreter that ``before_cottage`` is the
489 room where the game starts, and we do this in the ``Initialise`` routine::
491 [ Initialise; location = before_cottage; ];
493 :var:`location` is a :term:`variable`, part of the library, which tells the
494 interpreter in which room the player character currently is. Here, we're
495 saying that, at the start of the game, the player character is in the
496 ``before_cottage`` room.
498 Now we can add what we've done to the ``Heidi.inf`` source file template.
499 At this stage, you should study the four room definitions, comparing them
500 with the sketch map until you're comfortable that you understand how to
501 create simple rooms and define the connections between them.
503 .. include:: /config/typethis.rst
505 .. code-block:: inform
507 !============================================================================
508 Constant Story "Heidi";
510 "^A simple Inform example
511 ^by Roger Firth and Sonja Kesserich.^";
516 !============================================================================
519 Object before_cottage "In front of a cottage"
521 "You stand outside a cottage. The forest stretches east.",
525 Object forest "Deep in the forest"
527 "Through the dense foliage, you glimpse a building to the west.
528 A track heads to the northeast.",
533 Object clearing "A forest clearing"
535 "A tall sycamore stands in the middle of this clearing.
536 The path winds southwest through the trees.",
541 Object top_of_tree "At the top of the tree"
542 with description "You cling precariously to the trunk.",
546 !============================================================================
547 ! Entry point routines
549 [ Initialise; location = before_cottage; ];
551 !============================================================================
552 ! Standard and extended grammar
556 !============================================================================
558 Type this in, as always taking great care with the punctuation -- watch
559 those commas and semicolons. Compile it, and fix any mistakes which the
560 compiler reports. You can then play the game in its current state.
561 Admittedly, you can't do very much, but you should be able to move freely
562 among the four rooms that you've defined.
566 In order to minimise the amount of typing that you have to do, the
567 descriptive text in this game has been kept as short as possible. In a
568 real game, you would typically provide more interesting descriptions
571 Adding the bird and the nest
572 ============================
574 Given what we said earlier, you won't be surprised to hear that both the
575 bird and its nest are Inform objects. We'll start their definitions like
578 .. code-block:: inform
580 Object bird "baby bird"
581 with description "Too young to fly, the nestling tweets helplessly.",
584 Object nest "bird's nest"
585 with description "The nest is carefully woven of twigs and moss.",
588 You can see that these definitions have exactly the same format as the
589 rooms we defined previously: a one-word internal identifier (``bird``,
590 ``nest``), and a word or phrase naming the object for the player's benefit
591 (``baby bird``, ``bird's nest``). They both have some descriptive detail:
592 for a room this is printed when the player first enters, or when she types
593 LOOK; for other objects it's printed when she EXAMINEs that object. What
594 they *don't* have are connections (:prop:`e_to`, :prop:`w_to`, etc. apply
595 only to rooms) or :attr:`light` (it's not necessary -- the rooms ensure
596 that light is available).
598 When the game is running, the player will want to refer to these two
599 objects, saying for instance EXAMINE THE BABY BIRD or PICK UP THE NEST.
600 For this to work reliably, we need to specify the word (or words) which
601 relate to each object. Our aim here is flexibility: providing a choice of
602 relevant vocabulary so that the player can use whatever term seems
603 appropriate to her, with a good chance of it being understood. We add a
604 line to each definition:
606 .. include:: /config/typethis.rst
608 .. code-block:: inform
610 Object bird "baby bird"
611 with description "Too young to fly, the nestling tweets helplessly.",
612 name 'baby' 'bird' 'nestling',
615 Object nest "bird's nest"
616 with description "The nest is carefully woven of twigs and moss.",
617 name 'bird^s' 'nest' 'twigs' 'moss',
620 The :prop:`name` introduces a list in single quotes '...'. We call each of
621 those quoted things a :term:`dictionary word`, and we do mean "word", not
622 "phrase" (``'baby'``\ ``'bird'`` rather than ``'baby bird'``); you can't
623 uses spaces, commas or periods *in* dictionary words, though there's a
624 space *between* each one, and the whole list ends with a comma. The idea
625 is that the interpreter decides which object a player is talking about by
626 matching what she types against the full set of all dictionary words. If
627 the player mentions BIRD, or BABY BIRD, or NESTLING, it's the ``baby bird``
628 that she means; if she mentions NEST, BIRD'S NEST or MOSS, it's the
629 ``bird's nest``. And if she types NEST BABY or BIRD TWIGS, the interpreter
630 will politely say that it doesn't understand what on earth she's talking
638 You'll notice the use of ``'bird^s'`` to define the dictionary word
639 BIRD'S; this oddity is necessary because the compiler expects the single
640 quotes in the list always to come in pairs -- one at the start of the
641 dictionary word, and one at the end. If we had typed ``'bird's'`` then
642 the compiler would find the opening quote, the four letters ``b``,
643 ``i``, ``r`` and ``d``, and what looks like the closing quote. So far
644 so good; it's read the word BIRD and now expects a space before the next
645 opening quote... but instead finds ``s'`` which makes no sense. In
646 cases like this we must use the circumflex ``^`` to *represent* the
647 apostrophe, and the compiler then treats ``bird's`` as a dictionary
650 You may be wondering why we need a list of :prop:`name` words for the bird
651 and its nest, yet we didn't when we defined the rooms? It's because the
652 player can't interact with a room in the same way as with other objects;
653 for example, she doesn't need to say EXAMINE THE FOREST -- just being there
654 and typing LOOK is sufficient.
656 .. Generated by autoindex
658 pair: container; library attribute
659 pair: open; library attribute
661 The bird's definition is complete, but there's an additional complexity
662 with the nest: we need to be able to put the bird into it. We do this by
663 labelling the nest as a :attr:`container` -- able to hold other objects --
664 so that the player can type PUT (or INSERT) BIRD IN (or INTO) NEST.
665 Furthermore, we label it as :attr:`open`; this prevents the interpreter
666 from asking us to open it before putting in the bird.
668 .. code-block:: inform
670 Object nest "bird's nest"
671 with description "The nest is carefully woven of twigs and moss.",
672 name 'bird^s' 'nest' 'twigs' 'moss',
675 Both objects are now defined, and we can incorporate them into the game.
676 To do this, we need to choose the locations where the player will find
677 them. Let's say that the bird is found in the forest, while the nest is in
678 the clearing. This is how we set this up:
680 .. code-block:: inform
682 Object bird "baby bird" forest
683 with description "Too young to fly, the nestling tweets helplessly.",
684 name 'baby' 'bird' 'nestling',
687 Object nest "bird's nest" clearing
688 with description "The nest is carefully woven of twigs and moss.",
689 name 'bird^s' 'nest' 'twigs' 'moss',
692 Read that first line as: "Here's the definition of an object which is
693 identified within this file as ``bird``, which is known to the player as
694 ``baby bird``, and which is initially located inside the object identified
695 within this file as ``forest``."
697 Where in the source file do these new objects fit? Well, anywhere really,
698 but you'll find it convenient to insert them following the rooms where
699 they're found. This means adding the bird just after the forest, and the
700 nest just after the clearing. Here's the middle piece of the source file:
702 .. code-block:: inform
704 !============================================================================
707 Object before_cottage "In front of a cottage"
709 "You stand outside a cottage. The forest stretches east.",
713 Object forest "Deep in the forest"
715 "Through the dense foliage, you glimpse a building to the west.
716 A track heads to the northeast.",
721 Object bird "baby bird" forest
722 with description "Too young to fly, the nestling tweets helplessly.",
723 name 'baby' 'bird' 'nestling',
726 Object clearing "A forest clearing"
728 "A tall sycamore stands in the middle of this clearing.
729 The path winds southwest through the trees.",
734 Object nest "bird's nest" clearing
735 with description "The nest is carefully woven of twigs and moss.",
736 name 'bird^s' 'nest' 'twigs' 'moss',
739 Object top_of_tree "At the top of the tree"
740 with description "You cling precariously to the trunk.",
744 !============================================================================
746 Make those changes, recompile the game, play it and you'll see this:
748 .. code-block:: transcript
751 Through the dense foliage, you glimpse a building to the west. A track heads
754 You can see a baby bird here.
758 Adding the tree and the branch
759 ==============================
761 The description of the clearing mentions a tall sycamore tree, up which the
762 player character supposedly "climbs". We'd better define it:
764 .. include:: /config/typethis.rst
766 .. code-block:: inform
768 Object tree "tall sycamore tree" clearing
770 "Standing proud in the middle of the clearing,
771 the stout tree looks easy to climb.",
772 name 'tall' 'sycamore' 'tree' 'stout' 'proud',
775 Everything there should be familiar, apart from that :attr:`scenery` at the
776 end. We've already mentioned the tree in the description of the forest
777 clearing, so we don't want the interpreter adding "You can see a tall
778 sycamore tree here" afterwards, as it does for the bird and the nest. By
779 labelling the tree as :attr:`scenery` we suppress that, and also prevent it
780 from being picked up by the player character. One final object: the branch
781 at the top of the tree. Again, not many surprises in this definition:
783 .. include:: /config/typethis.rst
785 .. code-block:: inform
787 Object branch "wide firm bough" top_of_tree
788 with description "It's flat enough to support a small object.",
789 name 'wide' 'firm' 'flat' 'bough' 'branch',
790 has static supporter;
792 The only new things are those two labels. :attr:`static` is similar to
793 :attr:`scenery`: it prevents the branch from being picked up by the player
794 character, but *doesn't* suppress mention of it when describing the
795 setting. And :attr:`supporter` is rather like the :attr:`container` that
796 we used for the nest, except that this time the player character can put
797 other objects *onto* the branch. (In passing, we'll mention that an object
798 can't normally be both a :attr:`container` *and* a :attr:`supporter`.) And
799 so here are our objects again:
801 .. code-block:: inform
803 !============================================================================
806 Object before_cottage "In front of a cottage"
808 "You stand outside a cottage. The forest stretches east.",
812 Object forest "Deep in the forest"
814 "Through the dense foliage, you glimpse a building to the west.
815 A track heads to the northeast.",
820 Object bird "baby bird" forest
821 with description "Too young to fly, the nestling tweets helplessly.",
822 name 'baby' 'bird' 'nestling',
825 Object clearing "A forest clearing"
827 "A tall sycamore stands in the middle of this clearing.
828 The path winds southwest through the trees.",
833 Object nest "bird's nest" clearing
834 with description "The nest is carefully woven of twigs and moss.",
835 name 'bird^s' 'nest' 'twigs' 'moss',
838 Object tree "tall sycamore tree" clearing
840 "Standing proud in the middle of the clearing,
841 the stout tree looks easy to climb.",
842 name 'tall' 'sycamore' 'tree' 'stout' 'proud',
845 Object top_of_tree "At the top of the tree"
846 with description "You cling precariously to the trunk.",
850 Object branch "wide firm bough" top_of_tree
851 with description "It's flat enough to support a small object.",
852 name 'wide' 'firm' 'flat' 'bough' 'branch',
853 has static supporter;
855 !============================================================================
857 Once again, make the changes, recompile, and investigate what you can do in
863 Our first pass at the game is nearly done; just two more changes to
864 describe. The first is easy: Heidi wouldn't be able to climb the tree
865 carrying the bird and the nest separately: we want the player character to
866 put the bird into the nest first. One easy way to enforce this is by
867 adding a line near the top of the file:
869 .. include:: /config/typethis.rst
871 .. code-block:: inform
873 !============================================================================
874 Constant Story "Heidi";
876 "^A simple Inform example
877 ^by Roger Firth and Sonja Kesserich.^";
879 Constant MAX_CARRIED 1;
881 The value of ``MAX_CARRIED`` limits the number of objects that the player
882 character can be holding at any one time; by setting it to 1, we're saying
883 that she can carry the bird or the nest, but not both. However, the limit
884 ignores the contents of :attr:`container` or :attr:`supporter` objects, so
885 the nest with the bird inside it is still counted as one object.
887 The other change is slightly more complex and more important: there's
888 currently no way to "win" the game! The goal is for the player character
889 to put the bird in the nest, take the nest to the top of the tree, and
890 place it on the branch; when that happens, the game should be over. This
891 is one way of making it happen:
893 .. include:: /config/typethis.rst
895 .. code-block:: inform
897 Object branch "wide firm bough" top_of_tree
898 with description "It's flat enough to support a small object.",
899 name 'wide' 'firm' 'flat' 'bough' 'branch',
900 each_turn [; if (nest in branch) deadflag = 2; ],
901 has static supporter;
905 Here's an explanation of what's going on. If you find this difficult to
906 grasp, don't worry. It's the hardest bit so far, and it introduces
907 several new concepts all at once. Later in the guide, we'll explain
908 those concepts more clearly, so you can just skip this bit if you want.
910 .. Generated by autoindex
912 pair: deadflag; library variable
914 The variable :var:`deadflag`, part of the library, is normally 0. If
915 you set its value to 2, the interpreter notices and ends the game with
916 "You have won". The statement::
918 if (nest in branch) deadflag = 2;
920 should be read as: "Test whether the ``nest`` is currently in the
921 ``branch`` (if the branch is a :attr:`container`) or on it (if the
922 ``branch`` is a supporter); if it is, set the value of :var:`deadflag`
923 to 2; if it isn't, do nothing." The surrounding part::
927 should be read as: "At the end of each turn (when the player is in the
928 same room as the branch), do whatever is written inside the square
929 brackets". So, putting that all together:
931 * At the end of each turn (after the player has typed something and
932 pressed the Enter key, and the interpreter has done whatever was
933 requested) the interpreter checks whether the player and the
934 ``branch`` are in the same room. If not, nothing happens. If they're
935 together, it looks to see where the nest is. Initially it's in the
936 ``clearing``, so nothing happens.
938 * Also at the end of each turn, the interpreter checks the value of
939 :var:`deadflag`. Usually it's 0, so nothing happens.
941 * Finally the player character puts the ``nest`` on the ``branch``.
942 "Aha!" says the interpreter (to itself, of course), and sets the
943 value of :var:`deadflag` to 2.
945 * Immediately afterwards, (another part of) the interpreter checks and
946 finds that the value of :var:`deadflag` has changed to 2, which means
947 that the game is successfully completed; so, it says to the player,
950 That's as far as we'll take this example for now. Make those final
951 changes, recompile, and test what you've achieved. You'll probably find a
952 few things that could be done better -- even on a simple game like this
953 there's considerable scope for improvement -- so we'll revisit Heidi in her
954 forest shortly. First, though, we'll recap what we've learnt so far.