A-code vocabulary

A-code vocabulary structure and handling have some unusual features, motivated by my desire to make IF games more player-friendly and less 'mechanical' in their responses to player commands. This document deals specifically with vocabulary handling, rather than with the more general topic of player command parsing. See a separate document for parsing details.

There are four specific areas in which A-code vocabulary handling is unusual. These are:

Automatic abbreviations

By default, all vocabulary words are automatically abbreviated to the shortest unambiguous length. For example, if the vocabulary contains KICK and no other word beginning with K, then KICK is automatically abbreviable as any of K, KI and KIC. If, however, the vocabulary also contains KILL (and no other word beginning with KI), then KICK is only abbreviable to KIC, and KILL to KIL.

There are, of course, command words which must not be abbreviated: this is particularly true for any magic words. E.g. we do not want X to mean XYZZY! This is catered for in vocabulary declarations by prefixing the non-abbreviable word with an exclamation mark:

verb !xyzzy

This does not, however, eliminate all unwanted abbreviations. For example, a player may wish to save a game under some arbitrary name, which just happens to be a legitimate abbreviation of some vocabulary word. Clearly, the intended name should not be expanded to the vocabulary word in question.

This problem is solved by permitting some vocabulary verbs to be marked as "special" in that other words in the command are taken verbatim, as entered by the player (except for the case, which is always normalised to lower case). For historical reasons, instead of such special verbs being flagged individually, at present (A-code version 12) they are grouped in one block of verb declarations:

verb -first.special
[standard declarations of any special verbs]
verb -last.special

The '-' sign preceding "first.special" and "last.special" indicate that these are pseudo-verbs, not to be added to the game's vocabulary. This is an extension of the same convention in declaring object names.

To cater for any other instances in which abbreviation expansion is not wanted, setting the mandatory STATUS variable to the built-in value of NO.MATCH suppresses expansion for the duration of one command cycle.

As a further wrinkle, for object names, abbreviation matching is performed only if the object in question is either carried by the player or is in the same location as the player. This prevents game secrets being inadvertently revealed by being too generous in interpreting player's command.

See the document on command parsing for an explanation of A-code's response to ambiguous abbreviations.

Approximate matching

My typing is terrible. From seeing many player logs I know that I am not alone in this. That's why by default A-code enables automatic approximate matching of words entered by the player against words in the game's vocabulary. This feature is activated by the game declaring a text named TYPO, the assumed purpose of which is to report typo matching. This is necessary because otherwise typo correction can look distinctly baffling to players.

If a single typo is sufficient to transform an unknown word type by the player into a unique, non-abbreviated match in the vocabulary, that match is accepted as the player's command word. Here by a typo I mean a single character dropped, a single character interpolated, a single character substituted by another character or two adjacent characters swapped around. Thus, for example GET BOTTEL will be understood as GET BOTTLE.

Note, however, that approximate matching is attempted instead of, rather than in addition to unique abbreviation matching, if no unique abbreviation is found. Thus if BOTT is a unique abbreviation of BOTTLE, then GET BOTT will be understood, but GET BORT will not. That's because BORT differs from BOTTLE by three typos rather than one: mistyped R instead of T and two missing letters L and E at the end.

Clearly enough, the same problems arise here as with abbreviation matching. These are dealt with by the same mechanisms. No approximate matching in the following circumstances:

  • word declared as non-abbreviable
  • word accompanies a verb declared as "special"
  • word refers to an object not yet seen by the player
  • the STATUS variable is set to NO.MATCH or NO.AMATCH (duration one command cycle)

See the document on command parsing for a detailed explanation of A-code's responses to approximately matched commands.

Synonyms and sub-synonyms

Traditionally, IF game vocabulary is a 2D structure, consisting of list of lists of synonyms. Thus, for example, using A-code notation

verb get, take
verb drop, release

declares two vocabulary terms, both of which are denoted by two synonymous words. From version 10, A-code adds a third dimension: any individual word in the traditional structure may be associated with a list of sub-synonyms. For example, in Adv770 the full definitions of get and drop are as follows:

verb get, =g, =reach, carry, take, =t, pickup, keep, hold, catch, grab, =grip, clutch, steal, capture, tote, scoop
verb drop, =dr, =discard, =fall, =abandon, free, =release, =let

The '=' sign preceding a word indicates that word to be a sub-synonym of the last preceding word not prefixed with '='. So G and REACH are sub-synonyms of GET, but CARRY is not.

This additional vocabulary structure is motivated by my preference for responding to player commands rather more explicitly than is traditionally the case. Thus instead of the standard and rather mechanical "Taken." in response to GET CAGE, I like the game to respond with "You get the cage.". But there is a very obvious snag to this: G CAG should not result in "You g the cag."

While the expansion of "cag" to "cage" is handled by the abbreviation processing feature of the parser, "g" is declared explicitly as a vocabulary word, so does not get expanded as an abbreviation. If there were no other verbs beginning with g, it would not be necessary to include "g" as a verb synonym – the abbreviation processor would do the expanding, but that's not a realistic solution. Hence the declaration of "g" as a sub-synonym of "get", which instructs the A-code engine to echo the latter if the command verb is to be echoed.

Vocabulary listing

To my mind, one of the most irritating features of many IF games is the need to guess what words may or may not be present in the game's vocabulary. A-code offers an intelligent way of making the vocabulary listing available to players, without revealing things players should not as yet know about. This is achieved by the minor directive VOCAB, which is a kind-of fancy wrapper around the SAY directive. The full syntax of the directive is as follows:

VOCAB {<OBJECT>|<PLACE>|<WORD>} [, {<PLACE>}] [, {<FLAG>}] [, {<TEXT>}]

The first argument is the vocabulary word to be conditionally included in a vocabulary listing. The optional second and the third arguments specify conditions under which the word is to be included. The fourth argument, also optional, specifies the text to be shown instead of the word given by the 1st argument. Each vocabulary word shown to the player is prefixed with a comma followed by a space. A special form of the directive


is used to signal the start of a sequence of VOCAB directives. It can optionally display a text, but its main purpose is to suppress the comma-and-space lead of the following vocabulary list.

As an example, here are some VOCAB commands from Adv770

vocab voc.lead
A special form, signalling the beginning of a vocabulary listing in order to suppress the leading comma before the first word to be shown; in this example a text name is given as an argument, so the voc.lead message will be also displayed.

vocab axe
The word axe is shown unconditionally.

vocab alarm, seen
The word alarm is shown if the seen bit of the alarm object is set.

vocab bones, bones.room, been.here
The word bones is shown if the player has been at the bones.room location.

vocab eggs, seen, eggs.voc
The text eggs.voc (in this case "eggs (nest)") is shown if the object eggs has been seen.

Back to the documentation index
To the Mipmip home page
Feel free to leave a comment!
Mike Arnautov (27 March 2023)