1 ========================
3 ========================
11 .. image:: /images/picF.png
14 |F|\inally our three example games are written; we've shown you as much of
15 the Inform language as we've needed to, and made a lot of observations
16 about how and why something should be done. Despite all that, there's much
17 that we've left unsaid, or touched on only lightly. In this chapter we'll
18 revisit key topics and review some of the more significant omissions, to
19 give you a better feel for what's important, and what can be ignored for
20 the time being; when you become an accomplished designer, you will decide
21 what matters and what can be left on the shelf.
23 We'll also talk, in :ref:`reading-other-code`, about a few ways of doing
24 things that we've chosen not to tell you about, but which you're quite
25 likely to encounter if you look at Inform code written by other designers.
27 The tone here is perhaps a little dry, but trust us: in walking this dusty
28 ground we touch on just about everything that is fundamental in your
29 overall understanding of Inform. And as always, the |DM4| provides rounder
30 and more comprehensive coverage.
35 In this guide we’ve used the placeholder `{expression}` a few times;
36 here's roughly what we mean.
38 * An `{expression}` is a single `{value}`, or several `{values}`
39 combined using `{operators}` and sometimes parentheses ``(...)``.
41 * Possible `{values}` include:
43 * a literal number (-32768 to 32767)
45 * something that's represented as a number (a character ``'a'`` , a
46 dictionary word ``'aardvark'`` , a string ``"aardvark's adventure"``
47 or an action ``##Look`` )
49 * the internal identifier of a constant, an object, a class or a routine
51 * (only in a run-time statement, not in a compile-time directive) the
52 contents of a variable, or the return value from a routine.
54 * Possible `{operators}` include:
56 * an arithmetic operator: ``+ - * / % ++``
57 * a bitwise logical operator: ``& | ~``
58 * a numeric comparison operator: ``== ~= > < >= <=``
59 * an object conditional operator: ``ofclass in notin provides has hasnt``
60 * a boolean combinational operator: ``&& || ~~``
65 Many of the items which you define in your source file -- objects,
66 variables, routines, etc. -- need to be given a name so that other items
67 can refer to them. We call this name an item's internal identifier
68 (because it's used only within the source file and isn't visible to the
69 player), and we use the placeholders `{obj_id}`, `{var_id}`,
70 `{routine_id}`, etc. to represent where it's used. An internal ID
72 * can be up to thirty-two characters long
74 * must start with a letter or underscore, and then continue with letters
75 ``A-Z`` , underscore ``_`` and digits ``0-9`` (where upper-case and
76 lower-case letters are treated as indistinguishable)
78 * should generally be unique across all files: your source file, the
79 standard library files, and any library contributions which you've
80 used (except that a routine's local variables are not visible outside
90 We might need some custom syntax highlighting here.
92 A :term:`statement` is an instruction intended for the interpreter, telling
93 it what to do at run-time. It *must* be given in lower-case, and always
94 ends with a semicolon.
96 Some statements, like ``if``, control one or more other statements. We
97 use the placeholder `{statement_block}` to represent either a single
98 `{statement}`, or any number of `{statements}` enclosed in braces::
102 { statement; statement; ... statement; }
104 Statements that we've met
105 -------------------------
107 Our games have used these statements, about half of the Inform
110 give obj_id attribute;
111 give obj_id attribute attribute ... attribute;
113 if (expression) statement_block
114 if (expression) statement_block else statement_block
116 move obj_id to parent_obj_id;
118 objectloop (var_id) statement_block
121 print value, value, ... value;
124 print_ret value, value, ... value;
131 style underline; print...; style roman;
133 switch (expression) {
134 value: statement; statement; ... statement;
136 default: statement; statement; ... statement;
140 "string", value, ... value;
144 <action noun second>;
148 <<action noun second>>;
150 Statements that we've not met
151 -----------------------------
153 Although our example games haven't needed to use them, these looping
154 statements are sometimes useful::
159 do statement_block until (expression)
161 for (set_var : loop_while_expression : update_var) statement_block
163 while (expression) statement_block
165 On the other hand, we suggest that you put the following statements on
166 hold for now; they're not immediately relevant to everyday code and have
167 mostly to do with printing and formatting::
176 In particular, avoid using the deprecated jump statement if you possibly can.
181 In ``print`` and ``print_ret`` statements, each `{value}` can be:
183 * a numeric `{expression}`, displayed as a signed decimal number,
185 * a `"{string}"`, displayed literally, or
187 * a print rule. You can create your own, or use a standard one, including:
189 .. tabularcolumns:: ll
191 +-------------------------+---------------------------------------------------+
192 | `(a) {obj_id}` | the object's name, preceded by "a", "an" or "some"|
193 +-------------------------+---------------------------------------------------+
194 | `(A) {obj_id}` | as ``(a)`` but using "A", "An" or "Some" |
195 +-------------------------+---------------------------------------------------+
196 | `(the) {obj_id}` | the object's name, preceded by "the" |
197 +-------------------------+---------------------------------------------------+
198 | `(The) {obj_id}` | as ``(the)`` but using "The" |
199 +-------------------------+---------------------------------------------------+
200 | `(number) {expression}` | the numeric expression's value in words |
201 +-------------------------+---------------------------------------------------+
206 A :term:`directive` is an instruction intended for the compiler, telling it
207 what to do at compile-time, while the source file is being translated into
208 Z-code. By convention it's given an initial capital letter (though the
209 compiler doesn't enforce this) and always ends with a semicolon.
211 Directives that we've met
212 -------------------------
214 We've used all of these directives; note that for ``Class``, ``Extend``,
215 ``Object`` and ``Verb`` the full supported syntax is more sophisticated
216 than the basic form presented here::
223 has attribute attribute ... attribute;
226 Constant const_id = expression;
227 Constant const_id expression;
230 * token token ... token -> action
231 * token token ... token -> action
233 * token token ... token -> action
237 Object obj_id "external_name" parent_obj_id
242 has attribute attribute ... attribute;
251 * token token ... token -> action
252 * token token ... token -> action
254 * token token ... token -> action;
256 ! comment text which the compiler ignores
258 [ routine_id; statement; statement; ... statement; ];
260 #Ifdef any_id; ... #Endif;
262 Directives that we've not met
263 -----------------------------
265 There's only a handful of useful directives which we haven't needed to
271 Global var_id = expression;
278 but there's a whole load which are of fairly low importance for now::
301 An object is really just a collection of variables which together
302 represent the capabilities and current status of some specific component
303 of the model world. Full variables are called properties; simpler
304 two-state variables are attributes.
309 The library defines around forty-eight standard property variables (such
310 as :prop:`before` or :prop:`name`), but you can readily create further ones just
311 by using them within an object definition.
313 You can create and initialise a property in an object's ``with`` segment:
315 property, ! set to zero / false
317 property value, ! set to a single value
319 property value value ... value, ! set to a list of values
321 In each case, the `{value}` is either a compile-time `{expression}`, or
322 an embedded routine::
326 property [; statement; statement; ... statement; ],
328 You can refer to the value of a property::
330 self.property ! only within that same object
332 obj_id.property ! everywhere
334 and you can test whether an object definition includes a given property::
336 (obj_id provides property) ! is true or false
343 Inform provides standalone routines and embedded routines.
348 Standalone routines are defined like this::
350 [ routine_id; statement; statement; ... statement; ];
352 and called like this::
359 These are embedded as the value of an object's property::
361 property [; statement; statement; ... statement; ],
363 and are usually called automatically by the library, or manually by::
365 self.property() ! only within that same object
367 obj_id.property() ! everywhere
370 single: arguments (of a routine)
372 Arguments and local variables
373 -----------------------------
375 Both types of routine support up to fifteen local variables -- variables
376 which can be used only by the statements within the routine, and which
377 are automatically initialised to zero every time that the routine is
380 [ routine_id var_id var_id ... var_id; statement; statement; ... statement; ];
382 property [ var_id var_id ... var_id; statement; statement; ... statement; ],
384 You can pass up to seven arguments to a routine, by listing those
385 arguments within the parentheses when you call the routine. The effect
386 is simply to initialise the matching local variables to the argument
387 values rather than to zero::
389 routine_id(expression, expression, ... expression)
391 Although it works, this technique is rarely used with embedded routines,
392 because there is no mechanism for the library to supply argument values
393 when calling the routine.
398 Every routine returns a single value, which is supplied either
399 explicitly by some form of return statement::
401 [ routine_id; statement; statement; ... return expr; ]; ! returns expr
403 property [; statement; statement; ... return expr; ], ! returns expr
405 or implicitly when the routine runs out of statements. If none of these
406 ``statements`` is one -- ``return``, ``print_ret``, ``"..."`` or
407 ``<<...>>`` -- that causes an explicit return, then::
409 [ routine_id; statement; statement; ... statement; ];
411 returns :const:`true` and ::
413 property [; statement; statement; ... statement; ]
415 return :const:`false`.
417 This difference is *important*. Remember it by the letter pairs STEF:
418 left to themselves, Standalone routines return True, Embedded routines
421 Here's an example standalone routine which returns the larger of its two
424 [ Max a b; if (a > b) return a; else return b; ];
426 and here are some examples of its use (note that the first example,
427 though legal, does nothing useful whatsoever)::
433 if (Max(x,7) == 7) ...
435 switch (Max(3,y)) { ...
437 Library routines versus entry points
438 ------------------------------------
440 A library routine is a standard routine, included within the library
441 files, which you can optionally call from your source file if you
442 require the functionality which the routine provides. We've mentioned
443 these library routines::
445 IndirectlyContains(parent_obj_id, obj_id)
449 PlayerTo(obj_id, flag)
456 By contrast, an entry point routine is a routine which you can provide
457 in your source file, in which case the library calls it at an
458 appropriate time. We've mentioned these optional entry point routines::
462 InScope(actor_obj_id)
464 And this, the only mandatory one::
468 There are full lists in :ref:`library-routines` and :ref:`entry-points`.
470 .. _reading-other-code:
472 Reading other people's code
473 ===========================
475 Right at the start of this guide, we warned you that we weren't setting
476 out to be comprehensive; we've concentrated on presenting the most
477 important aspects of Inform, as clearly as we can. However, when you
478 read the *Inform Designer's* Manual, and more especially when you look
479 at complete games or library extensions which other designers have
480 produced, you'll come across other ways of doing things -- and it might
481 be that you, like other authors, prefer them over our methods. Just try
482 to find a style that suits you and, this is the important bit, be
483 *consistent* about its use. In this section, we highlight some of the
484 more obvious differences which you may encounter.
489 Every designer has his or her own style for laying out their source
490 code, and they're all worse than the one you adopt. Inform's flexibility
491 makes it easy for designers to choose a style that suits them;
492 unfortunately, for some designers this choice seems influenced by the
493 Jackson Pollock school of art. We've advised you to be consistent, to
494 use plenty of white space and indentation, to choose sensible names, to
495 add comments at difficult sections, to actively *think*, as you write
496 your code, about making it as readable as you can.
498 This is doubly true if you ever contemplate sharing a library extension
499 with the rest of the community. This example, with the name changed, is
500 from a file in the Archive::
504 if (i in player) rtrue;
505 if (i has static || (i has scenery)) rtrue;
507 if (runroutines(j,before) ~= 0 || (j has static || (j has scenery))) {
508 print "You'll have to disconnect ",(the) i," from ",(the) j," first.^";
512 if (runroutines(i,before)~=0 || (i has static || (i has scenery))) {
513 print "You'll have to disconnect ",(the) i," from ",(the) j," first.^";
517 if (j hasnt concealed && j hasnt static) move j to player;
518 if (i hasnt static && i hasnt concealed) move i to player;
520 if (runroutines(j,after) ~= 0) rtrue;
521 print "You take ",(the) i," and ",(the) j," connected to it.^";
526 Here's the same routine after a few minutes spent purely on making it
527 more comprehensible; we haven't actually tested that it (still) works,
528 though that second ``else`` looks suspicious::
531 if (i in player || i has static or scenery || j == nothing) return true;
533 if (RunRoutines(j,before) || j has static or scenery)
534 "You'll have to disconnect ", (the) i, " from ", (the) j, " first.";
536 if (RunRoutines(i,before) || i has static or scenery)
537 "You'll have to disconnect ", (the) i, " from ", (the) j, " first.";
539 if (j hasnt static or concealed) move j to player;
540 if (i hasnt static or concealed) move i to player;
541 if (RunRoutines(j,after)) return true;
542 "You take ", (the) i, " and ", (the) j, " connected to it.";
546 We hope you'll agree that the result was worth the tiny extra effort.
547 Code gets written once; it gets read dozens and dozens of times.
552 There are a few statement shortcuts, some more useful than others, which
555 * These five lines all do the same thing::
561 ]; ! at the end of a standalone routine
563 * These four lines all do the same thing::
568 ]; ! at the end of an embedded routine
570 * These four lines all do the same thing::
572 print "string"; new_line; return true;
573 print "string^"; return true;
577 * These lines are the same::
579 print value1; print value2; print value3;
580 print value1, value2, value3;
582 * These lines are the same::
584 <action noun second>; return true;
585 <<action noun second>>;
587 * These lines are also the same::
592 * These ``if`` statements are equivalent::
594 if (MyVar == 1 || MyVar == 3 || MyVar == 7) ...
596 if (MyVar == 1 or 3 or 7) ...
598 * These ``if`` statements are equivalent as well::
600 if (MyVar ~= 1 && MyVar ~= 3 && MyVar ~= 7) ...
601 if (MyVar ~= 1 or 3 or 7) ...
603 * In an ``if`` statement, the thing in parentheses can be *any*
604 expression; all that matters is its value: zero (false) or anything
605 else (true). For example, these statements are equivalent::
607 if (MyVar ~= false) ...
608 if (~~(MyVar == false)) ...
610 if (~~(MyVar == 0)) ...
613 Note that the following statement specifically tests whether ``MyVar``
614 contains :const:`true` (1), *not* whether its value is anything other than
617 if (MyVar == true) ...
619 * If ``MyVar`` is a variable, the statements ``MyVar++;`` and
620 ``++MyVar;`` work the same as ``MyVar = MyVar + 1;`` For example,
621 these lines are equivalent::
623 MyVar = MyVar + 1; if (MyVar == 3) ...
624 if (++MyVar == 3) ...
625 if (MyVar++ == 2) ...
627 What's the same about ``MyVar++`` and ``++MyVar`` is that they both
628 add one to ``MyVar``. What's different about them is the value to
629 which the construct itself evaluates: ``MyVar++`` returns the current
630 value of ``MyVar`` and then performs the increment, whereas
631 ``++MyVar`` does the "+1" first and then returns the incremented
632 value. In the example, if ``MyVar`` currently contains 2 then
633 ``++MyVar`` returns 3 and ``MyVar++`` returns 2, even though in both
634 cases the value of ``MyVar`` afterwards is 3. As another example,
635 this code (from Helga in "William Tell")::
637 Talk: self.times_spoken_to = self.times_spoken_to + 1;
638 switch (self.times_spoken_to) {
639 1: score = score + 1;
640 print_ret "You warmly thank Helga for the apple.";
641 2: print_ret "~See you again soon.~";
642 default: return false;
646 could have been written more succinctly like this::
648 Talk: switch (++self.times_spoken_to) {
650 print_ret "You warmly thank Helga for the apple.";
651 2: print_ret "~See you again soon.~";
652 default: return false;
656 * Similarly, the statements ``MyVar--;`` and ``--MyVar;`` work the same
657 as ``MyVar = MyVar - 1;`` Again, these lines are equivalent::
659 MyVar = MyVar - 1; if (MyVar == 7) ...
660 if (--MyVar == 7) ...
661 if (MyVar-- == 8) ...
663 "number" property and "general" attribute
664 -----------------------------------------
666 The library defines a standard :prop:`number` property and a standard
667 :attr:`general` attribute, whose roles are undefined: they are
668 general-purpose variables available within every object to designers as
669 and when they desire.
671 We recommend that you avoid using these two variables, primarily because
672 their names are, by their very nature, so bland as to be largely
673 meaningless. Your game will be clearer and easier to debug if you
674 instead create new property variables -- with appropriate names -- as
675 part of your ``Object`` and ``Class`` definitions.
679 Common properties and attributes
680 --------------------------------
682 As an alternative to creating new individual properties which apply only to
683 a single object (or class of objects), it's possible to devise properties
684 and new attributes which, like those defined by the library, are available
685 on *all* objects. The need to do this is actually quite rare, and is mostly
686 confined to library extensions (for example, the ``pname.h`` extension
687 which we encountered in :doc:`12` gives every object a ``pname`` property
688 and a ``phrase_matched`` attribute). To create them, you would use these
689 directives near the start of your source file::
695 We recommend that you avoid using these two directives unless you really
696 do need to affect every object -- or at least the majority of them -- in
697 your game. There is a limit of forty-eight attributes (of which the
698 library currently defines around thirty) and sixty-two of these common
699 properties (of which the library currently defines around forty-eight).
700 On the other hand, the number of individual properties which you can add
701 is virtually unlimited.
705 Setting up the object tree
706 --------------------------
708 Throughout this guide, we've defined the initial position of each object
709 within the overall object tree either by explicitly mentioning its
710 parent's ``obj_id`` (if any) in the first line of the object definition
711 -- what we've been calling the header information -- or, for a few
712 objects which crop up in more than one place, by using their
713 :prop:`found_in` properties. For example, in "William Tell" we defined
714 twenty-seven objects; omitting those which used :prop:`found_in` to define
715 their placement at the start of the game, we're left with object
716 definitions starting like this::
718 Room street "A street in Altdorf"
720 Room below_square "Further along the street"
721 Furniture stall "fruit and vegetable stall" below_square
722 Prop "potatoes" below_square
723 Prop "fruit and vegetables" below_square
724 NPC stallholder "Helga" below_square
726 Room south_square "South side of the square"
728 Room mid_square "Middle of the square"
729 Furniture pole "hat on a pole" mid_square
731 Room north_square "North side of the square"
733 Room marketplace "Marketplace near the square"
734 Object tree "lime tree" marketplace
735 NPC governor "governor" marketplace
739 Object quiver "quiver"
746 You'll see that several of the objects begin the game as parents:
747 ``below_square``, ``mid_square``, ``marketplace`` and ``quiver`` all
748 have child objects beneath them; those children mention their parent as
749 the last item of header information.
751 There's an alternative object syntax which is available to achieve the
752 same object tree, using "arrows". That is, we could have defined those
753 parent-and-child objects as::
755 Room below_square "Further along the street"
756 Furniture -> stall "fruit and vegetable stall"
758 Prop -> "fruit and vegetables"
759 NPC -> stallholder "Helga"
761 Room mid_square "Middle of the square"
762 Furniture -> pole "hat on a pole"
764 Room marketplace "Marketplace near the square"
765 Object -> tree "lime tree"
766 NPC -> governor "governor"
768 Object quiver "quiver"
773 The idea is that an object's header information *either* starts with an
774 arrow, or ends with an ``obj_id``, or has neither (having both isn’t
775 permitted). An object with neither has no parent: in this example,
776 that's all the ``Rooms``, and also the ``bow`` and the ``quiver`` (which
777 are moved to the player ``object`` in the ``Initialise`` routine) and
778 the apple (which remains without a parent until Helga gives it to
781 An object which starts with a single arrow ``->`` is defined to be a
782 child of the nearest previous object without a parent. Thus, for
783 example, the ``tree`` and ``governor`` objects are both children of the
784 ``marketplace``. To define a child of a child, you'd use two arrows
785 ``-> ->``, and so on. In "William Tell", that situation doesn't occur;
786 to illustrate how it works, imagine that at the start of the game the
787 potatoes and the other fruit and vegetables where actually *on* the
788 stall. Then we might have used::
790 Room below_square "Further along the street"
791 Furniture -> stall "fruit and vegetable stall"
792 Prop -> -> "potatoes"
793 Prop -> -> "fruit and vegetables"
794 NPC -> stallholder "Helga"
797 That is, the objects with one arrow (the ``stall`` and ``stallholder``)
798 are children of the nearest object without a parent (the ``Room``), and
799 the objects with two arrows (the produce) are children of the nearest
800 object defined with a single arrow (the ``stall``).
802 The advantages of using arrows include:
804 * You're forced to define your objects in a "sensible" order.
806 * Fewer ``obj_ids`` may need to be used (though in this game it would
809 The disadvantages include:
811 * The fact that objects are related by the physical juxtaposition of
812 their definitions is not necessarily intuitive to all designers.
814 * Especially in a crowded room, it’s harder to be certain exactly how
815 the various parent–child relationships are initialised, other than by
816 carefully counting lots of arrows.
818 * If you relocate the parent within the initial object hierarchy to a
819 higher or lower level, you'll need also to change its children by
820 adding or removing arrows; this isn't necessary when the parent is
821 named in the child headers.
823 We prefer to explicitly name the parent, but you'll encounter both forms
826 Quotes in "name" properties
827 ---------------------------
829 We went to some lengths, way back in :ref:`things-in-quotes`, to explain
830 the difference between double quotes ``"..."`` (strings to be output) and
831 single quotes ``'...'`` (input tokens -- dictionary words). Perhaps
832 somewhat unfortunately, Inform allows you to blur this clean distinction:
833 you can use double quotes in name properties and Verb directives::
835 NPC stallholder "Helga" below_square
836 with name "stallholder" "greengrocer" "monger" "shopkeeper" "merchant"
837 "owner" "Helga" "dress" "scarf" "headscarf",
840 Verb "talk" "t//" "converse" "chat" "gossip"
841 * "to"/"with" creature -> Talk
844 *Please* don't do this. You'll just confuse yourself: those are
845 dictionary words, not strings; it's just as easy -- and far clearer --
846 to stick rigidly to the preferred punctuation.
851 Finally, remember that Inform has been evolving since 1993. Over that
852 time, Graham has taken considerable care to maintain as much
853 compatibility as possible, so that games written years ago, for earlier
854 versions of the compiler and the library, will still compile today.
855 While generally a good thing, this brings the disadvantage that a
856 certain amount of obsolete baggage is still lying around. You may, for
857 example, see games using ``Nearby`` directives (denotes parentage,
858 roughly the same as ``->``) and ``near`` conditions (roughly, having the
859 same parent), or with ``" \ "`` controlling line breaks in long
860 ``print`` statements. Try to understand them; try *not* to use them.