§6.17. Clarification and Correction

Some commands and some objects raise special challenges when it comes to working out the player's intention.

Sometimes this can be done with good rules about the assumptions Inform should make. Alpaca Farm demonstrates a USE command, always a challenge because USE can mean very different actions with different items.

There are also times when we need to ask the player for more information. Apples demonstrates how sensibly to use properties to disambiguate between similar objects, while Walls and Noses rephrases the disambiguation question when special objects are involved: examining one of the walls of the room will make the story ask "In which direction?" and EXAMINE NOSE will lead to "Whose nose do you mean, Frederica's, Betty's, Wilma's or your own?"

At other times, the player types something that is wrong in a predictable way: for instance, we might want to remove all the "with..." phrases from commands like

HIT DOOR WITH FIST
KICK DRAGON WITH FOOT
LOOK WEST WITH EYES

and merely parse the remainder of the command. (That last command may be unlikely, but novice players do quite often type commands that refer unnecessarily to body parts.) Cave-troll demonstrates how.

WXPQ demonstrates how to modify the error message the parser gives in response to a command it doesn't understand; this particular example focuses on the "That noun doesn't make sense in this context" message that arises from using the "[any thing]" or "[any room]" tokens, but the techniques could be adapted to handling other parser errors as well.

For catching typing errors, Cedric Knight's extension Mistype may also be of use: it provides an automatic typo-correction function that the player can turn on or off.


arrow-up.pngStart of Chapter 6: Commands
arrow-left.pngBack to §6.16. Alternate Default Messages
arrow-right.pngOnward to §6.18. Alternatives To Standard Parsing

*ExampleAlpaca Farm
A generic USE action which behaves sensibly with a range of different objects.

*ExampleApples
Prompting the player on how to disambiguate otherwise similar objects.

*ExampleWXPQ
Creating a more sensible parser error than "that noun did not make sense in this context".

***ExampleWalls and Noses
Responding to "EXAMINE WALL" with "In which direction?", and to "EXAMINE NOSE" with "Whose nose do you mean, Frederica's, Betty's, Wilma's or your own?"

Novice players of interactive fiction, unfamiliar with its conventions, will often try to add extra phrases to a command that the game cannot properly parse: HIT DOOR WITH FIST, for instance, instead of HIT DOOR.

While we can deal with some of these instances by expanding our range of actions, at some point it becomes impossible to account for all the possible prepositional phrases that the player might want to tack on. So what do we do if we want to handle those appended bits of text sensibly?

We could go through and remove any piece of text containing "with ..." from the end of a player's command; the problem with that is that it overzealously lops off the ends of valid commands like UNLOCK DOOR WITH KEY, as well. So clearly we don't want to do this as part of the "After reading a command..." stage.

A better time to cut off the offending text is right before issuing a parser error. At that point, Inform has already determined that it definitely cannot parse the instruction as given, so we know that there's something wrong with it.

The next problem, though, is that after we've edited the player's text we want to feed the corrected version back to Inform and try once more to interpret it.

This is where we have a valid reason to write a new "rule for reading a command". We will tell Inform that when we have just corrected the player's input to something new, it should not ask for a new command (by printing a prompt and waiting for another line of input); it should instead paste our stored corrected command back into "the player's command" and proceed as though that new text had just been typed.

Thanks to John Clemens for the specifics of the implementation.

paste.png "Cave-troll" by JDC

Section 1 - The Mechanism

The last command is a text that varies.

The parser error flag is a truth state that varies. The parser error flag is false.

Rule for printing a parser error when the latest parser error is the only understood as far as error and the player's command matches the text "with":
    now the last command is the player's command;
    now the parser error flag is true;
    let n be "[the player's command]";
    replace the regular expression ".* with (.*)" in n with "with \1";
    say "(ignoring the unnecessary words '[n]')[line break]";
    replace the regular expression "with .*" in the last command with "".

Rule for reading a command when the parser error flag is true:
    now the parser error flag is false;
    change the text of the player's command to the last command.

Section 2 - The Scenario

The Cave is a room.

The troll is a man in the cave.

The player carries a sword.

The chest is a locked lockable container in the cave.

Test me with "attack troll with sword / unlock chest with sword / attack troll as a test".

A caveat about using this method in a larger game: "parser error flag" will not automatically control the behavior of any rules we might have written for Before reading a command... or After reading a command..., so they may now fire at inappropriate times. It is a good idea to check for parser error flag in those rules as well.

***ExampleCave-troll
Determining that the command the player typed is invalid, editing it, and re-examining it to see whether it now reads correctly.

Novice players of interactive fiction, unfamiliar with its conventions, will often try to add extra phrases to a command that the game cannot properly parse: HIT DOOR WITH FIST, for instance, instead of HIT DOOR.

While we can deal with some of these instances by expanding our range of actions, at some point it becomes impossible to account for all the possible prepositional phrases that the player might want to tack on. So what do we do if we want to handle those appended bits of text sensibly?

We could go through and remove any piece of text containing "with ..." from the end of a player's command; the problem with that is that it overzealously lops off the ends of valid commands like UNLOCK DOOR WITH KEY, as well. So clearly we don't want to do this as part of the "After reading a command..." stage.

A better time to cut off the offending text is right before issuing a parser error. At that point, Inform has already determined that it definitely cannot parse the instruction as given, so we know that there's something wrong with it.

The next problem, though, is that after we've edited the player's text we want to feed the corrected version back to Inform and try once more to interpret it.

This is where we have a valid reason to write a new "rule for reading a command". We will tell Inform that when we have just corrected the player's input to something new, it should not ask for a new command (by printing a prompt and waiting for another line of input); it should instead paste our stored corrected command back into "the player's command" and proceed as though that new text had just been typed.

Thanks to John Clemens for the specifics of the implementation.

paste.png "Cave-troll" by JDC

Section 1 - The Mechanism

The last command is a text that varies.

The parser error flag is a truth state that varies. The parser error flag is false.

Rule for printing a parser error when the latest parser error is the only understood as far as error and the player's command matches the text "with":
    now the last command is the player's command;
    now the parser error flag is true;
    let n be "[the player's command]";
    replace the regular expression ".* with (.*)" in n with "with \1";
    say "(ignoring the unnecessary words '[n]')[line break]";
    replace the regular expression "with .*" in the last command with "".

Rule for reading a command when the parser error flag is true:
    now the parser error flag is false;
    change the text of the player's command to the last command.

Section 2 - The Scenario

The Cave is a room.

The troll is a man in the cave.

The player carries a sword.

The chest is a locked lockable container in the cave.

Test me with "attack troll with sword / unlock chest with sword / attack troll as a test".

A caveat about using this method in a larger game: "parser error flag" will not automatically control the behavior of any rules we might have written for Before reading a command... or After reading a command..., so they may now fire at inappropriate times. It is a good idea to check for parser error flag in those rules as well.