Inform 7: In a Nutshell

Identifiers may have spaces. When objects, variables, functions, and actions are named appropriately, the result is extraordinarily readable code. Knuth would approve.



The language is rulebook-based. Rulebooks are containers for rules. Rules give it a declarative flavor at the high level while remaining plainly imperative at the low level.



The language is currently the most natural language-like programming language in the world.



domain-specific: it compiles to a virtual machine not used outside of the I-F community, and rules are restricted to three parameters -- the highest arity an English verb may have



event-based: events are called "actions" because the command line controls the protagonist's actions in the simulated gameworld



object-based: single-inheritance and polymorphism are supported, but abstraction, modularity, and namespaces are poor to absent. I7 is a "white-box" development language by design



cross-compiler: technically, Inform 7 source compiles to Inform 6 source, a weakly-typed multiple-inheritance traditional programming language, before compiling for the virtual machine. The dev team takes care to hide this complication from novice users.



strongly typed: you'll swear you're in Pascal again, but inline Inform 6 code will circumvent



statically allocated: extensions can be downloaded to circumvent this. The language is intended for non-experts.



verbose: the true verbosity stems from circumventing strong-typing, and the lack of deeply nested mathematical-esque computations. But is insanely quick to type on a Dvorak layout. May also be pronounceable for voice-recognition input methods.



has no unifying theory: some languages can say "everything is an object" or "everything is a list"; Inform doesn't have One True Construct. This makes it easier to learn at first because we can use and learn any feature while remaining ignorant of others. This organically-grown pattern satisfies Inform's target demographic of non-programmers. But at higher levels of programming, the language has a very ad-hoc feel to it.



unique: Inform does boast some semantic conciseness unique to itself, which will hopefully be emulated in programming languages to come. We will mention these below as they occur.



In this article as well as in Inform's official documentation, "the parser" always refers to the runtime parser, our player's simplistic VERB NOUN PREPOSITION NOUN parser. It does not mean that part of the Inform 7 compiler.



"X is room." is the smallest program that will compile, not counting the automatically-added title and author listed on the first line. Every program must have at least one room.



Hello world is: My apartment is a room. When play begins: say "Hello world."







With three exceptions, the articles "a", "an", and "the" are treated as whitespace.



Types, Variables, and Objects

X is a number that varies. Y is a number variable.

Deadline is a time that varies.

An excuse is some text that varies.

My favorite toy is a thing that varies.

The current manager is a person that varies.

The ocean currents are a direction that varies.

The best spot is a room that varies.

The light switch's boolean is a truth state that varies.

The guru's answers are a table-name that varies.

My secret plans are a rulebook that varies.

What worked last time is a rule that varies.

My regex target is some indexed text that varies.

An abeyance is a stored action that varies.



The apartment is a room. "Behold Bob's apartment. That smell is coming from the pile of dishes in the sink."



The apartment complex's lobby is south of the apartment. "Rows of mailboxes are set into the wall. Box 114 is Bob's."



Mr Bob Dobalena is a man in the apartment. "Bob is wearing an old Transformers t-shirt with some well-loved jeans."



T-shirt, jeans, and a pair of shoes are wearable things. Bob is wearing the shoes, the T-shirt, and the jeans.



X is usually 2. Y is 5.

Deadline is usually 4:30 pm.

The excuse is usually "I didn't know."

My favorite toy is usually the red Porsche.

The light switch's boolean is usually true.

The guru's answers are usually the Table Of Deep Answers.



Class And Prejudice

object

direction

room

region

thing

door

container

vehicle

player's holdall

supporter

backdrop

device

person

man

woman

animal



An archway is a kind of door.

An archway has a number called the horizontal clearance. It is usually 6.

An archway is always open.

An archway can be magic or mundane. An archway is usually not magic.



The player is Bob.

[...]; change the player to Bob;



The Coding Imperative

let Z be 5;

now X is 5;

change Y to 4;



if X > Y then say "The word 'then' flags a one-liner.";



if X > Y, say "A comma is synonymous for 'then'.";

otherwise say "'Otherwise' (or 'else') must be a one-liner if the 'if' was a one-liner. No punctuation follows it in this case.";



if X > Y begin;

say "'Begin' requires a semicolon of its own.";

otherwise;

say "As does the matching 'otherwise' and 'end'.";

end if;



if X > Y:

say "Python-esque style is OK as long as we don't mix the two styles in the same function.";

otherwise:

say "Posting code to internet forums usually corrupts the tabs. But tabs are required elsewhere in the language, so, meh.";



if X is greater than Y begin;

say "This is a else-if chain. Also, notice that relational operators can be spelled out.";

otherwise if X is Y;

say "Only a semicolon is found for the trailing conditionals.";

otherwise;

say "The final otherwise is the same as usual.";

end if;



if X is greater than Y:

say "This is a else-if chain in Python style.";

otherwise if X = Y:

say "The punctuation here is more regular: always a colon, no matter what.";

otherwise:

say "The = is rarely seen by itself, in practice; 'is' is easier to type.";



unless X <= Y, say "'Unless' means 'if not'. Also, inequalities are written >= or <=, never => or =

while X > Y begin;

say "While loops are almost never seen in practice. Infinite loops are too easy with them.";

end while;



while X > Y repeatedly say "Especially the one-liner version.";



if X is:

-- 1: say "A switch statement masquerades as an if statement. 'Unless' cannot be used.";

-- 2: say "Python style only.";

-- otherwise: say "There is no fall-through between cases, and no goto to restore it.";



if my favorite toy is:

-- the red Porsche:

say "Numbers and objects both can be used in switches.";

-- the jeans:

say "Also note the further indentation of the cases, and their subsequent lines.";



repeat with X running from 1 to 10 begin;

say "'Repeat' is the usual loop construct. It has [X] forms. This enumerated one isn't used much.";

end repeat;



repeat with clothing running through every wearable thing begin;

say "The 'description' type describes a set of objects.";

if the clothing is the pair of shoes, say "Also, 'every', 'each', or 'all' aren't required here but may read better.";

end repeat;



repeat with target running through all limbs:

if the target is the head, say "We can repeat through Named Values just as easily.";



repeat with programmer running through the men who are in a lighted room (called the mainframe's area):

say "[The programmer] in [the mainframe's area] says we can do some pretty complex stuff with 'descriptions'.";

next;

break;



repeat through the table of designs:

say "Tables are 2D arrays, We'll look at them in detail in their own section.";



When play begins: say "Hello world!".

Every turn: say "La-dee-da."

Instead of taking yourself, say "You pull yourself up by your bootstraps and read on."



Boolean Adjectives

A thing can be spiffy.

A person can be grumpy or happy.



now the iPod is not spiffy;

if Mary is happy, change Bob to grumpy;



Definition: a person is boring: [...]; [...]; decide no.

Definition: a person is unlikable if it is boring or it is grumpy.

Definition: a person (called the academic) is laconic rather than chatty if the academic is [...].



repeat with associate running through every chatty not grumpy spiffy person begin;

say "Hi [associate].";

end repeat;



Patterned Procedures

To plainly greet (friend - a person):

say "Hi [friend]."



To ponder/mull over/-- (good point - a thing) for (awhile - a time) as (ponderer - a person):

say "[Ponderer] sits back in [his-her] chair for about [awhile]. 'Hm, [good point] is a very good point, sir.'"



plainly greet Dr. Muller;





ponder the best idea yet for 7 minutes as Dr. Muller;

ponder over the best idea yet for 7 minutes as Dr. Muller;

mull best idea yet for 7 minutes as Muller;

mull over the best idea yet for 7 minutes as Dr. Muller;



To (ponderer - a person) ponders/ponder/mulls/mull (good point - a thing): .

To ponder for (awhile - a time) (good point - a thing): .



let X be 5;

let the typical exclamation be "That's cool!";

let the articles of clothing be the list of things worn by Bob;

let M be { the red Porsche, the pair of shoes };

let the modifiable exclamation be indexed text;

let the modifiable exclamation be "That's cool!";





To go hiking, into the woods or up the mountain:

if into the woods then say "Watch out for badgers.";

if up the mountain then say "Better take your compass.";

say "You go hiking."



To ponder the/an/a/-- (nefarious plans - a rulebook): .

To ponder (nefarious plans - a rulebook): .



To ponder the/an/a/-- foiled/new/-- (nefarious plans - a rulebook): [...].



Functions Decide on a Value

To decide which room is my favorite place: [...]; decide on My Bedroom.

To decide what person is brother to/of (sibling - a person): [...]; decide sibling.

To decide which object is my fabulous doodad: decide on a random thing.



ponder the best idea in my favorite place;

if the brother of the noun is not the noun, say "[Noun] has a brother, [Brother of the noun].";

if my fabulous doodad is nothing, say "I'm fresh out of fabulous.";



To decide whether (pants - a thing) is/are on fire:

decide on whether or not a random chance of 1 in 2 succeeds.



if the brother of the noun is on fire, say "That's gonna leave a mark.";



Say Phrases

To say He-She for (P - a person):

if P is plural begin;

say "They";

otherwise;

if P is female, say "She";

otherwise say "He";

end if.



To say (P - a person) mulls/ponders --/over (idea - a thing): [...].



[...]; say "[He-She for Chris] glances at you[Chris ponders tar-and-feathering].";



To say (code - a rule): abide by the code.





say "Chris seems to make a decision.[the formulate plans rules] But you don't know what.";



say "He put on [if the jeans are stained]yesterday's[otherwise]his[end if] jeans.";

say "The weather was [one of]rainy[or]sunny[or]windy[at random].";



Sweet Relations

Marriage relates one person to another (called the spouse).

The verb to be married to implies the marriage relation.



Bob is married to Jane.

[...]; if Jane is married to Bob, [...]



Friendship relates various people to various people.

The verb to be friends with implies the friendship relation.

The verb to be befriended by implies the reversed friendship relation.



if the brother of the noun is married to the second noun, now the noun befriends the second noun;

repeat with associate running through every person who is friends with the brother of the noun begin;

[...];

end repeat;



Trust relates people to each other in groups.

The verb to trust (he trusts, they trust, he trusted, it is trusted, he is trusting) implies the Trust relation.



Memorability relates various people to various things.

The verb to be able to remember (he is remembered) implies the memorability relation.



Bob is a man. The time he spent in jail is a thing.

Bob can remember the time he spent in jail.



...one person to one person...

...various people to one person...

...one person to various people...

...various people to various people...

...one person to another...

...people to each other...

...people to each other in groups...



Siblinghood relates a person (called X) to a person (called Y) when X is the brother of Y or X is the sister of Y.

The verb to be a sibling of implies the siblinghood relation.



let X be the number of steps via the acts-with relation from Kevin Bacon to Jodie Foster;

let S be the next step via the acts-with relation from Christopher Walken to Kevin Bacon;



let L be the list of spiffy people who are friends with Bob;

repeat with countrymen running through every chatty not boring person who trusts the player begin;

repeat with countrymen running through every chatty not boring person who trusts the player who is friends with a person (called the shill) who owns a thing (called riches) begin;

say "Hi [countrymen]; [shill] said you'd lend me your [riches].";

end repeat;



Rules of Thumb

A persuasion rule: [...]; [...]; [...].

Persuasion: [...].

Every turn: [...].

Every turn during the collapsing bridge scene: [...].

Report someone burning something: [...].

Instead of burning something held: say "No, you might burn yourself!".

Carry out an actor helping someone: now the noun is friends with the actor.

Report tattooing: say "You go to work on [the second noun]'s [the limb understood]."



My magic hand rule is listed instead of the can't take distant objects rule in the check taking rulebook.

The landlubbers can't walk right rule is listed first in the check going rules.

The block sleeping rule is not listed in any rulebook.

A procedural rule when the player is a ghost: ignore the can't walk through closed doors rule.



Rulebooks: White-box Paradigm

The pick a plan rules are a rulebook.

The pick a plan rules have default outcome success.

A pick a plan rule: say "I always fail, regardless the rulebook's default."; rule fails.

A pick a plan rule: say "I can never make up my mind so one of my peers will now execute."; make no decision.

A pick a plan rule: say "I exhibit the default behaviour for the rulebook."



The audible rules have outcomes silent (failure), whisper (success), voiced (success - the default), shout, and deafening.



[...]; rule succeeds with result the whisper outcome.

[...]; whisper.

[...]; rule succeeds with result my fabulous doodad.

[...]; rule fails with result "In your dreams."



consider the pick a plan rules;

if the rule succeeded, say "How about [the result of the rule]?";

if the rule failed, say "I've no plans because of [the reason the action failed].";



follow the pick a plan rules;

if the rule succeeded, [...]



abide by the pick a plan rules;

say "This never prints because Abide By also returns.";



anonymously abide by the pick a plan rules;

say "As above, but doesn't clobber the global return variables. Useful for middleman rulebooks."



The pick a plan rulebook has an object called the best plan so far.

The first pick a plan rule (this is the initialize plan rule): change the best plan so far to the little-used do nothing rule.

The last pick a plan rule (this is the default fallback answer rule): rule fails.



Events are Actions

Check taking something held: say "You already have that!" instead.

Carry out an actor taking something: now the actor carries the noun.

Report taking: say "Taken."



Donating is an action applying to one thing.

Discussing is an action applying to one topic.

Accusing it of is an action applying to one object and one visible object.

Tabulating is an action applying to one number and requiring light.

Scheduling is an action applying to one time.

Temporarily waiting is an action applying to one time.

Whining is an action applying to nothing.

Teleporting to is an action applying to one room.

Saving the game is an action out of world applying to nothing.

Tattooing it of is an action applying to one limb and one thing, requiring light.

Weaving is an action with past participle woven, applying to one thing.



try Bob donating the jeans;

silently try donating the red Porsche;

try Bob accusing the player of theft;

try teleporting to the tattoo parlor;

try silently the current manager tattooing the back of the player;



An abeyance is a stored action that varies.



[...]; now the abeyance is the action of Bob examining the player;

[...]; try the abeyance;

[...]; now abeyance is the action of the current manager firing the noun;



No Lights, No Camera, Just Action

Setting Action Variables For <action>

Before Persuasion (NPCs only)

Instead (default outcome is failure, so only one rule will typically execute)

(default outcome is failure, so only one rule will typically execute) Check <action> Unsuccessful Attempt By (only when Instead or Check fails) (NPCs only)

Carry out <action>

After (default outcome is success, so only one rule will typically execute, and, will also skip the Report rules in that case)

(default outcome is success, so only one rule will typically execute, and, will also skip the Report rules in that case) Report <action> (skipped if the action was invoked with " try silently ")

Check rulebooks catch situations which should prevent an action from occurring; it enforces preconditions, essentially. If the Check rules prevent the player from doing something, it is responsible for narrating that result.

Carry Out rulebooks simulate the action, updating any data and running any code necessary; it should not print anything lest "try silently" won't live up to its name.

Report rulebooks then narrate the result.

The sole Persuasion rulebook catches player commands of the form BOB, TAKE ROCK. It decides whether Bob will do as you ask him to. If a Persuasion rule succeeds, the NPC attempts the action. If it fails, it should narrate the NPC's negative response. A default Persuasion rule, last in the rulebook, will return failure.

Unsuccessful Attempt By will run if the NPC obeyed but a Check or Instead rule (i.e., the physical world) stopped him. It too should narrate the failure. (The standard library Check rulebooks will check all characters, but only print a particular failure message for the player; the NPCs are sent here for a single, generic "is unable to do that" response from the last, default rule in the book.)

Before happens between parsing and game reaction. It can also trigger on groups of actions.

Instead is useful for blocking groups of actions.

After, when adorned with a condition or three, is useful for triggering cutscenes.

Setting Action Variables For is responsible for initializing variables that are local to the action, as opposed to variables local to an individual function, rule, or rulebook. This rulebook should do as little as possible. It should not print anything. It is rarely needed.

Instead of Tiny jumping: say "Tiny is too overweight to jump. You all must find another way to help him across."

Carry out an actor jumping: now the actor is on the nearby platform.

Report someone jumping: say "You see [the actor] jump over."

Report jumping: say "You jump over."



Report going from the monkey village to the lost city's entrance by the hoverboard: say "You sail into the clearing easily this time, bypassing all those nasty monkeys that like to drop on top of you."

The jumping action has an object called the obstacle (matched as "over").

Setting action variables for jumping:

now the obstacle is the current blockage of the location.

Instead of Stevie Burns jumping: say "Even little Stevie hops over [the obstacle]."

Instead of Stevie Burns jumping over a fiery fallen beam: say "'Help!' says Stevie. You suddenly recall him telling you about the time his house burned down."



Whining is pointless behavior.

Temporarily waiting is pointless behavior.

Discussing is conversation.

Accusing it of is conversation.

Accusing it of is drama.

Teleporting to is drama.

Tabulating is acting like a frickin' accountant.

Scheduling is acting like a frickin' accountant.



After pointless behavior: say "But you still feel unfulfilled."

Before conversation when the current interlocutor is not in the location: now the current interlocutor is a random person in the location.

Instead of drama, say "(Now is the time to lay low!)"

Instead of acting like a frickin' accountant during the collapsing bridge scene, say "You calculate (correctly) that you're about to become a victim of natural selection."



Before an actor discussing a spiffy thing when in the presence of Mr Blackheart: [...].

Instead of doing anything except waiting when the player is paralyzed, say "(Uhh... can't... move...)"

Instead of someone doing anything except taking, dropping, or burning with something incriminating, say "[The actor] says, 'No, I must get rid of [the noun]!'"

After examining, looking under, or searching anything owned by Mr Blackheart during a scene needing tension: say "Suddenly, Blackheart re-enters the room. 'What are you doing.' It wasn't a question."



Examining something is acting like a klutz.

Dropping someone is acting like a klutz.

Looking is acting like a klutz.



Before someone acting like a klutz: [...].



Understanding Our Player, Our Parser

Understand "whine" as whining.

Understand "donate [something]" as donating.

Understand "give away [something]" as donating.

Understand "discuss [text]" or "talk about [text]" as discussing.

Understand "tabulate [a number]" as tabulating.

Understand "answer [truth state]" as answering.

Understand "schedule [a time]" as scheduling.

Understand "wait for [a time period]" as temporarily waiting.

Understand "teleport to/-- [any room]" as teleporting to.

Understand "accuse [someone] of committing/-- [any thing]" as accusing it of.

Understand "[any thing] committed by/via [someone]" as accusing it of (with nouns reversed).

Understand "wear [something preferably held]" as wearing.

Understand "put [other things] in/inside/into [something]" as inserting it into.

Understand "deposit [something] in/into [an open container]" as inserting it into.

Understand "go to [any adjacent visited room]" as going by name.

Understand "tattoo [limb] of [someone]" or "tattoo [specific limb] of [someone]" as tattooing it of.



Understand "dog" as Rover.

Understand "birds" and "ruddy ducks" as the plural of duck.

Understand "upper [limb]" or "lower [limb]" as "[specific limb]".

Understand "beneath/under/by/near/beside/alongside/against" or "next to" or "in front of" as "[nearby]".





Understand "colour [a colour]" or "[something]" as "[tint]".



A pot is a kind of thing. A pot can be broken or unbroken.

Understand the unbroken property as referring to the pot.

Understand "shattered" or "cracked" or "smashed" as broken.

Understand "pristine" as unbroken.



Understand the broken property as describing a flowerpot.



Understand "bottle of [something related by containment]" as a bottle.

Understand "machine" as a device.



Understand "rouge" as red when the make-up set is visible.

Understand "Rover" as Rover The Dog when the player knows-about Rover.

Understand "your" as a thing when the item described is held by the person asked.



Understand "xyzzy" as a mistake ("The machine doesn't seem to have a button with that label on it.") when in the teleportation chamber.

Understand "xyzzy" as a mistake ("Ah, I see you're an old hand at this.").



Time for a Scene

A lightsaber duel is a [non-recurring?] scene.

A lightsaber duel begins when the location of Luke is the location of Darth.

A lightsaber duel ends when Luke is too injured to continue or Darth is too injured to continue.



A person can be too injured to continue. A person is rarely too injured to continue.



Every turn during a lightsaber duel: say "BWWAAUUAAAHH".



[...]; if a lightsaber duel is happening, [...]





When a lightsaber duel begins: change the command prompt to the battle command prompt.

When a lightsaber duel ends: change the command prompt to the normal command prompt.



A scene can be thrilling or dull. Train Stop is dull.

A scene has a text called cue speech. The cue speech of Train Stop is "All aboard!".

Every turn during a dull scene: [...].

[...]; if a thrilling scene is happening, [...]



Arrays Have Been Tabled

Table 2.1 - Selected Elements Element (some text) Symbol (some text) Atomic number (a number) Atomic weight (a number) "Hydrogen" "H" 1 1 "Iron" "Fe" 26 56 "Zinc" "Zn" 30 65 "Uranium" "U" 92 238

Table of Selected Elements Element Symbol Atomic number Atomic weight text text number number "Hydrogen" "H" 1 1 "Iron" "Fe" 26 56

Table of Energy Proponents Proponent Fuel Danger Bob Hydrogen a number Phoebe Wind -- -- Geothermal -- Jean Nuclear 10 with 4 blank rows.

Table of NPC Responses topic answer "hi/hello" "He says, 'Well hello there!'" "bye/goodbye" "'Take care,' he answers."

if Wind is a Fuel listed in The Table Of Energy Proponents ...

blank out the whole row;

choose row My Favorite Number in The Table Of Energy Proponents;

if there is no Proponent entry ...

choose row with Danger of 10 in The Table Of Energy Proponents;

if there is a Proponent corresponding to a Fuel of Geothermal in The Table Of Energy Proponents ...

choose a blank row in Table 2.1;

change Element entry to "Fluorine";

change Atomic Number entry to 9;

if there is an Atomic Number in row 2 of The Table Of Standard Elements ...

sort The Table Of Energy Proponents in reverse Danger order;

sort The Table Of Energy Proponents in random order;



... the number of blank rows in Table 2.1 ...

... the number of filled rows in Table 2.1 ...

... the Proponent corresponding to a Fuel of Hydrogen in The Table Of Energy Proponents ...

... Symbol in row 3 of The Table Of Selected Elements ..



after taking An Item listed in The Table Of Treasures: [...].

after asking The Guru about A Topic listed in The Table Of NPC Responses: [...].



Named Values Everywhere

A limb is a kind of value. The limbs are left leg, left arm, right leg, right arm, the neck, and the back.

Tattoos are a kind of value. The tattoos are mom, barbed wire, wings, a kanji, a pseudo-photograph, and some obscure symbol.



change X to the limb after the left leg;

change X to the limb before the back;

Definition: a limb is hurt if [...].

Tattooing is an action applying to one limb and one thing.

Understand "tattoo [limb] of [someone]" as tattooing.

Exposition relates various people to various tattoos. The verb to be tattooed with implies the exposition relation.

Bob is tattooed with some obscure symbol.

[...]; repeat with X running through each limb begin;







Tattoos are a kind of value. Some tattoos are defined by the Table of Designs.



Table of Designs

tattoo

barbed wire

wings



Table of Designs (continued)

tattoo

Jean-Pierre 4-ever



Causality relates an action-name (called the cause) to an action-name (called the effect) when [...].

SecondOrderRelation relates an abstract-relation (called the scaffold) to an action-name (called the side effect) when [...].



T.E.X.T.

Rene Descartes said, "I think not!" and promptly disappeared.

So don't ever say that, 'k?



say "Rene Descartes said, 'I think not!' and promptly disappeared.[line break]So don't ever say that, [']k?";



let T be indexed text;

let T be "Hello World";



if the player's command does not include "please/thanks", say "How rude!";

if the player's command includes "please/thanks", cut the matched text;

if the player's command includes "hi", replace the matched text with "hello";

if the player's command matches "hello world", say "You're a programmer, aren't you?";

if the player's command does not match "hello world", say "To code... perchance, to write?";



let N be indexed text;

let N be the player's command;

[...];

change the text of the player's command to N;



Precisely One Spoon-unit Of Sugar

Money is a kind of value. $19.99 specifies some money with parts dollars (without leading zeros) and cents (optional, preamble optional).

My wallet is some money that varies. My wallet is usually $20.75.

A thing has some money called the price. The price of a thing is usually $5.

The price of Bob is $2.05.



say "[the dollars part of the price of Bob]";



A length is a kind of value. 10 m specifies a length.

An area is a kind of value. 10 sq m specifies an area.

A length times a length specifies an area.



Understand "donate [money]" as donating. Donating is an action applying to some money.



The verb to cost (it costs, they cost, it is costing) implies the price property.

The jeans cost $19.95.





Fanciness relates a thing (called X) to some money (called Y) when the price of X > Y. The verb to be fancier than implies the fanciness relation.



let L be the list of things fancier than $2.50;

let B be the list of things fancier than the price of jeans;



Backstage Activities

Rule for printing the name of the sack while the sack is not carried: say "your abandoned sack".



[...]; if the printing the name activity is going on, [...]



Starting the virtual machine

Constructing the status line

Printing the banner text



Printing the player's obituary

Amusing a victorious player



Reading a command



Deciding whether all includes



Deciding the scope of something



Deciding the concealed possessions of something



Clarifying the parser's choice of something



Asking which do you mean



Supplying a missing noun



Supplying a missing second noun



Printing a parser error





Printing room description details of something



Printing the locale description of something



Choosing notable locale objects for something



Printing a locale paragraph about



Writing a paragraph about



Listing nondescript items of something





Printing the announcement of darkness



Printing the name of a dark room



Printing the description of a dark room

Printing a refusal to act in the dark



Printing the announcement of light



Implicitly taking something





Printing the name of something

Printing the plural name of something

Printing a number of something



Listing contents of something



Grouping together something





Testing Commands

Test me with " look / test foobar / wave ".

Test foobar with " look / take me / jump ".



SHOWME an object : will list the current values of all the properties of that object, including any relations it's involved in



RULES : will list the name of a rule before it executes



RULES ALL : will list the name of a rule before it considers execution



RULES OFF : turns off the mode



ACTIONS / ACTIONS OFF : will list when actions begin and end



RELATIONS : lists the relations



SCENES / SCENES OFF : lists the scenes currently happening, and will update us when one begins or end



TREE : shows all instantiations, indented according to the containment relation



TEST a test-script : runs the list of commands



PURLOIN an object : immediately places the object in the player's inventory, no questions asked



ABSTRACT object TO object: similar to purloin, but gives the first object to the second object, which is likely to be a container or some such

GONEAR an object : moves the player to the room which has the object

RANDOM: random number generator now predictable

SHOWVERB: shows I6-level information about a verb: synonyms, arguments, whether the arguments are reversed for a particular line

SCOPE: show all objects currently in scope

SCOPE object: show the scope from the particular object

TRACE a number: shows very low-level parsing information. The number ranges from 1 (the default) to 6 (the most detailed)

Indistinguishable Memory

A coin is a kind of thing.

55 coins are in the couch. 3 coins are carried by the player. There are 7 coins.



try taking a random tarnished coin which is carried by the player;



Understand the tarnished property as describing a coin.

Understand the metal property as referring to a coin.



Time, Turns, and Tenses

time

time period

The turn count

the time of day

Every turn while [we are] taking something fragile,

if [we are] taking something fragile,



if Grognar has carried the Sword of Villain-Smiting...

if we have taken the lantern...

if Sam has carried the One Ring...

if the One Ring has been carried by Sam...

if the One Ring has been carried...



if the candle was lit, now the candle is unlit;

if the candle was unlit, now the candle is lit;



if X had been Y

a time

turns

Every turn when the player does not carry the bottled sprite for 3 turns: say "The sprite begins to sing a lonely song."

Before taking the candle for the second time: say "You guess you'll need that candle again after all."

Every turn when the player carries the slow-acting poison for at least 5 turns: say "You feel ill."



After taking the candle for the second time: say "If the Check Taking rules block the second attempt, this rule never fires."



At 12:00 PM: say "The lunch bell rings!"



Carry out setting the watch to: the watch will beep at the time understood.

At the time when the watch will beep: say "Your Casio beeps at you urgently."



Carry out pushing the watch: the watch will beep in six minutes from now.

Carry out pushing the watch: the watch will beep in six turns from now.

At the time when the watch will beep: say "Your Casio beeps at you urgently."



Grammar Gotchas

The articles "the", "an", and "a" are almost always optional. We can think of them as a peculiar kind of whitespace. But there are a few exceptions where articles are either significant or required.



First, "the" (not "a" or "an") is required when defining a rule's name:

[..] (this is the my favorite rule): [...]



Second, "a" (not "the" or "an") is required in front of the word "random":

let N be a random number from 1 to 5;



Third, "an" (not "the" or "a") is required in front of the word "actor" when in the subject of a rule header. Though the others will compile, they will compile as reading the current value of the variable "actor" and comparing it to itself, rather than skipping the condition altogether as it should. This almost works, except when the player is performing an action, the variable "actor" is set to nothing (NULL). This also means that Descriptions in the subject won't match the player.

Report an actor jumping: [...].

Report actor jumping: [...].

Report a laconic person examining: [...].



Finally, articles in an action's or activity's name are captured, so will remain required. This is because actions and activities are intended to begin with a verb or participle, such as "printing" or "asking". So as a general rule, do not begin an action's or activity's name with an article, nor name them after nouns or noun phrases:

The speech engine is an activity.

Before speech engine:

Before the speech engine:

Speech engine is an activity.



The last is a common error with activities because their invocation begs for a "the":

carry out the speaking engine activity;





First, "the" (not "a" or "an") is required when defining a rule's name: Second, "a" (not "the" or "an") is required in front of the word "random": Third, "an" (not "the" or "a") is required in front of the word "actor" when in the subject of a rule header. Though the others will compile, they will compile as reading the current value of the variable "actor" and comparing it to itself, rather than skipping the condition altogether as it should. This almost works, except when the player is performing an action, the variable "actor" is set to nothing (NULL). This also means that Descriptions in the subject won't match the player. Finally, articles in an action's or activity's name are captured, so will remain required. This is because actions and activities are intended to begin with a verb or participle, such as "printing" or "asking". So as a general rule, do not begin an action's or activity's name with an article, nor name them after nouns or noun phrases: The last is a common error with activities because their invocation begs for a "the": Object names can unfortunately occlude one another. If we have an object "car", and then an object "car key", it frequently happens that the car cannot be referred to. Inform supplies objects with a property, "privately-named", which will not automatically export an object's source code name to the player's parser; an explicit Understand As line will be required.





The words "rules" and "rulebook" are exactly synonymous in source code. Though programmers know that a list of items isn't the same as the items themselves -- an empty list is still a space-using construct, even when no items exist to use space -- non-programmers would call it a distinction without a difference. ("A grocery list without items isn't a grocery list; it's blank paper.") So "rules" is synonymous with "rulebook" in source code.





Relatedly, because rules compose rulebooks, and rulebooks compose actions, the terms are sometimes used seemingly interchangably. Know that this is an allowance to the non-programmer, who is interested in "the reason the action failed", even though "the rule that caused the action's rulebook to fail" is more correct in most instances, and "the non-anonymous rule that most recently returned failure" is completely correct. Likewise for "if the rule succeeded" and its many cousins; it may be worth noting that the middleman here, "rulebook", is almost never explicitly mentioned where either the base-level "rule" or the top-level "action" could instead be used. Hence, "stop the action" means "rule fails", and "continue the action" means "make no decision". The sole exception, "the outcome of the rulebook" (synonymous with "the result of the rule") makes sense since the outcome/result of a protagonist action would be a permanent change in worldstate.





Finally, know that a rule variable can hold either a rule or a rulebook, but a rulebook variable can only hold a rulebook -- not a rule.

My favorite rule is a rule that varies.

My favorite book is a rulebook that varies.

change my favorite rule to the can't walk through closed doors rule;

change my favorite rule to the every turn rulebook;

change my favorite book to the every turn rulebook;

change my favorite book to the can't walk through closed doors rule;



This may be counter-intuitive to those of us who love our polymorphism, which states the more general type can accept itself as well as its subclasses. One way of viewing this is that polymorphism works on the is-a relation, while rulebooks & rules associate through the has-a relation. Alternately, anything that can be done to a item can be done to a collection by doing it to every item in that collection, but doing something specific to a collection -- like ignoring its third part -- makes no sense when applied directly to a single item.





This may be counter-intuitive to those of us who love our polymorphism, which states the more general type can accept itself as well as its subclasses. One way of viewing this is that polymorphism works on the is-a relation, while rulebooks & rules associate through the has-a relation. Alternately, anything that can be done to a item can be done to a collection by doing it to every item in that collection, but doing something specific to a collection -- like ignoring its third part -- makes no sense when applied directly to a single item. And a final note about actual whitespace. First, even if we don't use the Python style of code block demarcation, tabs are required between table columns. (One tab will absorb all other whitespace touching it, however, so we can manually format tables to look well.) Secondly, a blank line is significant: it will end an imperative flow (assuming we didn't end it properly with a period), and one is required both before & after a table or a section heading.





Very occasionally, the compiler will have difficulty parsing an invocation that has a NPC as a subject. In these cases, add the word "trying" before the action: "Bob trying examining the player". It frequently happens in Tables with a Stored Action column.





A verb ending in -ed may be acting as an adjective. Observe the given example in chapter 9.13 of the manual, which gives this example for the simple past tense.

if the lantern was switched on, change the lantern to switched off;

if the lantern was switched off, change the lantern to switched on;



This example can be misleading due to the identical forms of passive voice and participial adjectives. In other words, we can parse that as either "if (the lantern) (was switched) (on)" or "if (the lantern) (was) (switched on)". After all, there is both a property called "switched on / switched off" as well as two actions that set the relation either way, "switching on" and "switching off", with the past participles "switched on" and "switched off". So are we referring to the properties or to the actions up there?



The answer is: the properties. Verbs of change -- Actions -- are never in any form of past tense. They are either present continuous tense "[we are] switching" or present-perfect tense "we have switched", never in simple past tense 'we switched' or in past-perfect tense 'we had switched'. Furthermore, actions require "we have" when using its tensed variation. Long story short: a word ending in -ed does not guarantee past tense. It could be the present-perfect.





This example can be misleading due to the identical forms of passive voice and participial adjectives. In other words, we can parse that as either "if (the lantern) (was switched) (on)" or "if (the lantern) (was) (switched on)". After all, there is both a property called "switched on / switched off" as well as two actions that set the relation either way, "switching on" and "switching off", with the past participles "switched on" and "switched off". So are we referring to the properties or to the actions up there? The answer is: the properties. Verbs of change -- Actions -- are never in any form of past tense. They are either present continuous tense "[we are] switching" or present-perfect tense "we have switched", never in simple past tense 'we switched' or in past-perfect tense 'we had switched'. Furthermore, actions require "we have" when using its tensed variation. Long story short: a word ending in -ed does not guarantee past tense. It could be the present-perfect. There is a difference between the following valid lines of Inform:

if the lantern was switched on,

if we have switched on the lantern,



Categorizing tense properly is essential, because the used tense determines the implementation and limitations. The first line is in simple past tense, which holds the previous turn's gamestate. This means that past tenses change every turn. The second line is in present-perfect tense, which holds a truth about the present: once we have done an action to a thing, it always, for the rest of the game, remains true that we have done it. Even if it was later undone, the fact that we once did it remains true. This means the two lines act quite differently, the first being an echo of the previous turn's "if the lantern is (switched on)", and the latter asking if the switching on action had ever been used on the lantern.



Paradigm Leaning

Rules aren't Functions



This is the foobar rule:

[...];

[...].



The named but non-headered rule implies we are thinking too procedurally. Whatever invokes that rule is itself invoked at a particular time under particular circumstances, so those circumstances should be put in the header. Even if the rule is invoked from multiple places, at least one place can use the header. A possible exception would be:

The foobar rule is listed instead of the X rule in the Y rulebook.



...in which case the foobar rule will steal the replaced rule's header.





The named but non-headered rule implies we are thinking too procedurally. Whatever invokes that rule is itself invoked at a particular time under particular circumstances, so those circumstances should be put in the header. Even if the rule is invoked from multiple places, at least one place can use the header. A possible exception would be: ...in which case the foobar rule will steal the replaced rule's header. Callbacks in the Rulebook Paradigm



The callback rules are a rulebook.

To foobar:

ponder foo;

consider the callback rulebook;

mull over bar.



This implies we're halfway between the procedural and rule-based paradigms. The fix here is usually to put the two pieces of imperative code into rules of their own, and the whole To phrase becomes a rulebook itself.



The foobar rules are a rulebook.

Foobar rule (this is the pre-callback work rule): ponder foo.

Foobar rule (this is the post-callback work rule): mull over bar.



Now client code may insert code in a variety of places, and even replace the imperative sections as well, if desired. (We should, of course, use descriptive names for the rules to encourage this.)





This implies we're halfway between the procedural and rule-based paradigms. The fix here is usually to put the two pieces of imperative code into rules of their own, and the whole To phrase becomes a rulebook itself. Now client code may insert code in a variety of places, and even replace the imperative sections as well, if desired. (We should, of course, use descriptive names for the rules to encourage this.) Declarative Lists... Sometimes



Building a list is one of the more onerous things to do imperatively: declare an empty list, loop through some items evaluating and possibly adding some of them to the list, pass the list to where it's needed (always elsewhere, because if it were right here we'd simply loop & use immediately), use the list via another loop, and remember to deallocate the list at the right time & place to avoid memory leaks.



If we're building a list of objects in Inform, the proper way is to use a collection of adjectives on the loop that would use the list:

repeat with associate running through every chatty not grumpy spiffy person in the location who is not the player begin;

say "Hi [associate].";

end repeat;



Or, at the very least (and probably using a global variable):

let L be a list of every chatty not grumpy spiffy person in the location who is not the player;

change my friends list to the list of every chatty not grumpy spiffy person in the location who is not the player;



To Hack... or not... to Hack?

The first is the various activities, as previously seen. Most activities are a single function dressed up with hooks and such so code can easily be inserted to preempt the default behavior.





The procedural rulebook -- a meta-rulebook -- is second. It can shuffle around named rules at runtime.

A procedural rule when the player is a ghost: ignore the can't walk through closed doors rule.



This meta-rule will "nuke from orbit" the particular Check Going rule that simulates a door's ability to stop movement. The "when" clause on a procedural rule is important. If there were no clause, the check rule would always be ignored, so we are spending runtime cycles to do what could be done at compile time:

The can't walk through closed doors rule is not listed in any rulebook.



When we look at the scaffolding of Inform 7 -- the action-processing rulebook, the specific action-processing rulebook, the visibility rulebook, the accessibility rulebook, the player's action awareness rulebook, and the turn sequence rulebook -- we discover that Procedural rules and the ability to list, de-list, swap and substitute rules allows us a great deal of flexibility in changing nearly anything.



The compile-time meta-rules, and their run-time equivalents, are:

The <rule> is not listed in any rulebook.

[...]; ignore <rule>;

[...]; reinstate <rule>;



The <rule> is listed instead of the <second rule> in the <rulebook>;

[...]; substitute <rule> for <second rule> ;

[...]; restore the original <rule>;



The <rule> is listed before/after the <second rule> in the <rulebook>;

[...]; move <rule> to before/after <second rule> ;



[no compile-time equivalent]

[...]; reject the result of <rule>;

[...]; accept the result of <rule>;



The run-time meta-rules can be used by a normal rule to nuke its peer within the same rulebook (assuming he's run before his peer), but this is a non-standard usage, and may change in later builds.





This meta-rule will "nuke from orbit" the particular Check Going rule that simulates a door's ability to stop movement. The "when" clause on a procedural rule is important. If there were no clause, the check rule would always be ignored, so we are spending runtime cycles to do what could be done at compile time: When we look at the scaffolding of Inform 7 -- the action-processing rulebook, the specific action-processing rulebook, the visibility rulebook, the accessibility rulebook, the player's action awareness rulebook, and the turn sequence rulebook -- we discover that Procedural rules and the ability to list, de-list, swap and substitute rules allows us a great deal of flexibility in changing nearly anything. The compile-time meta-rules, and their run-time equivalents, are: The run-time meta-rules can be used by a normal rule to nuke its peer within the same rulebook (assuming he's run before his peer), but this is a non-standard usage, and may change in later builds. Third is replacing named sections of preexisting extensions.



Chapter 2a (for use with Locksmith by Emily Short)



Chapter 2b (for use without Locksmith by Emily Short)



Section 6 - Hacked locking (in place of Section 1 - Regular locking in Locksmith by Emily Short)



Though we'll have to be careful of causing compiler errors and such, a good extension writer will break up the extension into names sections in order to facilitate replacability. Also, all the most basic information on the class hierarchy, the built-in actions, variables, etc., of Inform 7 is found in an automatically included extension, the Standard Rules. In there, we find definitions like:



Section SR1/3 - Things



A thing can be privately-named or publically-named. A thing is usually publically-named.

A thing can be plural-named or singular-named. A thing is usually singular-named.

A thing can be proper-named or improper-named. A thing is usually improper-named.

A thing can be described or undescribed. A thing is usually described.

A thing has a text called an indefinite article.

A thing has a text called a description.

A thing has a text called an initial appearance.

A thing has a text called printed name.

A thing has a text called a printed plural name.



That's only a small excerpt from the definition of the Thing class, but you get the idea. The standard rules can be changed just like any other extension:

Section 8 - My thing class (in place of Section SR1/3 - Things in the Standard Rules by Graham Nelson)



Avoiding compiler errors by changing so much of the most basic assumptions of the code library is difficult, but the option is open to us.





Though we'll have to be careful of causing compiler errors and such, a good extension writer will break up the extension into names sections in order to facilitate replacability. Also, all the most basic information on the class hierarchy, the built-in actions, variables, etc., of Inform 7 is found in an automatically included extension, the Standard Rules. In there, we find definitions like: That's only a small excerpt from the definition of the Thing class, but you get the idea. The standard rules can be changed just like any other extension: Avoiding compiler errors by changing so much of the most basic assumptions of the code library is difficult, but the option is open to us. Fourth is interfacing with the underlying language, Inform 6. How to program in I6 is beyond the scope of this document, but here's a taste.



To really clear the/-- screen: (- VM_ClearScreen(0); statuswin_cursize = 0; -)



To decide what number is the currently-chosen table row: (- ct_1 -).



To (w - value) is now (p - property): (- Write{p}{-delete},{w}); -).



To decide what number is the first misunderstood parser word: (- (wn - 1) -)



To say pattern: (- PrintPatternCommand(); -)

Include (-



[ PrintPatternCommand m pcount pcount2;

if (etype == UPTO_PE) {

for (m=0 : m<32 : m++) pattern-->m = pattern2-->m;

pcount = pcount2; PrintCommand(0);

}

];



-).







Fifth and finally, is using a feature like section-replacement, but on the Inform 6 template files. Every Inform 7 installation comes with many files with an I6T extension. After Inform 7 compiles to Inform 6, all of the I7-specific features must be implemented in I6. These I6T files hold that implementation.



Include (- ... -) before "Relations.i6t".

Include (- ... -) instead of "Relations.i6t".

Include (- ... -) after "Symmetric One To One Relations" in "Relations.i6t".



