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
88 A :term:`statement` is an instruction intended for the interpreter, telling
89 it what to do at run-time. It *must* be given in lower-case, and always
90 ends with a semicolon.
92 Some statements, like ``if``, control one or more other statements. We
93 use the placeholder `{statement_block}` to represent either a single
94 `{statement}`, or any number of `{statements}` enclosed in braces:
98 | `{statement}; {statement}; ... {statement};`
100 Statements that we've met
101 -------------------------
103 Our games have used these statements, about half of the Inform
106 | `give {obj_id} {attribute};`
107 | `give {obj_id} {attribute} {attribute} ... {attribute};`
109 | `if ({expression}) {statement_block}`
110 | `if ({expression}) {statement_block} else {statement_block}`
112 | `move {obj_id} to {parent_obj_id};`
114 | `objectloop ({var_id}) {statement_block}`
117 | `print {value}, {value}, ... {value};`
119 | `print_ret {value};`
120 | `print_ret {value}, {value}, ... {value};`
127 | `style underline; print...; style roman;`
129 | `switch ({expression}) {`
130 | `{value}: {statement}; {statement}; ... {statement};`
132 | `default: {statement}; {statement}; ... {statement};`
136 | `"{string}", {value}, ... {value};`
139 | `<{action} {noun}>;`
140 | `<{action} {noun} {second}>;`
143 | `<<{action} {noun}>>;`
144 | `<<{action} {noun} {second}>>;`
146 Statements that we've not met
147 -----------------------------
149 Although our example games haven't needed to use them, these looping
150 statements are sometimes useful:
155 | `do {statement_block} until ({expression})`
157 | `for ({set_var} : {loop_while_expression} : {update_var}) {statement_block}`
159 | `while ({expression}) {statement_block}`
161 On the other hand, we suggest that you put the following statements on
162 hold for now; they're not immediately relevant to everyday code and have
163 mostly to do with printing and formatting:
172 In particular, avoid using the deprecated jump statement if you possibly can.
177 In ``print`` and ``print_ret`` statements, each `{value}` can be:
179 * a numeric `{expression}`, displayed as a signed decimal number,
181 * a `"{string}"`, displayed literally, or
183 * a print rule. You can create your own, or use a standard one, including:
185 .. tabularcolumns:: ll
187 +-------------------------+---------------------------------------------------+
188 | `(a) {obj_id}` | the object's name, preceded by "a", "an" or "some"|
189 +-------------------------+---------------------------------------------------+
190 | `(A) {obj_id}` | as ``(a)`` but using "A", "An" or "Some" |
191 +-------------------------+---------------------------------------------------+
192 | `(the) {obj_id}` | the object's name, preceded by "the" |
193 +-------------------------+---------------------------------------------------+
194 | `(The) {obj_id}` | as ``(the)`` but using "The" |
195 +-------------------------+---------------------------------------------------+
196 | `(number) {expression}` | the numeric expression's value in words |
197 +-------------------------+---------------------------------------------------+
202 A :term:`directive` is an instruction intended for the compiler, telling it
203 what to do at compile-time, while the source file is being translated into
204 Z-code. By convention it's given an initial capital letter (though the
205 compiler doesn't enforce this) and always ends with a semicolon.
207 Directives that we've met
208 -------------------------
210 We've used all of these directives; note that for ``Class``, ``Extend``,
211 ``Object`` and ``Verb`` the full supported syntax is more sophisticated
212 than the basic form presented here::
219 has attribute attribute ... attribute;
222 Constant const_id = expression;
223 Constant const_id expression;
226 * token token ... token -> action
227 * token token ... token -> action
229 * token token ... token -> action
233 Object obj_id "external_name" parent_obj_id
238 has attribute attribute ... attribute;
247 * token token ... token -> action
248 * token token ... token -> action
250 * token token ... token -> action;
252 ! comment text which the compiler ignores
254 [ routine_id; statement; statement; ... statement; ];
256 #Ifdef any_id; ... #Endif;
258 Directives that we've not met
259 -----------------------------
261 There's only a handful of useful directives which we haven't needed to
267 Global var_id = expression;
274 but there's a whole load which are of fairly low importance for now::
297 An object is really just a collection of variables which together
298 represent the capabilities and current status of some specific component
299 of the model world. Full variables are called properties; simpler
300 two-state variables are attributes.
305 .. Generated by autoindex
307 pair: before; library property
308 pair: name; library property
310 The library defines around forty-eight standard property variables (such
311 as :prop:`before` or :prop:`name`), but you can readily create further ones just
312 by using them within an object definition.
314 You can create and initialise a property in an object's ``with`` segment:
316 property, ! set to zero / false
318 property value, ! set to a single value
320 property value value ... value, ! set to a list of values
322 In each case, the `{value}` is either a compile-time `{expression}`, or
323 an embedded routine::
327 property [; statement; statement; ... statement; ],
329 You can refer to the value of a property::
331 self.property ! only within that same object
333 obj_id.property ! everywhere
335 and you can test whether an object definition includes a given property::
337 (obj_id provides property) ! is true or false
344 Inform provides standalone routines and embedded routines.
349 Standalone routines are defined like this::
351 [ routine_id; statement; statement; ... statement; ];
353 and called like this::
360 These are embedded as the value of an object's property::
362 property [; statement; statement; ... statement; ],
364 and are usually called automatically by the library, or manually by::
366 self.property() ! only within that same object
368 obj_id.property() ! everywhere
371 single: arguments (of a routine)
373 Arguments and local variables
374 -----------------------------
376 Both types of routine support up to fifteen local variables -- variables
377 which can be used only by the statements within the routine, and which
378 are automatically initialised to zero every time that the routine is
381 [ routine_id var_id var_id ... var_id; statement; statement; ... statement; ];
383 property [ var_id var_id ... var_id; statement; statement; ... statement; ],
385 You can pass up to seven arguments to a routine, by listing those
386 arguments within the parentheses when you call the routine. The effect
387 is simply to initialise the matching local variables to the argument
388 values rather than to zero::
390 routine_id(expression, expression, ... expression)
392 Although it works, this technique is rarely used with embedded routines,
393 because there is no mechanism for the library to supply argument values
394 when calling the routine.
399 Every routine returns a single value, which is supplied either
400 explicitly by some form of return statement::
402 [ routine_id; statement; statement; ... return expr; ]; ! returns expr
404 property [; statement; statement; ... return expr; ], ! returns expr
406 or implicitly when the routine runs out of statements. If none of these
407 ``statements`` is one -- ``return``, ``print_ret``, ``"..."`` or
408 ``<<...>>`` -- that causes an explicit return, then::
410 [ routine_id; statement; statement; ... statement; ];
412 .. Generated by autoindex
414 pair: true; library constant
416 returns :const:`true` and ::
418 property [; statement; statement; ... statement; ]
420 return :const:`false`.
422 This difference is *important*. Remember it by the letter pairs STEF:
423 left to themselves, Standalone routines return True, Embedded routines
426 Here's an example standalone routine which returns the larger of its two
429 [ Max a b; if (a > b) return a; else return b; ];
431 and here are some examples of its use (note that the first example,
432 though legal, does nothing useful whatsoever)::
438 if (Max(x,7) == 7) ...
440 switch (Max(3,y)) { ...
442 Library routines versus entry points
443 ------------------------------------
445 A library routine is a standard routine, included within the library
446 files, which you can optionally call from your source file if you
447 require the functionality which the routine provides. We've mentioned
448 these library routines::
450 IndirectlyContains(parent_obj_id, obj_id)
454 PlayerTo(obj_id, flag)
461 By contrast, an entry point routine is a routine which you can provide
462 in your source file, in which case the library calls it at an
463 appropriate time. We've mentioned these optional entry point routines::
467 InScope(actor_obj_id)
469 And this, the only mandatory one::
473 There are full lists in :ref:`library-routines` and :ref:`entry-points`.
475 .. _reading-other-code:
477 Reading other people's code
478 ===========================
480 Right at the start of this guide, we warned you that we weren't setting
481 out to be comprehensive; we've concentrated on presenting the most
482 important aspects of Inform, as clearly as we can. However, when you
483 read the *Inform Designer's* Manual, and more especially when you look
484 at complete games or library extensions which other designers have
485 produced, you'll come across other ways of doing things -- and it might
486 be that you, like other authors, prefer them over our methods. Just try
487 to find a style that suits you and, this is the important bit, be
488 *consistent* about its use. In this section, we highlight some of the
489 more obvious differences which you may encounter.
494 Every designer has his or her own style for laying out their source
495 code, and they're all worse than the one you adopt. Inform's flexibility
496 makes it easy for designers to choose a style that suits them;
497 unfortunately, for some designers this choice seems influenced by the
498 Jackson Pollock school of art. We've advised you to be consistent, to
499 use plenty of white space and indentation, to choose sensible names, to
500 add comments at difficult sections, to actively *think*, as you write
501 your code, about making it as readable as you can.
503 This is doubly true if you ever contemplate sharing a library extension
504 with the rest of the community. This example, with the name changed, is
505 from a file in the Archive::
509 if (i in player) rtrue;
510 if (i has static || (i has scenery)) rtrue;
512 if (runroutines(j,before) ~= 0 || (j has static || (j has scenery))) {
513 print "You'll have to disconnect ",(the) i," from ",(the) j," first.^";
517 if (runroutines(i,before)~=0 || (i has static || (i has scenery))) {
518 print "You'll have to disconnect ",(the) i," from ",(the) j," first.^";
522 if (j hasnt concealed && j hasnt static) move j to player;
523 if (i hasnt static && i hasnt concealed) move i to player;
525 if (runroutines(j,after) ~= 0) rtrue;
526 print "You take ",(the) i," and ",(the) j," connected to it.^";
531 Here's the same routine after a few minutes spent purely on making it
532 more comprehensible; we haven't actually tested that it (still) works,
533 though that second ``else`` looks suspicious::
536 if (i in player || i has static or scenery || j == nothing) return true;
538 if (RunRoutines(j,before) || j has static or scenery)
539 "You'll have to disconnect ", (the) i, " from ", (the) j, " first.";
541 if (RunRoutines(i,before) || i has static or scenery)
542 "You'll have to disconnect ", (the) i, " from ", (the) j, " first.";
544 if (j hasnt static or concealed) move j to player;
545 if (i hasnt static or concealed) move i to player;
546 if (RunRoutines(j,after)) return true;
547 "You take ", (the) i, " and ", (the) j, " connected to it.";
551 We hope you'll agree that the result was worth the tiny extra effort.
552 Code gets written once; it gets read dozens and dozens of times.
557 There are a few statement shortcuts, some more useful than others, which
560 * These five lines all do the same thing::
566 ]; ! at the end of a standalone routine
568 * These four lines all do the same thing::
573 ]; ! at the end of an embedded routine
575 * These four lines all do the same thing::
577 print "string"; new_line; return true;
578 print "string^"; return true;
582 * These lines are the same::
584 print value1; print value2; print value3;
585 print value1, value2, value3;
587 * These lines are the same::
589 <action noun second>; return true;
590 <<action noun second>>;
592 * These lines are also the same::
597 * These ``if`` statements are equivalent::
599 if (MyVar == 1 || MyVar == 3 || MyVar == 7) ...
601 if (MyVar == 1 or 3 or 7) ...
603 * These ``if`` statements are equivalent as well::
605 if (MyVar ~= 1 && MyVar ~= 3 && MyVar ~= 7) ...
606 if (MyVar ~= 1 or 3 or 7) ...
608 * In an ``if`` statement, the thing in parentheses can be *any*
609 expression; all that matters is its value: zero (false) or anything
610 else (true). For example, these statements are equivalent::
612 if (MyVar ~= false) ...
613 if (~~(MyVar == false)) ...
615 if (~~(MyVar == 0)) ...
618 Note that the following statement specifically tests whether ``MyVar``
619 contains :const:`true` (1), *not* whether its value is anything other than
622 if (MyVar == true) ...
624 * If ``MyVar`` is a variable, the statements ``MyVar++;`` and
625 ``++MyVar;`` work the same as ``MyVar = MyVar + 1;`` For example,
626 these lines are equivalent::
628 MyVar = MyVar + 1; if (MyVar == 3) ...
629 if (++MyVar == 3) ...
630 if (MyVar++ == 2) ...
632 What's the same about ``MyVar++`` and ``++MyVar`` is that they both
633 add one to ``MyVar``. What's different about them is the value to
634 which the construct itself evaluates: ``MyVar++`` returns the current
635 value of ``MyVar`` and then performs the increment, whereas
636 ``++MyVar`` does the "+1" first and then returns the incremented
637 value. In the example, if ``MyVar`` currently contains 2 then
638 ``++MyVar`` returns 3 and ``MyVar++`` returns 2, even though in both
639 cases the value of ``MyVar`` afterwards is 3. As another example,
640 this code (from Helga in "William Tell")::
642 Talk: self.times_spoken_to = self.times_spoken_to + 1;
643 switch (self.times_spoken_to) {
644 1: score = score + 1;
645 print_ret "You warmly thank Helga for the apple.";
646 2: print_ret "~See you again soon.~";
647 default: return false;
651 could have been written more succinctly like this::
653 Talk: switch (++self.times_spoken_to) {
655 print_ret "You warmly thank Helga for the apple.";
656 2: print_ret "~See you again soon.~";
657 default: return false;
661 * Similarly, the statements ``MyVar--;`` and ``--MyVar;`` work the same
662 as ``MyVar = MyVar - 1;`` Again, these lines are equivalent::
664 MyVar = MyVar - 1; if (MyVar == 7) ...
665 if (--MyVar == 7) ...
666 if (MyVar-- == 8) ...
668 "number" property and "general" attribute
669 -----------------------------------------
671 .. Generated by autoindex
673 pair: general; library attribute
674 pair: number; library property
676 The library defines a standard :prop:`number` property and a standard
677 :attr:`general` attribute, whose roles are undefined: they are
678 general-purpose variables available within every object to designers as
679 and when they desire.
681 We recommend that you avoid using these two variables, primarily because
682 their names are, by their very nature, so bland as to be largely
683 meaningless. Your game will be clearer and easier to debug if you
684 instead create new property variables -- with appropriate names -- as
685 part of your ``Object`` and ``Class`` definitions.
689 Common properties and attributes
690 --------------------------------
692 As an alternative to creating new individual properties which apply only to
693 a single object (or class of objects), it's possible to devise properties
694 and new attributes which, like those defined by the library, are available
695 on *all* objects. The need to do this is actually quite rare, and is mostly
696 confined to library extensions (for example, the ``pname.h`` extension
697 which we encountered in :doc:`12` gives every object a ``pname`` property
698 and a ``phrase_matched`` attribute). To create them, you would use these
699 directives near the start of your source file::
705 We recommend that you avoid using these two directives unless you really
706 do need to affect every object -- or at least the majority of them -- in
707 your game. There is a limit of forty-eight attributes (of which the
708 library currently defines around thirty) and sixty-two of these common
709 properties (of which the library currently defines around forty-eight).
710 On the other hand, the number of individual properties which you can add
711 is virtually unlimited.
715 Setting up the object tree
716 --------------------------
718 .. Generated by autoindex
720 pair: found_in; library property
722 Throughout this guide, we've defined the initial position of each object
723 within the overall object tree either by explicitly mentioning its
724 parent's ``obj_id`` (if any) in the first line of the object definition
725 -- what we've been calling the header information -- or, for a few
726 objects which crop up in more than one place, by using their
727 :prop:`found_in` properties. For example, in "William Tell" we defined
728 twenty-seven objects; omitting those which used :prop:`found_in` to define
729 their placement at the start of the game, we're left with object
730 definitions starting like this::
732 Room street "A street in Altdorf"
734 Room below_square "Further along the street"
735 Furniture stall "fruit and vegetable stall" below_square
736 Prop "potatoes" below_square
737 Prop "fruit and vegetables" below_square
738 NPC stallholder "Helga" below_square
740 Room south_square "South side of the square"
742 Room mid_square "Middle of the square"
743 Furniture pole "hat on a pole" mid_square
745 Room north_square "North side of the square"
747 Room marketplace "Marketplace near the square"
748 Object tree "lime tree" marketplace
749 NPC governor "governor" marketplace
753 Object quiver "quiver"
760 You'll see that several of the objects begin the game as parents:
761 ``below_square``, ``mid_square``, ``marketplace`` and ``quiver`` all
762 have child objects beneath them; those children mention their parent as
763 the last item of header information.
765 There's an alternative object syntax which is available to achieve the
766 same object tree, using "arrows". That is, we could have defined those
767 parent-and-child objects as::
769 Room below_square "Further along the street"
770 Furniture -> stall "fruit and vegetable stall"
772 Prop -> "fruit and vegetables"
773 NPC -> stallholder "Helga"
775 Room mid_square "Middle of the square"
776 Furniture -> pole "hat on a pole"
778 Room marketplace "Marketplace near the square"
779 Object -> tree "lime tree"
780 NPC -> governor "governor"
782 Object quiver "quiver"
787 The idea is that an object's header information *either* starts with an
788 arrow, or ends with an ``obj_id``, or has neither (having both isn’t
789 permitted). An object with neither has no parent: in this example,
790 that's all the ``Rooms``, and also the ``bow`` and the ``quiver`` (which
791 are moved to the player ``object`` in the ``Initialise`` routine) and
792 the apple (which remains without a parent until Helga gives it to
795 An object which starts with a single arrow ``->`` is defined to be a
796 child of the nearest previous object without a parent. Thus, for
797 example, the ``tree`` and ``governor`` objects are both children of the
798 ``marketplace``. To define a child of a child, you'd use two arrows
799 ``-> ->``, and so on. In "William Tell", that situation doesn't occur;
800 to illustrate how it works, imagine that at the start of the game the
801 potatoes and the other fruit and vegetables where actually *on* the
802 stall. Then we might have used::
804 Room below_square "Further along the street"
805 Furniture -> stall "fruit and vegetable stall"
806 Prop -> -> "potatoes"
807 Prop -> -> "fruit and vegetables"
808 NPC -> stallholder "Helga"
811 That is, the objects with one arrow (the ``stall`` and ``stallholder``)
812 are children of the nearest object without a parent (the ``Room``), and
813 the objects with two arrows (the produce) are children of the nearest
814 object defined with a single arrow (the ``stall``).
816 The advantages of using arrows include:
818 * You're forced to define your objects in a "sensible" order.
820 * Fewer ``obj_ids`` may need to be used (though in this game it would
823 The disadvantages include:
825 * The fact that objects are related by the physical juxtaposition of
826 their definitions is not necessarily intuitive to all designers.
828 * Especially in a crowded room, it’s harder to be certain exactly how
829 the various parent–child relationships are initialised, other than by
830 carefully counting lots of arrows.
832 * If you relocate the parent within the initial object hierarchy to a
833 higher or lower level, you'll need also to change its children by
834 adding or removing arrows; this isn't necessary when the parent is
835 named in the child headers.
837 We prefer to explicitly name the parent, but you'll encounter both forms
840 Quotes in "name" properties
841 ---------------------------
843 We went to some lengths, way back in :ref:`things-in-quotes`, to explain
844 the difference between double quotes ``"..."`` (strings to be output) and
845 single quotes ``'...'`` (input tokens -- dictionary words). Perhaps
846 somewhat unfortunately, Inform allows you to blur this clean distinction:
847 you can use double quotes in name properties and Verb directives::
849 NPC stallholder "Helga" below_square
850 with name "stallholder" "greengrocer" "monger" "shopkeeper" "merchant"
851 "owner" "Helga" "dress" "scarf" "headscarf",
854 Verb "talk" "t//" "converse" "chat" "gossip"
855 * "to"/"with" creature -> Talk
858 *Please* don't do this. You'll just confuse yourself: those are
859 dictionary words, not strings; it's just as easy -- and far clearer --
860 to stick rigidly to the preferred punctuation.
865 Finally, remember that Inform has been evolving since 1993. Over that
866 time, Graham has taken considerable care to maintain as much
867 compatibility as possible, so that games written years ago, for earlier
868 versions of the compiler and the library, will still compile today.
869 While generally a good thing, this brings the disadvantage that a
870 certain amount of obsolete baggage is still lying around. You may, for
871 example, see games using ``Nearby`` directives (denotes parentage,
872 roughly the same as ``->``) and ``near`` conditions (roughly, having the
873 same parent), or with ``" \ "`` controlling line breaks in long
874 ``print`` statements. Try to understand them; try *not* to use them.