§18   Making conversation

To listen is far harder than to speak. This section overlaps with Chapter IV, the chapter on parsing text, and the later exercises are among the hardest in the book. As the following summary table shows, the simpler ways for the player to speak to people were covered in the previous section: this section is about “orders”.

Example command Rule action noun second consult
“say troll to orc” life Answer 'troll' orc 21
“answer troll to orc” life Answer 'troll' orc 21
“orc, tell me about coins” life Ask orc 'coins' 61
“ask orc about the big troll” life Ask orc 'big' 43
“ask orc about wyvern” life Ask orc 0 41
“tell orc about lost troll” life Tell orc 'lost' 42
“orc, take axe” order Take axe 0
“orc, yes” order Yes 0 0
“ask orc for the shield” order Give shield player
“orc, troll” order NotU... 'troll' orc 31

Here we're supposing that the game's dictionary includes “troll”, “orc” and so forth, but not “wyvern”, which is why “ask orc about wyvern” results in the action Ask orc 0. The notation NotU... is an abbreviation for NotUnderstood, of which more later. The two numbers in the “consult” column are the values of consult_from and consult_words, in cases where they are set.

When the player types in something like “pilot, fly south”, addressing an object which has animate or at least talkable, the result is called an ‘order’.

The order is sent to the pilot's orders property, which may if it wishes comply or react in some other way. Otherwise, the standard game rules will simply print something like “The pilot has better things to do.” The ‘Ruins’ priest is especially unhelpful:

orders [;
    Go: "~I must not leave the Shrine.~";
    NotUnderstood: "~You speak in riddles.~";
    default: "~It is not your orders I serve.~";

The NotUnderstood clause of an orders rule is run when the parser couldn't understand what the player typed: e.g., “pilot, fly somersaults”.

The Inform library regards the words “yes” and “no” as being verbs, so it parses “delores, yes” into a Yes order. This can be a slight nuisance, as “say yes to delores” is treated differently: it gets routed through the life routine as an Answer.

When a NotUnderstood order is being passed to orders, the library sets up some variables to help you parse by hand if you need to. The actual order, say “fly somersaults”, becomes a sort of consultation topic, with consult_from and consult_words set to the first word number and the number of words. The variable etype holds the parser error that would have been printed out, had it been a command by the player himself. See §33: for instance, the value CANTSEE_PE would mean “the pilot can't see any such object”.

If the orders property returns false or if there wasn't an orders property in the first place, the order is sent on either to the Order: part of the life property, if it was understood, or to the Answer: part, if it wasn't. (This is how all orders used to be processed, and it's retained to avoid making old Inform code go wrong.) If these also return false, a message like “X has better things to do” (if understood) or “There is no reply” (if not) is finally printed.

(Cf. ‘Starcross’.) Construct a computer responding to “computer, theta is 180”.

For many designers, Answer and Tell are just too much trouble. How can you make attempts to use these produce a message saying “To talk to someone, try ‘someone, something’.”?

When the player issues a request to an animate or talkable object, they're normally parsed in the standard way. “avon, take the bracelet” results in the order Take bracelet being sent to Kerr Avon, just as typing “take the bracelet” results in the action Take bracelet passing to the player. The range of text understood is the same, whether or not the person addressed is Avon. Sometimes, though, one would rather that different people understood entirely different grammars.

For instance, consider Zen, the flight computer of an alien spacecraft. It's inappropriate to tell Zen to pick up a teleport bracelet and the crew tend to give commands more like:

“Zen, set course for Centauro”
“Zen, speed standard by six”
“Zen, scan 360 orbital”
“Zen, raise the force wall”
“Zen, clear the neutron blasters for firing”

For such commands, an animate or talkable object can if it likes provide a grammar property. This is called at a time when the parser has worked out the object being addressed and has set the variables verb_wordnum and verb_word to the word number of the ‘verb’ and its dictionary entry, respectively. For example, in “orac, operate the teleport” verb_wordnum would be 3, because the comma counts as a word on its own, and verb_word would be 'operate'.

Once called, the grammar routine can reply to the parser by returning:

Meaning “carry on as usual”.
Meaning “you can stop parsing now because I have done it all, and put the resulting order into the variables action, noun and second”.
Meaning “don't use the standard game grammar: use the grammar lines for this verb instead”.
Meaning “use the grammar lines for this verb, and if none of them match, use the standard game grammar as usual”.

In addition, the grammar routine is free to do some partial parsing of the early words provided it moves on verb_wordnum accordingly to show how much it's got through.

Implement Charlotte, a little girl who's playing Simon Says (a game in which she only follows your instructions if you remember to say “Simon says” in front of them: so she'll disobey “charlotte, wave” but obey “charlotte, simon says wave”).

Another of Charlotte's rules is that if you say a number, she has to clap that many times. Can you play?

Regrettably, Dyslexic Dan has always mixed up the words “take” and “drop”. Implement him anyway.

When devising unusual grammars, you sometimes want to define grammar lines that the player can only use when talking to other people. The vile trick to achieve this is to attach these grammar lines to an “untypeable verb”, such as 'comp,'. This can never match what the player typed because the parser automatically separates the text “comp,” into two words, “comp” and “,”, with a space between them. The same will happen with any word of up to 7 letters followed by a comma or full stop. For instance, here's one way to solve the ‘Starcross’ computer exercise, using an untypeable verb:

[ Control;
  switch (NextWord()) {
      'theta': parsed_number = 1; return GPR_NUMBER;
      'phi':   parsed_number = 2; return GPR_NUMBER;
      'range': parsed_number = 3; return GPR_NUMBER;
      default: return GPR_FAIL;
Verb 'comp,' * Control 'is' number -> SetTo;

(Here, Control is a “general parsing routine”: see §31.) The computer itself then needs these properties:

grammar [; return 'comp,'; ],
orders [;
        switch (noun) {
            1: print "~Theta"; 2: print "~Phi"; 3: print "~Range";
        " set to ", second, ".~";
    default: "~Does not compute!~";

This may not look easier, but it's much more flexible, as the exercises below may demonstrate.

How can you make a grammar extension to an ordinary verb that will apply only to Dan?

Make an alarm clock responding to “alarm, off”, “alarm, on” and “alarm, half past seven” (the latter to set its alarm time).

Implement a tricorder (from Star Trek) which analyses nearby objects on a request like “tricorder, the quartz stratum”.

And, for good measure, a replicator responding to commands like “replicator, tea earl grey” and “replicator, aldebaran brandy”.

And a communications badge in contact with the ship's computer, which answers questions like “computer, where is Admiral Blank”. (This is best done with “scope hacking”, for which see §32.)

Finally, construct the formidable flight computer Zen. (Likewise.)

▲▲ To trump one vile trick with another, untypeable verbs are also sometimes used to create what might be called ‘fake fake actions’. Recall that a fake action is one which is never generated by the parser, and has no action routine. For instance, there's no ThrownAtSub, because ThrownAt is a fake. A fake fake action is a half-measure: it's a full action in every respect, including having an action routine, except that it can never be generated by the parser. The following grammar line creates three of them, called Prepare, Simmer and Cook:

Verb 'fakes.' * -> Prepare * -> Simmer * -> Cook;

The author is indebted for this terminology to an algebraic geometry seminar by Peter Kronheimer on fake and fake fake K3 surfaces.

Difficult “someone on the other end of a phone” situations turn up quite often in one form or another (see, for instance, the opening scene of ‘Seastalker’) and often a quite simple solution is fine. If you just want to make something like “michael, tell me about the crystals” work, when Michael is at the other end of the line, give the phone the talkable attribute and make the word 'michael' one of its names. If several people are on the phone at different times, you can always give the phone a parse_name property (see §28) to respond to different names at different times.

Via the main screen of the Starship Enterprise, Captain Jean-Luc Picard wants to see and talk to Noslen Maharg, the notorious tyrant, who is down on the planet Mrofni. Make it so.

Put the player in telepathic contact with Martha, who is in a sealed room some distance away, but who has a talent for telekinesis. Martha should respond to “martha, look”, “ask martha about…”, “say yes to martha”, “martha, give me the red ball” and the like.

A much fuller example of a ‘non-player character’ is given in the example game ‘The Thief’, by Gareth Rees (though it's really an implementation of the gentleman in ‘Zork I’, himself an imitation of the pirate in ‘Advent’). The thief is capable of walking around, being followed, stealing things, picking locks, opening doors and so on.   Other good definitions of animate objects to look at are Christopher in ‘Toyshop’, who will stack up building blocks on request; the kittens in ‘Alice Through the Looking-Glass’; the barker in ‘Balances’, and the animals and dwarves of ‘Advent’.   Following people means being able to refer to them after they've left the room: see the library extension "follower.h" by Gareth Rees, Andrew Clover and Neil James Brown.   A wandering character with a destination to aim for needs to be able to navigate from room to room, and possibly through doors. Ideally, a designer should be able to make a simple instruction like “head for the West Ballroom” without specifying any route. Two independent library extensions allow this: "MoveClass.h", by Neil James Brown and Alan Trewartha, is compatible with "follower.h" and is especially strong on handling doors. Volker Lanz's "NPCEngine" is designed for what might be called detective-mystery situations, in which the people inside a country house are behaving independently in ways which must frequently be described to the player.   Irene Callaci's "AskTellOrder.h" library extension file automatically handles commands in the form “ask/tell someone to do something”.