RB §1.1. Preface

The Inform Recipe Book is one of two interlinked books included with Inform 7: a comprehensive collection of examples, showing the practical use of Inform. The other book is Writing with Inform, a systematic manual for the software. If you are reading this within the Inform application, you will see that the Recipe Book pages are on "yellow paper", while the manual is on "white paper".

The Recipe Book assumes that the reader already knows the basics covered in Chapters 1 and 2 of Writing with Inform: enough to get simple projects working in the Inform application. It's helpful, but not necessary, to have some familiarity with the main ingredients of Inform. For instance, the reader who can play and test the following source text, and who can take a guess at what it ought to do, should be fine:

"The Power of the Keys"

Afterlife is a room. "Fluffy white clouds gather round you here in the afterlife." The Pearly Gates are a door in Afterlife. "The Pearly Gates - large, white, wrought-iron and splendidly monumental - stand above you." Heaven is a room. The Gates are above the Afterlife and below Heaven.

St Peter is a man in the Afterlife. "St Peter, cheery if absent-minded, studies his celestial clipboard."

Before going through the Pearly Gates:
    say "St Peter coughs disarmingly. 'If you'd read your Bible,' he says, 'you might recall Revelation 21:21 saying that the twelve gates were twelve pearls, each gate being made from a single pearl. I really don't know why people keep imagining it like the entrance to some sort of public park - oh, well. In you go.'";
    end the story.

Test me with "enter gates".

The Recipe Book is not a tutorial - it offers advice and examples to crib from, not theory or systematic teaching. The examples here are provided with the express intention that authors cut and paste useful passages into their own works, modifying as they go. This is an excellent way to get things working quickly.

In the traditional saying: good programmers write good code, but great programmers steal it. (Appropriately enough, nobody seems to know who said this first.) For the avoidance of any doubt - the example text is here to be taken, and this infringes no copyright, and requires no acknowledgement. So steal at will. The examples are a part of Inform itself, and as such, they are available to anyone who accepts the Inform licence.

Many programming languages for conventional computing, such as C, come with elaborate libraries of ready-written code - so elaborate, in fact, that they often need much larger manuals than the language itself, and can be hard to learn. Even expert programmers typically use only a small part of what is available in such libraries, giving up on the rest as too complex to use, or too difficult to find out about, or not quite what they need.

The designers of Inform chose not to go down this road. Rather than providing a general system for liquids (say), which would have to be a quite complicated and opaque program, Inform provides a choice of examples showing how to get different effects. The writer can read the text which achieves these effects, and can simply cut and paste whatever might be useful, and rewrite whatever is not quite wanted.

The wider community of Inform writers has made a great wealth of material available in the form of Extensions, too, and under a Creative Commons Attribution licence requiring only a namecheck: we don't cover the Extensions in this book, because it would grow far too long and be a constant labour to maintain, but it's well worth seeing what is out there.

See also

Acknowledgements for a chance to try out the cross-referencing links in the Recipe Book - click on the red asterisk or the name of the destination to go there

Examples

1. About the examples

This is the first of about 400 numbered examples. In a few cases, such as this one, they provide a little background information, but almost all demonstrate Inform source text. The techniques demonstrated tend to be included either because they are frequently asked for, or because they show how to achieve some interesting effect.

The same examples are included in both of the books of documentation, but in a different order: in Writing with Inform, they appear near the techniques used to make them work; in The Inform Recipe Book, they are grouped by the effects they provide. For instance, an example called "Do Pass Go", about the throwing of a pair of dice, appears in the "Randomness" section of Writing with Inform and also in the "Dice and Playing Cards" section of The Inform Recipe Book. Clicking the italicised WI and RB buttons at the right-hand side of an example's heading switches between its position in each book.

Many computing books quote excerpts from programs, but readers have grown wary of them: they are tiresome to type in, and may only be fragments, or may not ever have been tested. The authors of Inform have tried to avoid this. All but two dozen examples contain entire source texts. A single click on the paste icon paste.png (always placed just left of the double-quoted title) will write the complete source text into the Source panel. All that is then required is to click the Go button, and the example should translate into a working game.

In most cases, typing the single command TEST ME will play through a few moves to show off the effect being demonstrated. (You may find it convenient to create a "scratch" project file for temporary trials like this, clearing all its text and starting again with each new test.)

As part of the testing process which verifies a new build of Inform, each example in turn is extracted from this documentation, translated, played through, and the resulting transcript mechanically checked. So the examples may even work as claimed. But the flesh is weak, and there are bound to be glitches. We would welcome reports, so that future editions can be corrected.

Each example is loosely graded by difficulty: if they were exercises in a textbook, the asterisks would indicate how many marks each question scores. As a general rule:

asterisk.png - A simple example, fairly easily guessed.
asterisk.png asterisk.png - A complicated or surprising example.
asterisk.png asterisk.png asterisk.png - An example needing detailed knowledge of many aspects of the system.
asterisk.png asterisk.png asterisk.png asterisk.png - A complete scenario, containing material not necessarily relevant to the topic being demonstrated.

In general, the main text of Writing with Inform tries never to assume knowledge of material which has not yet appeared, but the trickier examples almost always need to break this rule.

12. Midsummer Day

paste.png "Midsummer Day"

East of the Garden is the Gazebo. Above is the Treehouse. A billiards table is in the Gazebo. On it is a trophy cup. A starting pistol is in the cup. In the Treehouse is a container called a cardboard box.

Test me with "up / x box / d / e / x table / x cup / x pistol / get cup".

RB §1.2. Acknowledgements

David Fisher's "Past raif topics" pages on the Interactive Fiction Wiki were an invaluable tool during the early design of these examples, as they catalog an enormous assortment of implementation problems encountered by IF authors over the past fifteen years.

Thanks also go to Nick Montfort for several conversations during the development of Inform: these inspired a number of ideas about how the author should be able to control the textual output of a story, and suggested specific problem areas to work on.

Jeff Nyman provided extensive feedback about using Writing with Inform in workshops of aspiring IF authors from both programming and conventional fiction writing backgrounds. His observations about the concerns of conventional writers first encountering IF were especially useful, and had a great influence on the organization of the Recipe Book. While the results may not meet all the needs he identified, we hope to have taken a step in the right direction.

A few examples were contributed by denizens of rec.arts.int-fiction: Jesse McGrew, Jon Ingold, Mike Tarbert, Eric Rossing, and Kate McKee offered such elegant implementations of various tasks that we have folded their contributions (with permission) into the Recipe Book.

Finally, these pages owe much to the questions and suggestions of Inform users on rec.arts.int-fiction and ifMUD.

RB §1.3. Disenchantment Bay

"Disenchantment Bay" is a simple work of IF used as a running example in Chapter 3 of Writing with Inform - not so much a tutorial as a convenient hook on which to hang some demonstrations of the basics. Because the resulting examples only use basic features and in the most straightforward way, they make for uninteresting "recipes" - so they are not included in the Recipe Book proper. But some readers might like to have all twelve stages of the example gathered on a single page: this is that page.

Examples

14. Disenchantment Bay 1

To begin with the title:

paste.png "Disenchantment Bay"

There are many Disenchantment Bays across the world, named by eighteenth-century ships' captains - one in Antarctica, another in Tasmania, for instance. The most famous is probably the one where Lewis and Clark's expedition broke through to the Pacific. But ours is the one in Alaska, named in 1791 by a Spanish navigator who had hoped it might lead to the fabled Northwest Passage, and all of this history is beside the point since the game is set in the present day.

The Cabin is a room. "The front of the small cabin is entirely occupied with navigational instruments, a radar display, and radios for calling back to shore. Along each side runs a bench with faded blue vinyl cushions, which can be lifted to reveal the storage space underneath. A glass case against the wall contains several fishing rods.

Scratched windows offer a view of the surrounding bay, and there is a door south to the deck. A sign taped to one wall announces the menu of tours offered by the Yakutat Charter Boat Company."

We might want to start with the glass case.

The Cabin contains a glass case. In the glass case is a collection of fishing rods.

Now Inform will have guessed that the case is a container, but its default idea of a container is something like a bucket: permanently open and not able to be opened and shut. We can change that:

The case is closed, transparent, and openable.

We get a similar set of guesses if we write

The bench is in the cabin. On the bench are some blue vinyl cushions.

Using "some" rather than "a" or "the" tells Inform that the cushions are to be referred to as a plural object in the future. And because of the "on the bench..." phrase, Inform will guess that the bench is a supporter and that it is fixed in place and cannot be moved from room to room. We do have to tell it that the bench can be sat on, though:

The bench is enterable.

And now a short script, so that if we type TEST ME, we experiment with the case and bench:

Test me with "examine case / get rods / open case / get rods / sit on bench / take cushions / get up"

15. Disenchantment Bay 2

If we compile our last version of the cabin, we get a room where the glass case and the bench are listed separately from the room description, even though they have already been mentioned once. We can prevent this by making the already-mentioned things scenery:

paste.png "Disenchantment Bay"

The Cabin is a room. "The front of the small cabin is entirely occupied with navigational instruments, a radar display, and radios for calling back to shore. Along each side runs a bench with faded blue vinyl cushions, which can be lifted to reveal the storage space underneath. A glass case against the wall contains several fishing rods.

Scratched windows offer a view of the surrounding bay, and there is a door south to the deck. A sign taped to one wall announces the menu of tours offered by the Yakutat Charter Boat Company."

The Cabin contains a glass case. In the glass case is a collection of fishing rods. The case is closed, transparent, and openable. The case is scenery.

The bench is in the cabin. On the bench are some blue vinyl cushions. The bench is enterable and scenery. The cushions are scenery.

Generally speaking, it is a good idea to recognize the player's attempts to interact with any objects mentioned in the room description, so we should also provide

Some navigational instruments, some scratched windows, a sign, a radar display, and some radios are scenery in the cabin.

Test me with "examine instruments / x windows / x sign / x display / x radios".

The door and the view will need to be done as well, but they are special cases which we will get to shortly.

As noted, making something scenery also means that the player will be prevented from picking it up and carrying it away. This is sensible, though: if an object can be removed from the room where it first appears, we should be careful about mentioning it in the main room description; otherwise, it will continue to be described as present even when someone has carried it off.

17. Disenchantment Bay 3

Suppose we wanted to have the glacier visible from the Cabin of our boat, and anywhere else we might add to the game:

The view of the Malaspina glacier is a backdrop. It is everywhere. The description is "The Malaspina glacier covers much of the nearby slope, and -- beyond it -- an area as large as Rhode Island."

18. Disenchantment Bay 4

Currently we have provided objects for most of what is on the boat, but it's not very interesting to look at. We might want to give some more description to these things.

paste.png "Disenchantment Bay"

The Cabin is a room. "The front of the small cabin is entirely occupied with navigational instruments, a radar display, and radios for calling back to shore. Along each side runs a bench with faded blue vinyl cushions, which can be lifted to reveal the storage space underneath. A glass case against the wall contains several fishing rods.

Scratched windows offer a view of the surrounding bay, and there is a door south to the deck. A sign taped to one wall announces the menu of tours offered by the Yakutat Charter Boat Company."

The Cabin contains a glass case. In the glass case is a collection of fishing rods. The case is closed, transparent, and openable. The case is scenery.

The bench is in the cabin. On the bench are some blue vinyl cushions. The bench is enterable and scenery. The cushions are scenery.

Some navigational instruments, some scratched windows, a radar display, and some radios are scenery in the cabin.

The description of the instruments is "Knowing what they do is the Captain's job."

The description of the windows is "They're a bit the worse for wear, but you can still get an impressive view of the glacier through them. There were whales earlier, but they're gone now."

The description of the radar is "Apparently necessary to avoid the larger icebergs."

The description of the radios is "With any luck you will not need to radio for help, but it is reassuring that these things are here."

The order in which we define these things is fairly open. We could also define an object so:

A sign is scenery in the Cabin. The description is "You can get half-day and full-day sight-seeing tours, and half-day and full-day fishing trips."

Where "the description" is assumed to refer to the thing most recently defined, if no object is specified.

The view of the Malaspina glacier is a backdrop. It is everywhere. The description is "The Malaspina glacier covers much of the nearby slope, and -- beyond it -- an area as large as Rhode Island."

Test me with "examine sign / examine glacier / examine instruments / examine windows / examine radar / examine radios / take the cushions / take the glacier".

These last two commands show how scenery and backdrops are automatically impossible for the player to take.

20. Disenchantment Bay 5

We mentioned that there is a door out to the deck in our example. The following two sentences will create both the door and the other room:

paste.png The cabin door is south of the Cabin and north of the Deck. It is a door and scenery.

Now Inform has constructed a generic room called "Deck" to the south. It has neither a description nor any contents yet, but we could fix that in time. It does have a view of the glacier, though, since we defined the glacier view to be everywhere.

23. Disenchantment Bay 6

It stands to reason that the captain wouldn't let just anyone meddle with his fishing equipment; maybe he keeps that case locked. We could replace the case description with this one, instead:

paste.png The Cabin contains a glass case. In the glass case is a collection of fishing rods. The case is closed, transparent, openable, lockable, and locked. The case is scenery. The small silver key unlocks the case.

Now there's a silver key that will unlock it -- though since we haven't said where the key is, the player will never be able to find it in the game. (If we look at the World index, we find "small silver key" right at the bottom, not inside any of the rooms. That is as good as not existing at all -- though we usually use the term "out of play" -- but as we will later see, it is possible to have things initially out of play but brought into existence later on.)

25. Disenchantment Bay 7

If we would like the player to be able to turn instrumentation on and off, we could add a line to this effect:

paste.png The radar, the instruments, and the radios are devices.

And since the captain is probably not navigating blind, we might also want to say

The radar and the instruments are switched on.

30. Disenchantment Bay 9

Now finally we can put a Captain in the boat:

paste.png The Captain is a man in the Cabin. "The captain sits at the wheel, steering the boat and occasionally checking the radar readout."

33. Disenchantment Bay 10

At this point we can dress both the Captain and the player with some appropriate props:

paste.png The captain wears a baseball cap. The description of the cap is "It says, THE WORST DAY FISHING IS BETTER THAN THE BEST DAY WORKING."

The player is carrying a backpack and a bottle of water. The player is wearing a pair of sunglasses. The description of the sunglasses is "The light off the water and the ice does get pretty bright sometimes."

(At present the backpack can't be worn, but see the next version.)

34. Disenchantment Bay 11

If we wanted, we could make the player's backpack infinitely capacious, so:

paste.png The backpack is a player's holdall.

...And now whenever the player character is unable to hold everything, he will automatically stow some of his possessions therein.

This is only useful if the player doesn't have infinite carrying capacity himself, so perhaps we also need

paste.png The carrying capacity of the player is 3.

Perhaps mercifully, items which are worn are not counted against the player's carrying capacity. We might want to let him take advantage of that, too:

paste.png The backpack is wearable.

This capacity system makes a compromise between the realistic and the absurd: on the one hand, it acknowledges that people can't carry an infinite number of items in their hands, while at the same time providing a sack that can.

Many games will have no use for object-juggling of this kind at all; others will want to be much more rigorous about questions of capacity and volume. Fortunately, it is easy to leave the whole business out by assigning no carrying capacity to anything.

28. Disenchantment Bay 8 ★★

We probably do not need a vehicle to ride around our boat, but there might be a heavy ice chest that can only be pushed from room to room:

paste.png The ice chest is a closed openable container in the Deck. "A very heavy ice chest sits on the ground." It is fixed in place and pushable between rooms. A quantity of ice is in the chest. The description is "Ready and waiting just in case there's any fish needing to be kept cool."

This anticipates a later chapter, but it would probably be a good idea to hint to the player, if he tries to take the ice chest, that there is another way to move it:

Instead of taking the chest: say "It's too heavy to lift, but you might be able to push it, and just inch it over the frame of the door."

Otherwise, attempts to pick it up will just reply with "That's fixed in place."

37. Disenchantment Bay 12 ★★★★

paste.png "Disenchantment Bay"

Include Locksmith by Emily Short.

Use scoring.

The Cabin is a room. "The front of the small cabin is entirely occupied with navigational instruments, a radar display, and radios for calling back to shore. Along each side runs a bench with faded blue vinyl cushions[if the compartment is closed], which can be lifted to reveal the storage space underneath[otherwise], one of which is currently lifted to allow access to the storage compartment within[end if]. A glass case against the wall contains several fishing rods.

Scratched windows offer a view of the surrounding bay, and there is a door south to the deck. A sign taped to one wall announces the menu of tours offered by the Yakutat Charter Boat Company."

The Cabin contains a glass case. In the glass case is a collection of fishing rods. Understand "rod" as the collection. The case is closed, transparent, openable, lockable, and locked. The case is scenery. The small silver key unlocks the case.

The bench is in the cabin. On the bench are some blue vinyl cushions. The bench is enterable and scenery. The cushions are scenery.

A storage compartment is an openable closed container. It is part of the bench. Instead of opening the bench, try opening the storage compartment. Instead of closing the bench, try closing the storage compartment. Instead of pushing or pulling or turning the cushions, try opening the storage compartment. Understand "space" as the storage compartment.

Some nets and a Coke are in the compartment. Understand "net" as the nets. The description of the nets is "They must have something to do with fish as well. Really, you're just here for the sights." The nets are a container.

Some navigational instruments, some scratched windows, a radar display, and some radios are scenery in the cabin. The radar, the instruments, and the radios are devices. The radar and the instruments are switched on.

A screen is part of the radar. The description of the screen is "[if the radar is switched on]Phantom lights move across the screen.[otherwise]The screen is dark.[end if]". Instead of doing something other than examining to the screen, say "It's not good for much but looking at."

The Captain is a man in the Cabin. "The captain sits at the wheel, steering the boat and occasionally checking the radar readout." The captain wears a baseball cap. The description of the cap is "It says, THE WORST DAY FISHING IS BETTER THAN THE BEST DAY WORKING." The captain carries the silver key. The description of the captain is "[The captain] is wearing [a list of things worn by the captain][if the captain carries something] and carrying [a list of things carried by the captain][end if]."

The description of the instruments is "Knowing what they do is the Captain's job." Instead of doing something other than examining to the instruments in the presence of the Captain: say "The Captain glares at you. Clearly you are not welcome to do that."

The description of the windows is "They're a bit the worse for wear, but you can still get an impressive view of the glacier through them. There were whales earlier, but they're gone now." Understand "window" as the windows.

The description of the radar is "Apparently necessary to avoid the larger icebergs."

The description of the radios is "With any luck you will not need to radio for help, but it is reassuring that these things are here."

A sign is scenery in the Cabin. The description is "You can get half-day and full-day sight-seeing tours, and half-day and full-day fishing trips."

The view of the Malaspina glacier is a backdrop. It is everywhere. The description is "The Malaspina glacier covers much of the nearby slope, and -- beyond it -- an area as large as Rhode Island." Understand "view of the surrounding bay" or "surrounding bay" as the view.

The cabin door is south of the Cabin and north of the Deck. It is a door and scenery. The description of the Deck is "The whole back half of the boat is open, allowing you to view the surroundings without intervening windows -- if you can stand the cold."

The ice chest is a closed openable container in the Deck. "A very heavy ice chest sits on the ground." It is fixed in place and pushable between rooms.

A quantity of ice is in the Deck. "All around the boat bob chunks of glacier ice." Understand "glacier ice" as the quantity. The description is "Curiously cooled into funny-shaped chunks." The printed name of the quantity is "glacier ice".

Instead of taking the quantity of ice when the player is not carrying the nets:
    if the quantity of ice is handled, continue the action;
    say "You are having a hard time fishing out the ice with your bare hands."

Instead of taking the quantity of ice when the player is carrying the nets:
    if the quantity of ice is handled or the quantity of ice is in the nets, continue the action;
    now the quantity of ice is in the nets;
    say "You scoop up the ice with the net."

Instead of taking the chest: say "It's too heavy to lift, but you might be able to push it, and just inch it over the frame of the door."

The player is carrying a backpack. The player is wearing a pair of sunglasses. The description of the sunglasses is "The light off the water and the ice does get pretty bright sometimes."

The backpack is a player's holdall. The carrying capacity of the player is 3. The backpack is wearable.

Instead of asking the Captain for the key:
    say "'Sure, you can -- well, get me a drink first, would you?'"

Instead of asking the Captain for the key when the Captain is carrying a cold Coke and the Captain is carrying the key:
    move the key to the player;
    say "'Here, knock yourself out.'"

Instead of asking the Captain for the key when the Captain is not carrying the key: say "'I already gave it to you. You didn't lose it, did you?'"

Heat is a kind of value. The heats are cold, cool, room temperature, and warm.

A beverage is a kind of thing. A beverage can be open or closed. A beverage can be openable or unopenable. A beverage is always edible and openable. A beverage has a heat. A beverage is usually warm. The Coke is a beverage. The beer is a beverage. The beer is in the backpack.

Instead of giving or showing a beer to the Captain:
    say "'I don't drink on the job, thanks,' he says. 'You can help yourself if you want it, though.'"

Instead of giving or showing a Coke to the Captain:
    say "'It needs chilling,' the Captain remarks, disgruntled."

Instead of giving or showing a cold Coke to the Captain:
    move the Coke to the Captain;
    increase the score by 2;
    say "'Ah, thank you,' he says. How he can drink an iced soda on a day like today is an open question, but Alaskans are special."

Every turn when the quantity of ice is in the ice chest:
    repeat with item running through beverages in the ice chest:
        let the current heat be the heat of the item;
        if the current heat is not cold, now the heat of the item is the heat before the current heat.

Before printing the name of a beverage (called the drink):
    say "[heat of the drink] ".

Understand the heat property as describing a beverage.

The maximum score is 5.

After taking the fishing rods:
    end the story finally;
    increase the score by 3;
    say "Success is yours! (Now if only you knew anything about fishing.)"

Test me with "test first / test second / test third".

Test first with "x captain / open case / i / ask captain for the key / give beer to captain / open bench / x nets / get nets / get coke / give coke to captain".

Test second with "s / open chest / drop nets / get glacier ice / get nets / get glacier ice / g / put glacier ice in chest / get coke / put coke in chest".

Test third with "x coke / g / g / g / get coke / n / give coke to captain / ask captain for key / open case / get rods".

RB §1.4. Information Only

One last preliminary: a handful of the examples do not show how to do anything at all, but are really sidebars of information. Those examples are gathered below, since they contribute nothing by way of recipes.

Examples

415. About Inform's regular expression support

There is not really any unanimity about what regular expression language is. The unix tools sed and grep extend on Kleene's original grammar. Henry Spencer's regex library extended on this again, and was a foundation for Perl, but Perl once again went further. Philip Hazel's PCRE, despite the name Perl Compatible Regular Expressions, makes further extensions still, and so on.

Inform's regular expressions are modelled on those of Perl, as the best de facto standard we have, but a few omissions have been inevitable. Inform's regex matcher must occupy source code less than one hundredth the size of PCRE, and it has very little memory. Inform aims to behave exactly like Perl except as follows:

(i) Inform allows angle brackets as synonymous with square brackets, for reasons explained above. This means literal angle brackets have to be escaped as "\<" and "\>" in Inform regular expressions, which is unnecessary in Perl.

(ii) Inform only has single-line mode, not multiline mode: this removes need for the mode-switches "(?m)" and "(?s)" and the positional markers "\A" and "\Z". Multiline mode is idiosyncratic to Perl and is a messy compromise to do with holding long files of text as single strings, yet treating them as lists of lines at the same time: this would not be sensible for Inform. Similarly, because there is no ambiguity about how line breaks are represented in Inform strings (by a single "\n"), initial newline convention markers such as "(*ANYCRLF)" are unsupported.

(iii) The codes "\a", "\r", "\f", "\e", "\0" for alarm, carriage return, form feed, escape and the zero character are unsupported: none of these can occur in an Inform string.

(iv) Inform does not allow characters to be referred to by character code (whereas Perl allows "\036" for an octal character code, "\x7e" for a hexadecimal one, "\cD" for a control character). This is because we do not want the user to know whether text is internally stored as ZSCII or Unicode.

(v) Inform's character class "\p" (and its negation "\P") have no equivalent in Perl, and Inform's understanding of "\w" is different. Perl defines this as an upper or lower case English letter, underscore or digit, which is good for programming-language identifiers, but bad for natural language - for instance, "é" is not matched by "\w" in Perl, but unquestionably it appears in words. Inform therefore defines "\w" as the negation of "\s" union "\p".

(vi) Inform supports only single-digit grouping numbers "\1" to "\9", whereas Perl allows "\10", "\11", ...

(vii) POSIX named character ranges are not supported. These are only abbreviations in any case, and are not very useful. (Note that the POSIX range "[:punct:]", which is supposedly for punctuation, includes many things we do not want to think of that way - percentage signs, for instance - and so "\p" has a more natural-language-based definition.)

(viii) Character classes can be used inside ranges, so that "<\da-f>" is legal, but not as ends of contiguous runs, so that "<\d-X>" is not legal. (As reckless as this is, it is legal in Perl.)

(ix) For obvious reasons, escapes to Perl code using the notation "(?{...})" are unsupported, and so is the Perl iteration operator "\G".

(x) Perl's extended mode "(?x)", a lexical arrangement which allows expressions to be expanded out as little computer programs with comments, is unsupported. It would look awful syntax-coloured in the Inform interface and is not a style of coding to be encouraged.

Inform further does not support the Python extension of named subexpression groups, nor the Java extension of the possessive quantifier "++". There was only so much functionality we could squeeze in.

As verification of Inform's matching algorithm, we took the Perl 5 source code's notorious "re-test.txt" set of 961 test cases, removed the 316 using features unsupported by Inform (220 tested multiline mode, for instance), and ran the remaining 645 cases through Inform. It agrees with Perl on 643 of these: the two outstanding are -

(i) Perl is able to match "^(a\1?){4}$" against "aaaaaa" but Inform is not - Inform's backtracking is not as good when it comes to repetitions of groupings which are recursively defined. (Note that the optional "\1" match refers to the value of the bracketed expression which contains it, so that the interpretation is different on each repetition. Here to match we have to interpret "?" as 0, 0, 1, 0 repeats respectively as we work through the "{4}".)

(ii) Perl matches "((<a-c>)b*?\2)*" against "ababbbcbc" finding the match "ababb", whereas Inform finds the match "ababbbcbc". This is really a difference of opinion about whether the outer asterisk, which is greedy, should be allowed three matches rather than two if to do so requires the inner asterisk, which is not greedy, to eat more than it needs on one of those three matches.

Case (i) is a sacrifice to enable Inform's back-tracking to use less memory. Case (ii) simply seems unimportant.

223. Formal syntax of sentences ★★★

An entire grammar for the whole mass of Inform would not be linguistically interesting: it contains many convenient wordings which are not really part of a grand pattern. Inform does, however, have a formal notion of a Sentence, a grammatical structure which we shall call S. It is almost true that conditions ("if the flowerpot is on the wall") have the same grammar as assertions ("The flowerpot is on the wall") and "now" phrases ("now the flowerpot is on the wall"). All three use the S grammar, so we could define an assertion as "S.", say that "if S", "while S", "when S" and so on are conditions, and say that "now S" defines the "now" declaration.

Grammatical sentences do not necessarily make sense, of course. Many perfectly grammatical assertions in fact give rise to problem messages:

The wicker basket is not in the kitchen. (Unhelpfully negative.)
The wicker basket has been in the kitchen. (Talks about a time which never existed.)
The wicker basket is full. (Full of what? Too vague.)
The wicker basket is the ginger cat. (Demonstrably false.)

Whereas the first three, at least, would be sensible as conditions. So saying that assertions are "just like" conditions is a little misleading: what they have in common is S, the underlying grammar they each use as a starting-point.

To define S, we break it up into subsidiary structures. The most important is the Description Phrase (DP), examples of which include "the red basket", "somewhere lighted" and "an empty open container". Clearly sentences include DPs, but they also include other ingredients. The general pattern used in Inform is very simple:

1. S = DP + VP
2. VP = Verb + DP

where VP is another structure, the Verb Phrase. For instance:

S (The horseman wears a riding helmet)
    = DP (The horseman) + VP (wears a riding helmet)
VP (wears a riding helmet)
    = Verb (wears) + DP (a riding helmet)

In that example, the Verb was the single word "wears". More generally, Inform allows a Verb to include adverbs and prepositions, to be negated, and to come in any of four tenses, so the following are all valid examples of Verb in our grammar:

wore
carries
is carried by
had not been inside

Although we are not going through the definition of Description Phrases in detail, it is worth noticing how "which" and "who" behave:

3a. DP = DP + which + VP
3b. DP = DP + who + VP

Thus "an open container which is in the Ballroom" can be broken down as:

DP (an open container) + which + VP (is in the Ballroom)

To understand compounds like "something in a container", we have to invent a new grammatical structure for "in a container" and similar: let's call this a Relative Phrase (RP).

4. DP = DP + RP

Thus "an open container in the Ballroom" is DP (an open container) + RP (in the Ballroom). Relative Phrases have two different forms:

5a. RP = Preposition + DP
5b. RP = Participle + DP

so that "in a container" is an example of 5a. An example of 5b would be

RP (worn by Mr Darcy) = Participle (worn by) + DP (Mr Darcy)

That is nearly it, but not quite: we must go back to the "almost" in the statement above that assertions and conditions "almost" have the same grammar S. The difference arises from a curious irregularity in English called subject-verb inversion (see the Oxford English Grammar at 3.22F), whereby assertions can be reversed but not conditions. For instance,

In the Garden is a sunflower.

This does not follow the pattern S = DP + VP, because "in the garden" is not a DP: indeed, it is not a noun at all. To make sense of this sentence, Inform reverses it to "A sunflower is in the Garden", which does indeed follow DP + VP. Hence the final rule:

6 (assertions only). S = RP + Verb + DP

So the condition "if in the garden is a sunflower..." fails because rule 6 does not apply to the grammar for conditions: while occasional poetic uses of subject-verb inversion do turn up in conditions ("If On A Winter's Night A Traveller", say), they are rare in ordinary English usage, and illegal in Inform. That completes the S grammar, so to recap:

1. S = DP + VP
2. VP = Verb + DP
3a. DP = DP + which + VP
3b. DP = DP + who + VP
4. DP = DP + RP
5a. RP = Preposition + DP
5b. RP = Participle + DP
6 (assertions only). S = RP + Verb + DP

243. Mathematical view of relations ★★★

Inform uses the term "relation" in a broader sense than mathematics. Properly speaking, the term "relation" in its mathematical sense only applies to the case where the domain for the left and right objects are the same: for simplicity's sake, let us talk only about the case where they are.

In mathematics, the properties most often looked for in a relation are that it should be:

(a) Reflexive: A <=> A for every A. This is not especially useful for Inform, and seldom appears in practical examples.

(b) Symmetric: A <=> B if and only if B <=> A. Generally, Inform relations are not symmetric, but there are two important cases which are:

Meeting relates people to each other.
Marriage relates one person to another.

These are automatically symmetric, so that to assert one way round is to assert the other as well.

(c) Transitive: A <=> B and B <=> C means that A <=> C as well. Again, Inform relations are not generally transitive. In many relations, there can be long chains of things, each perhaps related to the one in front and the one behind, so that there is some indirect sense in which the two ends of the chain are connected to each other: but they are not related as such. For instance, a journey across the map might pass through ten rooms, each adjacent to the last and next, but the two ends would not themselves be adjacent. The concept we need is the "transitive closure" of the original relation, defined as the smallest transitive relation including the original. If R is a relation between "things", then the following:

TC relates a thing (called A) to a thing (called B) when the number of steps via R from A to B is greater than 0.

is the transitive closure of R. In particular,

Accessibility relates a room (called A) to a room (called B) when the number of moves from B to A is greater than 0. The verb to be accessible from means the accessibility relation.

calculates the transitive closure of adjacency. Here, though, the way we normally understand "accessible from" suggests that it would be better to write:

Accessibility relates a room (called A) to a room (called B) when the number of moves from B to A is at least 0.

which is reflexive as well as transitive. The usefulness of Inform's "next step via R from A to B" construction, in a wide variety of settings, reflects the importance of transitivity as an idea.

A relation which has all three properties of being reflexive, symmetric and transitive is called an "equivalence relation". (If all the map connections are two-way, then the accessibility relation above is symmetric and therefore a full equivalence relation: but if not, it may not be.) Inform has a special construction for making equivalence relations:

Nationality relates people to each other in groups.

This language - "in groups" - relies on the standard theorem that every equivalence relation on a set naturally defines a partition of that set, and vice versa. The "groups" referred to are what are normally called "equivalence classes". (Inform does little with these equivalence classes: it might be interesting to do so, in effect forming quotient kinds.)

244. Graph-theory view of relations ★★★

One way to look at a relation is to regard it as a directed graph: that is, a collection of things ("vertices") with arrows drawn between them ("edges"). We write our items A, B, C, ... on a piece of paper: then, if A relates to B, we draw an arrow pointing from A to B, and so on. If we made this drawing for the adjacency relation, we would more or less have reconstructed the map (or at least a simplified one which does not care about precise directions, like the famous diagram of the London Underground). But the drawing can be made for any relation. If we define:

Suspecting relates various people to one person.

then, in the corresponding graph, each "vertex" will have at most one arrow leading away from it - though there could be many (or none) leading towards. Conversely, a one-to-various relation produces a graph where each vertex has at most one arrow coming in. A one-to-one relation means that the picture consists of some vertices on their own, with no arrows, a few perhaps with looped arrows leading from and to themselves, and then a collection of pairs joined by arrows. On the other hand, a various-to-various relation is just a free-for-all, with no restrictions on the arrows. The relations:

Meeting relates people to each other.
Marriage relates one person to another.

always have the property of working both ways round, and these are easiest to visualise by forgetting the direction of the arrows, so that they just become lines joining the vertices.

Inform uses a different algorithm for finding routes ("the next step via R from A to B") in each of these cases, and internally it stores relations in different formats in the different cases, because it makes a big difference to the efficiency of Inform to minimise the storage required for a relation and the time taken to explore it.

All the cases are benign except for "various to various" - the most useful - and for its closely related symmetrical version, "relates... to each other". Inform cannot afford to assume that the relation will be "sparse" (that is: that no vertex will have more than a certain number of arrows, or that the total number of arrows will be small), because it has no idea how the arrows will come and go during play. It therefore uses 1 bit of storage for each pair of objects. This sounds harmless, but if there are 200 rooms, there are 40,000 pairs of rooms, which means a 5000-byte allocation of storage (plus a handful of bytes as overhead). Gratuitous various-to-various relations are therefore not a good idea.

There is a standard algorithm for calculating shortest paths through a directed graph, but Inform does not always use it, because there is not always memory to store the required matrix of partial results. Inform's slow method, likely to be used on the Z-machine, requires a storage overhead which is equal to the number of vertices, not the square of that number, but the worst-case running time can be bad: if there are N vertices, and the diameter of graph (the longest distance between vertices) is D, then the running time is proportional to D times N. The worst case in finding routes from A to B is when almost every vertex can reach B, some across long trails, but A cannot. In the case of finding routes across the game's map, this must be multiplied further by the number of possible directions - usually 16.

This does not sound too awful, but if one is trying to find (say) "the most distant room from A", that means a further loop and now the running time will be D times N squared. Extension writers will need to be careful of this kind of thing: it is easy to write highly cool prototypes which work terribly slowly on larger, more realistic maps.

399. Backus-Naur form for rules ★★★

Backus-Naur form, or BNF, is a standard notation used by computer scientists to specify more or less precisely what the valid programs are for a given programming language. It tends to provide a good description for a language such as C or Pascal, where contextual rules are limited, but the authors of Inform are doubtful that it is such a good tool for a natural-language system. For those who are interested, though, the following gives a formal specification for Inform's rules.

<rule> ::=
    Definition : A/an <kind> is <new adjectival name> if/unless <definition>
    | <preamble> : <phrases>
    | <preamble> , <phrase> (* only allowed for a few cases: see below)

<definition> ::=
    <condition>
    | its/his/her/their <value property name> is/are <value> or less/more
    | : <phrases>

<preamble> ::=
    To <phrase template>
    | To decide if/whether <phrase template>
    | To decide which/what <kind of value> is <phrase template>
    | This is the <rule name>
    | [[A] Rule for] <circumstances> [(this is the <rule name>)]

<circumstances> ::=
    At <time>
    | When <event name>
    | [<placement>] <rulebook reference> [while/when <condition>] [during <scene name>]

<rulebook reference> ::=
    <rulebook name> [about/for/of/on/rule] [<action pattern>]
    | <object-based-rulebook name> [about/for/of/on/rule] [<description>]

<placement> ::=
    a/an
    | [the] first
    | [the] last

<phrases> ::=
    <phrase>
    | <phrases> ; <phrase>

The following examples show how Inform breaks down some typical rules using the system above:

<rule> = At 2:09 PM: increase the score by 2; say "Progress!"
    <preamble> = At 2:09 PM
        <circumstances> = At 2:09 PM
            At
            <time> = 2:09 PM
    :
    <phrases> = increase the score by 2; say "Progress!"
        <phrase> = increase the score by 2
        ;
        <phrase> = say "Progress"

<rule> = Instead of eating the ostrich during Formal Dinner (this is the cuisine rule), say "It's greasy!"
    <preamble> = Instead of eating the ostrich during Formal Dinner (this is the cuisine rule)
        <circumstances> = Instead of eating the ostrich during Formal Dinner
            <rulebook reference> = Instead of eating the ostrich
                <rulebook name> = Instead
                of
                <action pattern> = eating the ostrich
            during
            <scene name> = Formal Dinner
        (
        this
        is
        the
        <rule name> = cuisine rule
        )
    ,
    <phrases> = say "It's greasy!"
        <phrase> = say "It's greasy!"

<rule> = After printing the name of a container: say "!"
    <preamble> = After printing the name of a container
        <circumstances> = After printing the name of a container
            <rulebook reference> = After printing the name of a container
                <object-based-rulebook name> = After printing the name
                of
                <description> = a container
    :
    <phrases> = say "!"
        <phrase> = say "!"

(*) The colon dividing a rule preamble from its definition can be replaced by a comma only if the preamble begins with the words "Instead of", "Before", "After", "Every turn" or "When", and if the definition consists only of a single phrase.