Add chapter 4.
authorGlenn Hutchings <zondo42@gmail.com>
Sun, 3 Apr 2016 14:46:07 +0000 (15:46 +0100)
committerGlenn Hutchings <zondo42@gmail.com>
Sun, 3 Apr 2016 14:46:07 +0000 (15:46 +0100)
chapters/04.rst [new file with mode: 0644]
images/heidiobj1.png [new file with mode: 0644]
images/heidiobj2.png [new file with mode: 0644]
images/heidiobj3.png [new file with mode: 0644]
images/heidiobj4.png [new file with mode: 0644]
images/heidiobj5.png [new file with mode: 0644]
images/heidiobj6.png [new file with mode: 0644]
images/heidiobj7.png [new file with mode: 0644]
images/heidiobj8.png [new file with mode: 0644]

diff --git a/chapters/04.rst b/chapters/04.rst
new file mode 100644 (file)
index 0000000..1c326c4
--- /dev/null
@@ -0,0 +1,547 @@
+======================
+ Reviewing the basics
+======================
+
+.. epigraph::
+
+   | *G was a gamester, who had but ill-luck;*
+   | *H was a hunter, and hunted a buck.*
+
+Going through the design of our first game in the previous chapter has
+introduced all sorts of Inform concepts, often without giving you much
+detail about what's been happening.  So let's review some of what we've
+learnt so far, in a slightly more organised fashion.  We'll talk about
+"Constants and variables" on page 49, "Object definitions" on page 50,
+"Object relationships -- the object tree" on page 52, "Things in quotes" on
+page 55, and "Routines and statements" on page 56.
+
+Constants and variables
+=======================
+
+Superficially similar, constants and variables are actually very different
+beasts.
+
+.. rubric:: Constants
+
+A **constant** is a name to which a value is given once and once only; you
+can't later use that name to stand for a different value.  Think of it as a
+stone tablet on which you carve a number: a carving can't be undone, so
+that you see the same number every time you look at the stone.
+
+So far, we've seen a ``Constant`` being set up with its value as a string
+of characters::
+
+    Constant Story "Heidi";
+
+and as a number::
+
+    Constant MAX_CARRIED 1;
+
+Those two examples represent the most common ways in which constants are
+used in Inform.
+
+.. rubric:: Variables
+
+A **variable** is a name to which a value is given, but that value can be
+changed to a different one at any time.  Think of it as a blackboard on
+which you mark a number in chalk: whenever you need to, just wipe the board
+and write up a new number.
+
+We haven't set up any variables of our own yet, though we've used a couple
+which the library created like this::
+
+    Global location;
+    Global deadflag;
+
+The value of a **global variable** created in this way is initially 0, but
+you can change it at any time.  For example, we used the statement::
+
+     location = before_cottage;
+
+to reset the value of the location variable to the ``before_cottage``
+object, and we wrote::
+
+     if (nest in branch) deadflag = 2;
+
+to reset the value of the ``deadflag`` variable to 2.
+
+Later, we'll talk about the **local variable** (see "Routines" on page 179)
+and about using object properties as variables (see "Objects" on page 177).
+
+Object definitions
+==================
+
+The most important information you should have gleaned from the previous
+chapter is that your entire game is defined as a series of objects.  Each
+room is an object, each item that the player sees and touches is an object;
+indeed the player herself is also an object (one that's automatically
+defined by the library).
+
+The general model of an **object** definition looks like this::
+
+        Object      obj_id   "external_name"   parent_obj_id
+           with     property    value ,
+                    property    value ,
+                    ...
+                    property    value ,
+           has      attribute    attribute   ... attribute
+           ;
+
+The definition starts with the word ``Object`` and ends with a semicolon;
+in between are three major blocks of information:
+
+* immediately after the word ``Object`` is the header information;
+* the word ``with`` introduces the object's **properties**;
+* the word ``has`` introduces the object's **attributes**.
+
+.. rubric:: Object headers
+
+An object header comprises up to three items, all optional:
+
+* An internal ``obj_id`` by which other objects refer to this object.  It's
+  a single word (though it can contain digits and underscores) of up to
+  thirty-two characters, and it must be unique within the game.  You can
+  omit the ``obj_id`` if this object isn't referred to by any other
+  objects.
+
+  For example: ``bird``, ``tree``, ``top_of_tree``.
+
+* An ``external_name``, in double quotes, which is what the interpreter
+  uses when referring to the object.  It can be one or more words, and need
+  not be unique (for instance, you might have several ``"Somewhere in the
+  desert"`` rooms).  Although not mandatory, it's best to give *every*
+  object an ``external_name``.  For example: ``"baby bird"``, ``"tall
+  sycamore tree"``, ``"At the top of the tree"``.
+
+* The internal ``obj_id`` of another object which is the initial location
+  of this object (its "parent" -- see the next section) at the start of the
+  game.  This is omitted from objects which have no initial parent; it's
+  *always* omitted from a room.
+
+  For example: the definition of the ``bird`` starts like this, specifying
+  that at the start of the game, it can be found in the ``forest`` room
+  (though later the player character will pick it up and move it around)::
+
+      Object   bird "baby bird" forest
+      ...
+
+  The ``tree`` starts like this; the only real difference is that, because
+  the player character can't move a ``scenery`` object, it's always going
+  to be in the ``clearing``::
+
+      Object   tree "tall sycamore tree" clearing
+      ...
+
+  .. note::
+
+     There's an alternative method for defining an object's initial
+     location, using "arrows" rather than the parent's internal ``obj_id``.
+     For example, the definition of the bird could have started like this::
+
+         Object   -> bird "baby bird"
+         ...
+
+     We don't use the arrows method in this guide, though we do describe
+     how it works in "Setting up the object tree" on page 185.
+
+.. rubric:: Object properties
+
+An object's property definitions are introduced by the ``with`` keyword.
+An object can have any number of properties, and they can be defined in any
+order.  Each definition has two parts: a name, and a value; there's a space
+between the two parts, and a comma at the end.
+
+Think of each property as a variable which is specifically associated with
+that object.  The variable's initial setting is the supplied value; if
+necessary, it can be reset to other values during play (though in fact most
+property values don't change in this way).
+
+Here are examples of the properties that we've come across so far::
+
+    description "The nest is carefully woven of twigs and moss.",
+    e_to forest,
+    name 'baby' 'bird' 'nestling',
+    each_turn [; if (nest in branch) deadflag = 2; ],
+
+By happy coincidence, those examples also demonstrate most of the different
+types of value which can be assigned to a property.  The value associated
+with the ``description`` property in this particular example is a string of
+characters in double quotes; the value associated with this ``e_to``
+property is the internal identity of an object; the ``name`` property is a
+bit unusual -- its value is a list of dictionary words, each in single
+quotes; the ``each_turn`` property has a value which is an **embedded
+routine** (see "Embedded routines" on page 58).  The only other type of
+value which is commonly found is a simple number; for example::
+
+     capacity 10,
+
+In all, the library defines around forty-eight standard properties -- like
+``name`` and ``each_turn`` -- which you can associate with your objects;
+there's a complete list in "Object properties" on page 266.  And in
+"William Tell: in his prime" on page 91 we show you how to invent your own
+property variables.
+
+.. rubric:: Object attributes
+
+An object's attribute list is introduced by the ``has`` keyword.  An object
+can have any number of attributes, and they can be listed in any order,
+with a space between each.
+
+As with properties, you can think of each attribute as a variable which is
+specifically associated with that object.  However, an attribute is a much
+more limited form of variable, since it can have only two possible states:
+present, and absent (also known as set/clear, on/off, or true/false;
+incidentally, a two-state variable like this is often called a **flag**).
+Initially, an attribute is either present (if you mention its name in the
+list) or absent (otherwise); if necessary, its state can change during play
+(and this is relatively common).  We often say that a certain object
+currently *has* a certain attribute, or that conversely it *hasn't* got it.
+
+The attributes that we've come across so far are::
+
+     container light open scenery static supporter
+
+Each of those answers a question: Is this object a container?  Does it
+provide light?  and so on.  If the attribute is present then the answer is
+Yes; if the attribute isn't present, the answer is No.
+
+The library defines around thirty standard attributes, listed in "Object
+attributes" on page 269.  Although you *can* devise additional attributes
+-- see "Common properties and attributes" on page 185 -- in practice you
+seldom need to.
+
+Object relationships -- the object tree
+=======================================
+
+Not only is your game composed entirely of objects, but also Inform takes
+great care to keep track of the relationships between those objects.  By
+"relationship" we don't mean that Walter is Wilhelm's son, while Helga and
+Wilhelm are just good friends; it's a much more comprehensive exercise in
+recording exactly where each object is located, relative to the other
+objects in the game.
+
+Despite what we just said, Inform relationships *are* managed in terms of
+**parent** and **child** objects, though in a much broader sense than
+Wilhelm and Walter.  When the player character is in a particular room --
+for example the forest -- we can say that:
+
+* the forest object is *the* parent of the player object, or alternatively
+* the player object is *a* child of the forest object.
+
+Also, if the player is carrying an object -- for example the nest -- we say
+that:
+
+* the player object is *the* parent of the nest object, or that
+* the nest object is *a* child of the player object.
+
+Note the emphasis there: an object has exactly *one* parent (or no parent
+at all), but can have *any number* of child objects (including none).
+
+For an example of an object having more than one child, think about the way
+we defined the nest and tree objects::
+
+    Object   nest "bird's nest" clearing
+    ...
+
+    Object   tree "tall sycamore tree" clearing
+    ...
+
+We used the third of the header items to say that the clearing was the
+parent of the nest, and also that the clearing was the parent of the tree;
+that is, both nest and tree are child objects of the clearing.
+
+.. note::
+
+   A "room" isn't anything magical; it's just an object which *never* has a
+   parent, and which *may* from time to time have the player object as a
+   child.
+
+When we defined the bird, we placed it in the forest, like so::
+
+    Object   bird "baby bird" forest
+    ...
+
+We didn't place any other objects in that room, so at the start of the game
+the forest was the parent of the bird (and the bird was the only child of
+the forest).  But what happens when the player character, initially in the
+``before_cottage`` room, goes EAST to the forest?  Answer: the player's
+parent is now the forest, and the forest has two children -- the bird *and*
+the player.  This is a key principle of the way Inform manages its objects:
+the parent--child relationships between objects change continuously, often
+dramatically, as the game progresses.
+
+Another example of this: suppose the player character picks up the bird.
+This causes another change in the relationships.  The bird is now a child
+of the player (and *not* of the forest), and the player is both a parent
+(of the bird) and a child (of the forest).
+
+In this diagram, we show how the object relationships change during the
+course of the game.  The straight lines represent parent--child
+relationships, with the parent object at the top of the line, and the child
+object at the bottom.
+
+.. list-table::
+   :widths: 1 3 5
+
+   * - 1.
+     - At the start of the game:
+     - .. image:: /images/heidiobj1.*
+
+   * - 2.
+     - The player types: ``GO EAST``
+     - .. image:: /images/heidiobj2.*
+
+   * - 3.
+     - The player types: ``TAKE THE BIRD``
+     - .. image:: /images/heidiobj3.*
+
+   * - 4.
+     - The player types: ``GO NORTHEAST``
+     - .. image:: /images/heidiobj4.*
+
+   * - 5.
+     - The player types: ``PUT BIRD IN NEST``
+     - .. image:: /images/heidiobj5.*
+
+   * - 6.
+     - The player types: ``TAKE NEST``
+     - .. image:: /images/heidiobj6.*
+
+   * - 7.
+     - The player types: ``UP``
+     - .. image:: /images/heidiobj7.*
+
+   * - 8.
+     - The player types: ``PUT NEST ON BRANCH``
+     - .. image:: /images/heidiobj8.*
+
+In this short example, we've taken a lot of time and space to spell out
+exactly how the objects relationship patterns -- generally known as the
+**object tree** -- appear at each stage.  Normally you wouldn't bother with
+this much detail (a) because the interpreter does most of the work for you,
+and (b) because in a real game there are usually too many objects for you
+to keep track of.  What's important is that you understand the basic
+principles: at any moment in time an object either has no parent (which
+probably means either that it's a room, or that it's floating in hyperspace
+and not currently part of the game) or exactly one parent -- the object
+that it's "in" or "on" or "a part of".  However, there's no restriction on
+the number of children that an object can have.
+
+There's a practical use for these relationships, covered in detail further
+on.  As a designer, you can refer to the current parent or children of any
+given object with the ``parent``, ``child`` and ``children`` routines, and
+this is one feature that you will be using frequently.  There are also
+other routines associated with the object tree, to help you keep track of
+the objects or move them around.  We'll see them one by one in the next
+chapters.  For a quick summary, see "Objects" on page 177.
+
+Things in quotes
+================
+
+Inform makes careful distinction between double and single quotes.
+
+.. rubric:: Double quotes
+
+Double quotes "..." surround a **string** -- a letter, a word, a paragraph,
+or almost any number of characters -- which you want the interpreter to
+display while the game is being played.  You can use the tilde ``~`` to
+represent a double quote inside the string, and the circumflex ``^`` to
+represent a newline (line break) character.  Upper-case and lower-case
+letters are treated as different.
+
+A long string can be split over several lines; Inform transforms each line
+break (and any spaces around it) into a single space (extra spaces not at a
+line break are preserved, though).  These two strings are equivalent::
+
+    "This is a      string of characters."
+
+    "This
+      is
+            a    string
+                       of characters."
+
+When the interpreter displays a long character string -- for example, while
+describing a feature-packed room -- it employs automatic word-wrapping to
+fit the text to the player's screen.  This is where you might insert ``^``
+characters to force line breaks to appear, thus presenting the text as a
+series of paragraphs.  So far, we've seen strings used as the value of a
+``Constant``::
+
+    Constant Headline
+          "^A simple Inform example
+           ^by Roger Firth and Sonja Kesserich.^";
+
+which could equally have been defined thus::
+
+    Constant Headline
+          "^A simple Inform example^by Roger Firth and Sonja Kesserich.^";
+
+and as the value of an object description property::
+
+    description "Too young to fly, the nestling tweets helplessly.",
+
+Later, you'll find that they're also very common in ``print`` statements.
+
+.. rubric:: Single quotes
+
+Single quotes '...' surround a **dictionary word**.  This has to be a
+single word -- no spaces -- and generally contains only letters (and
+occasionally numbers and hyphens), though you can use ``^`` to represent an
+apostrophe inside the word.  Upper-case and lower-case letters are treated
+as identical; also, the interpreter normally looks only at the first nine
+characters of each word that the player types.
+
+When the player types a command, the interpreter divides what was typed
+into individual words, which it then looks up in the dictionary.  If it
+finds all the words, and they seem to represent a sensible course of
+action, that's what happens next.
+
+So far, we've seen dictionary words used as the values of an object
+``name`` property::
+
+     name 'bird^s' 'nest' 'twigs' 'moss',
+
+and indeed that's just about the only place where they commonly occur.
+You'll save yourself a lot of confusion by remembering the distinction:
+Double quotes for Output, Single quotes for Input (DOSI).
+
+Routines and statements
+=======================
+
+A routine is a collection of statements, which are performed (or we often
+say "are executed") at run-time by the interpreter.  There are two types of
+routine, and about two dozen types of statement (there's a complete list in
+"Statements" on page 174; see also "Inform language" on page 257).
+
+.. rubric:: Statements
+
+A **statement** is an instruction telling the interpreter to perform a
+particular task -- to "do something" -- while the game is being played.  A
+real game usually has lots and lots of statements, but so far we've
+encountered only a few.  We saw::
+
+     location = before_cottage;
+
+which is an example of an **assignment** statement, so-called because the
+equals sign ``=`` assigns a new value (the internal ID of our
+``before_cottage`` room) to a variable (the global variable ``location``
+which is part of the library).  Later we saw::
+
+     if (nest in branch) deadflag = 2;
+
+which is actually *two* statements: an assignment, preceded by an ``if``
+statement::
+
+     if (nest in branch) ...
+
+The ``if`` statement tests a particular condition; if the condition is
+true, the interpreter executes whatever statement comes next; if it isn't
+true, the interpreter ignores the next statement.  In this example, the
+interpreter is testing whether the ``nest`` object is "in" or "on" (which
+we now know means "is a child of") the ``branch`` object.  For most of the
+game, that condition is not true, and so the interpreter ignores the
+following statement.  Eventually, when the condition becomes true, the
+interpreter executes that statement: it performs an assignment::
+
+    deadflag = 2;
+
+which changes the value of the library variable ``deadflag`` from its
+current value to 2.  Incidentally, if statements are often written on two
+lines, with the "controlled" statement indented.  This makes it easier to
+read, but doesn't change the way that it works::
+
+    if (nest in branch)
+        deadflag = 2;
+
+The thing that's being controlled by the ``if`` statement doesn't have to
+be an assignment; it can be any kind of statement.  In fact, you can have
+lots of statements, not just one, controlled by an ``if`` statement.  We'll
+talk about these other possibilities later.  For now, just remember that
+the only place where you'll find statements are within standalone routines
+and embedded routines.
+
+.. rubric:: Standalone routines
+
+A **standalone routine** is a series of statements, collected together and
+given a name.  When the routine is "called" -- by its given name -- those
+statements are executed.  Here's the one that we've defined::
+
+    [ Initialise; location = before_cottage; ];
+
+Because it's such a tiny routine, we placed it all on a single line.  Let's
+rewrite it to use several lines (as with the ``if`` statement, this improves
+the readability, but doesn't affect how it works)::
+
+    [ Initialise;
+        location = before_cottage;
+    ];
+
+The ``[ Initialise;`` is the start of the routine, and defines the name by
+which it can be "called".  The ``];`` is the end of the routine.  In
+between are the statements -- sometimes known as the body of the routine --
+which are executed when the routine is called.  And how is that done?  By a
+statement like this::
+
+    Initialise();
+
+That single statement, the routine's name followed by opening and closing
+parentheses, is all that it takes to call a routine.  When it comes across
+a line like this, the interpreter executes the statements -- in this
+example there's only one, but there may be ten, twenty, even a hundred of
+them -- in the body of the routine.  Having done that, the interpreter
+resumes what it was doing, on the line following the ``Initialise();``
+call.
+
+.. note::
+
+   You may have noticed that, although we've defined a routine named
+   ``Initialise``, we've never actually called it.  Don't worry -- the
+   routine is called, by the Inform library, right at the start of a game.
+
+.. rubric:: Embedded routines
+
+An **embedded routine** is much like a standalone routine, though it
+doesn't have a name and doesn't end in a semicolon.  This is the one that
+we defined::
+
+     [; if (nest in branch) deadflag = 2; ]
+
+except that we didn't write it in isolation like that: instead, we defined
+it to be the value of an object property::
+
+     each_turn [; if (nest in branch) deadflag = 2; ],
+
+which would have worked just the same if we'd written it like this::
+
+     each_turn [;
+         if (nest in branch)
+             deadflag = 2;
+     ],
+
+All embedded routines are defined in this manner: as the value of an object
+property.  That's where they're embedded -- inside an object.  The
+introductory characters ``[;`` maybe look a little odd, but it's really
+only the same syntax as for a standalone routine, only without a name
+between the ``[`` and ``;``.
+
+For calling an embedded routine, thus causing the statements it contains to
+be executed, the method that we described for a standalone routine won't
+work.  An embedded routine has no name, and needs none; it's
+*automatically* called by the library at appropriate moments, which are
+determined by the role of the property for which it is the value.  In our
+example, that's at the end of every turn in which the player character is
+in the same room as the branch.  Later, we'll see other examples of
+embedded routines, each designed to perform a task which is appropriate for
+the property whose value it is; we'll also see that it is possible to call
+an embedded routine yourself, using an ``obj_id.property()`` syntax -- in
+this example, we could call the routine by writing ``branch.each_turn()``.
+There's more about these topics in "Routines and arguments" on page 67, "A
+diversion: working with routines" on page 104 and in "Routines" on
+page 179.
+
+That ends our review of the ground covered in our first game.  We'll have
+more to say about most of this later, but we're trying not to overload you
+with facts at this early stage.  What we'd like you to do is to look back
+at the source of the game, and ensure that you can recognise all the
+elements which this chapter has described.  Then, we'll move on to fix a
+few of the game's more important defects.
diff --git a/images/heidiobj1.png b/images/heidiobj1.png
new file mode 100644 (file)
index 0000000..6caa0e3
Binary files /dev/null and b/images/heidiobj1.png differ
diff --git a/images/heidiobj2.png b/images/heidiobj2.png
new file mode 100644 (file)
index 0000000..255a32a
Binary files /dev/null and b/images/heidiobj2.png differ
diff --git a/images/heidiobj3.png b/images/heidiobj3.png
new file mode 100644 (file)
index 0000000..bfd73a5
Binary files /dev/null and b/images/heidiobj3.png differ
diff --git a/images/heidiobj4.png b/images/heidiobj4.png
new file mode 100644 (file)
index 0000000..082d70d
Binary files /dev/null and b/images/heidiobj4.png differ
diff --git a/images/heidiobj5.png b/images/heidiobj5.png
new file mode 100644 (file)
index 0000000..aef4113
Binary files /dev/null and b/images/heidiobj5.png differ
diff --git a/images/heidiobj6.png b/images/heidiobj6.png
new file mode 100644 (file)
index 0000000..985fe15
Binary files /dev/null and b/images/heidiobj6.png differ
diff --git a/images/heidiobj7.png b/images/heidiobj7.png
new file mode 100644 (file)
index 0000000..46ab2b7
Binary files /dev/null and b/images/heidiobj7.png differ
diff --git a/images/heidiobj8.png b/images/heidiobj8.png
new file mode 100644 (file)
index 0000000..c4ade78
Binary files /dev/null and b/images/heidiobj8.png differ