DM4 §4: ‘Ruins’ begun

## §4 ‘Ruins’ begun

This chapter introduces five fundamentals of Inform: how to construct games; messages, classes and actions; and how to debug games. Chapter III then makes a systematic exploration of the model world available to Inform games. Throughout both chapters, examples gradually build up a modest game called ‘Ruins’, a tale of Central American archaeology in the 1930s. Here is its first state:

    Constant Story "RUINS";
    Constant Headline "^An Interactive Worked Example^
                 Copyright (c) 1999 by Angela M. Horns.^";
    Include "Parser";
    Include "VerbLib";
    Object Forest "~Great Plaza~"
     with description
              "Or so your notes call this low escarpment of limestone,
              but the rainforest has claimed it back. Dark olive
              trees crowd in on all sides, the air steams with the
              mist of a warm recent rain, midges hang in the air.
              ~Structure 10~ is a shambles of masonry which might
              once have been a burial pyramid, and little survives
              except stone-cut steps leading down into darkness below.",
    has  light;
    [ Initialise;
      location = Forest;
      "^^^Days of searching, days of thirsty hacking through the briars of
      the forest, but at last your patience was rewarded. A discovery!^";
    ];
    Include "Grammar";

If you can compile this tiny beginning successfully, Inform is probably set up and working properly on your computer. Compilation may take a few seconds, because although you have only written twenty lines or so, the `Include` directives paste in another seven and a half thousand. This is “the Library”, a computer program which acts as umpire during play. The library is divided into three parts:

`Parser` which decodes what the player types;
`VerbLib` how actions, like “take” or “go north”, work;
`Grammar` the verbs and phrases which the game understands.

It does matter what order the three lines beginning with `Include` come in, and it sometimes matters where your own code goes with respect to them: objects shouldn't be declared until after the inclusion of the parser, for instance. For now, follow the structure above, with everything interesting placed between the inclusions of `VerbLib` and `Grammar`.

▲ Chapter I above said that every Inform program had to contain a routine called `Main`. Games like ‘Ruins’ are no exception, but their `Main` routine is part of the library, so that game designers do not need to write a `Main`.

· · · · ·

The two constants at the beginning are text giving the game's name and copyright message, which the library needs in order to print out the “banner” announcing the game. Similarly, the library expects to find a routine named `Initialise` somewhere in your source code. This routine is called when the game starts up, and is expected to carry out any last setting-up operations before play begins. In most games, it also prints up a ‘welcome’ message, but the one thing it has to do is to set the `location` variable to the place where the player begins. And this means that every game has to declare at least one object, too: the room where the player begins.

▲ In this book places are often called “rooms” even when outdoors (like `Forest`) or underground. This goes back at least to Stephen Bishop's 1842 map of the Mammoth and Flint Ridge cave system of Kentucky, which was the setting of the first adventure game, ‘Advent’, also called ‘Colossal Cave’ (c.1975). The author, Will Crowther, was a caver and used the word “room” in its caving sense. Don Woods, who recast the game in 1976–7, confused the word further with its everyday sense. Players of adventure games continue to call locations “rooms” to this day.

· · · · ·

‘Ruins’ is at this stage an exceedingly dull game:

Days of searching, days of thirsty hacking through the briars of the forest, but at last your patience was rewarded. A discovery!

RUINS
An Interactive Worked Example
Copyright (c) 1998 by Angela M. Horns.
Release 1 / Serial number 990220 / Inform v6.20 Library 6/8

“Great Plaza”
Or so your notes call this low escarpment of limestone, but the rainforest has claimed it back. Dark olive trees crowd in on all sides, the air steams with the mist of a warm recent rain, midges hang in the air. “Structure 10” is a shambles of masonry which might once have been a burial pyramid, and little survives except stone-cut steps leading down into darkness below.
>`inventory`
You are carrying nothing.
>`north`
You can't go that way.
>`wait`
Time passes.
>`quit`
Are you sure you want to quit? `yes`

· · · · ·

In an Inform game, objects are used to simulate everything: rooms and items to be picked up, scenery, the player, intangible things like mist and even some abstract ideas, like the direction “north” or the idea of “darkness”. The library itself is present as an object, called `InformLibrary`, though like the concept of “north” it cannot be picked up or visited during play. All told, ‘Ruins’ already contains twenty-four objects.

It is time to add something tangible, by writing the following just after the definition of `Forest`:

    Object -> mushroom "speckled mushroom"
      with name 'speckled' 'mushroom' 'fungus' 'toadstool';

The arrow `->` means that the mushroom begins inside the previous object, which is to say, the `Forest`. If the game is recompiled, the mushroom is now in play: the player can call it “speckled mushroom”, “mushroom”, “toadstool” and so on. It can be taken, dropped, looked at, looked under and so on. However, it only adds the rather plain line “There is a speckled mushroom here.” to the Forest's description. Here is a more decorative species:

    Object -> mushroom "speckled mushroom"
      with name 'speckled' 'mushroom' 'fungus' 'toadstool',
           initial
               "A speckled mushroom grows out of the sodden earth, on
               a long stalk.";

The `initial` message is used to tell the player about the mushroom when the Forest is described. (Once the mushroom has been picked or moved, the message is no longer used: hence the name ‘initial’.) The mushroom is, however, still “nothing special” when the player asks to “look at” or “examine” it. To provide a more interesting close-up view, we must give the mushroom its own `description`:

    Object -> mushroom "speckled mushroom"
      with name 'speckled' 'mushroom' 'fungus' 'toadstool',
           initial
               "A speckled mushroom grows out of the sodden earth, on
               a long stalk.",
           description
               "The mushroom is capped with blotches, and you aren't
               at all sure it's not a toadstool.",
      has  edible;

Now if we examine the mushroom, as is always wise, we get a cautionary hint. But the edible notation means that it can be eaten, so that for the first time the player can change the game state irrevocably: from a game with a forest and a mushroom into a game with just a forest.

The mushroom shows the two kinds of feature something can have: a “property” with some definite value or list of values and an “attribute”, which is either present or not but has no particular value. `name`, `initial` and `description` are all properties, while `light` and `edible` are attributes. The current state of these properties changes during play: for instance, it can be changed by code like the following.

    mushroom.description = "You're sure it's a toadstool now.";
    give mushroom light;
    if (mushroom has edible) print "It's definitely edible.^";

`light` is the attribute for “giving off light”. The `Forest` was defined as having `light` on account of daylight, so it doesn't much matter whether or not the mushroom has `light`, but for the sake of botanical verisimilitude it won't have `light` in the final game.

· · · · ·

Declaring objects has so far been a matter of filling in forms: fill some text into the box marked `description`, and so on. We could go much further like this, but for the sake of example it's time to add some rules:

    after [;
        Take: "You pick the mushroom, neatly cleaving its thin stalk.";
        Drop: "The mushroom drops to the ground, battered slightly.";
    ],

The property `after` doesn't just have a string for a value: it has a routine of its own. What happens is that after something happens to the mushroom, the library asks the mushroom if it would like to react in some way. In this case, it reacts only to `Take` and `Drop`, and the only effect is that the usual messages (“Taken.” “Dropped.”) are replaced by new ones. (It doesn't react to `Eat`, so nothing out of the ordinary happens when it's eaten.) ‘Ruins’ can now manage a briefly plausible dialogue:

“Great Plaza”
Or so your notes call this low escarpment of limestone, but the rainforest has claimed it back. Dark olive trees crowd in on all sides, the air steams with the mist of a warm recent rain, midges hang in the air. “Structure 10” is a shambles of masonry which might once have been a burial pyramid, and little survives except stone-cut steps leading down into darkness below.
A speckled mushroom grows out of the sodden earth, on a long stalk.
>`get mushroom`
You pick the mushroom, neatly cleaving its thin stalk.
>`look at it`
The mushroom is capped with blotches, and you aren't at all sure it's not a toadstool.
>`drop it`
The mushroom drops to the ground, battered slightly.

▲ Gareth Rees persuasively advocates writing this sort of transcript, of an ideal sequence of play, first, and worrying about how to code up the design afterwards. Other designers prefer to build from the bottom up, crafting the objects one at a time and finally bringing them together into the narrative.

· · · · ·

The mushroom is a little more convincing now, but still does nothing. Here is a more substantial new rule:

    before [;
        Eat: if (random(100) <= 30) {
                 deadflag = true;
                 "The tiniest nibble is enough. It was a toadstool,
                 and a poisoned one at that!";
             }
             "You nibble at one corner, but the curious taste
             repels you.";
    ],

The library consults `before` just before the player's intended action would take place. So when the player tries typing, say, “eat the mushroom", what happens is: in 30% of cases, death by toadstool poisoning; and in the other 70%, a nibble of a corner of fungus, without consuming it completely.

Like `location`, `deadflag` is a variable belonging to the library. It's normally `false`, meaning that the player is still alive and playing. Setting it to `true` thus kills the player. (Setting it to 2 causes the player to win the game and there are other uses: see §21.)

If the “tiniest nibble” text is printed, the rule ends there, and does not flow on into the second “You nibble at” text. So one and only one message is printed. Here is how this is achieved: although it's not obvious from the look of the program, the `before` routine is being asked the question “Do you want to interfere with the usual rules?”. It must reply, that is, return, either `true` or `false` meaning yes or no. Because this question is asked and answered many times in a large Inform game, there are several abbreviations for how to reply. For example,

`return true;` and `rtrue;`

both do the same thing. Moreover,

    print_ret "The tiniest nibble... ...at that!";

performs three useful tasks: prints the message, then prints a carriage return, and then returns `true`. And this is so useful that a bare string

    "The tiniest nibble... ...at that!";

is understood to mean the same thing. To print the text without returning, the statement `print` has to be written out in full. Here is an example:

    before [;
        Taste: print "You extend your tongue nervously.^";
            rfalse;
    ];

In this rule, the text is printed, but the answer to “Do you want to interfere?” is no, so the game will then go on to print something anodyne like “You taste nothing unexpected.” (In fact the `rfalse` was unnecessary, because if a rule like this never makes any decision, then the answer is assumed to be false.)

• EXERCISE 1
The present `after` routine for the mushroom is misleading, because it says the mushroom has been picked every time it's taken (which will be odd if it's taken, dropped then taken again). Correct this.

· · · · ·

The following example of “form-filling” is typical of the way that the library provides for several standard kinds of object. This one is a kind of door, which will be gone into properly in §13, but for now suffice to say that a door doesn't literally have to be a door: it can be any object which comes in between where the player is and where the player can go. Because the object is also marked as `scenery` (see §8), it isn't given any special paragraph of description when the Forest is described. Finally, it is marked as `static` to prevent the player from being able to pick it up and walk off with it.

    Object -> steps "stone-cut steps"
      with name 'steps' 'stone' 'stairs' 'stone-cut' 'pyramid' 'burial'
                'structure' 'ten' '10',
           description
               "The cracked and worn steps descend into a dim chamber.
               Yours might be the first feet to tread them for five
               hundred years.",
           door_to Square_Chamber,
           door_dir d_to
      has  scenery static door open;

We also need to add a new line to the Forest's definition to tell it that the way down is by these steps:

    Object Forest "~Great Plaza~"
           ...
           d_to steps,

Now “examine structure 10”, “enter stone-cut pyramid” and so forth will all work.

• EXERCISE 2
Except of course that now ‘Ruins’ won't compile, because Inform expects to find a room called `Square_Chamber` which the steps lead to. Design one.