Parserclass | parser.t[66], cmdhelp.t[17] |
Superclass Tree | Subclass Tree | Global Objects | Property Summary | Method Summary | Property Details | Method Details |
The conventional IF parsing loop simply consists of reading a line of text from the player, calling Parser.parse() on the string, and repeating.
In most cases you'll just need a single Parser instance. The Parser object keeps track of unfinished commands, such as when we need to ask for disambiguation help or for a missing object. If for some reason you want to keep multiple sets of this kind of state (reading input from more than one player, for example), you can create as many Parser instances as needed.
Modified in cmdhelp.t[17]:
Modifications to Parser for CMDHELP EXTENSION
class
Parser : object
autoHelp
autoLook
autoSpell
DefaultAction
defaultActions
lastTokens
question
showUnknownWords
spellTimeLimit
emptyCommand
parse
rmcType
updateVocab
autoHelp | cmdhelp.t[37] |
autoLook | parser.t[95] |
The traditional handling since the Infocom era has always been to treat an empty command line as a parsing error, and display an error message along the lines of "I beg your pardon?". Given that an empty command line has no conflicting meaning, though, we *could* assign it a meaning.
But what meaning should that be? A blank line is the simplest possible command for a player to enter, so it would make sense to define it as some very commonly used command. It's also fairly easy to enter a blank line accidentally (which is partly why the traditional reply is an error message), so the command should be benign - it shouldn't be a problem to enter it unintentionally. It can't be anything with parallel verbs, like NORTH, since then there'd be no good reason to pick NORTH instead of, say, SOUTH. Finally, it has to be intransitive, since it obviously won't involve an object name. The obvious candidates that fit all of these criteria are LOOK and INVENTORY. LOOK is probably the more useful and the more frequently used of the two, so it's the one we choose by default.
If this property is set to true, we'll perform a LOOK AROUND command when the player enters a blank command line. If nil, we'll show an error message.
autoSpell | parser.t[132] |
Our spelling correction algorithm is designed to be quite conservative. In particular, we generally limit candidates for "correct" words to the vocabulary for objects that are actually in scope, which avoids revealing the existence of objects that haven't been seen yet; and we only apply a correction when it yields a command that parses and resolves correctly. When we can't correct a command and get something resolvable, we don't even mention that we tried. This avoids the bizarre, random guesses at "corrections" that often show up in other applications, and more importantly avoids giving away information that the player shouldn't know yet.
We set this to true by default, in an attempt to reduce the player's typing workload by automatically correcting simple typos when possible. If for some reason the spelling corrector is problematic in a particular game, you can disable it by setting this property to nil.
As an experiment, change the default value to be nil when we're in a conversation and true otherwise, since over-zealous spelling corrections can be particularly troublesome in a conversational context.
DefaultAction | parser.t[780] |
defaultActions | parser.t[107] |
We make the default value nil since setting it to true can result in some rather odd parser behaviour.
lastTokens | parser.t[737] |
question | parser.t[747] |
showUnknownWords | parser.t[199] |
There are two schools of thought on this, both concerned with optimizing the user experience.
The first school holds that the parser's job is to be as helpful as possible. First and foremost, that means we should understand the user's input as often as possible. But when we can't, it means that we should be do our best to explain what we didn't understand, to help the user formulate a working command next time. In the case of a word the parser doesn't recognize, we can be pretty sure that the unknown word is the reason we can't understand the input. The best way to help the user correct the problem is to let them know exactly which word we didn't know, rather than make them guess at what we didn't understand. This is the way the classic Infocom games worked, and it's the traditional TADS default as well.
The second school holds that the user's overriding interest is maintaining suspension of disbelief, and that the parser should do its best not to interfere with that. A major aspect of this in IF the illusion that the game world is as boundless as the real world. Missing dictionary words tend to break this illusion: if the user types EXAMINE ZEBRA, and the parser replies that it doesn't know the word "zebra", we've suddenly exposed a limit of the game world. If we instead play coy and simply say that there's no zebra currently present, we allow the player to imagine that a zebra might yet turn up. This is the way Inform games typically work.
Each approach has its advantages and disadvantages, adherents and detractors, and it seems that neither one is objectively "right". It comes down to taste. But there seems to be a clear preference among the majority of players in the modern era for the second approach. The key factor is probably that typical IF commands are so short that it's easy enough to spot a typo without help from the parser, so the clarity benefits of "unknown word" messages seem considerably outweighed by the harm they do to the illusion of boundlessness. So, our default is the second option, playing coy.
spellTimeLimit | parser.t[148] |
emptyCommand ( ) | parser.t[756], cmdhelp.t[24] |
Modified in cmdhelp.t[24]:
Overridden for CMDHELP EXTENSION. If our autoHelp property is true then respond to an empty command by displaying a brief menu of command options.
parse (str) | parser.t[211] |
'str' is the text of the command line, as entered by the player.
rmcType ( ) | parser.t[783] |
updateVocab ( ) | parser.t[813] |