Above is a very simple text adventure game, in the style of the classic Adventure. It can be played directly in this page, and is written in Golem, a rule-based language designed especially for this purpose. Golem was described in part 1 of this series, and this game is a slightly improved version of the sample game from the previous article, where the dead ends have been fixed. The rules only describe the logic of the game, which can then be rendered in different ways; we previously saw a graphic interpretation, in this article, we have a look at a parser-based, text-only user interface which does not require any additional resources.
In this style of interface, the player enters commands at a text prompt, like take the stone
or examine the fountain
. Recall that our rules could describe three main actions from the player: looking at an
item, taking an item, and using an item with another:
This means that a Golem game can be played in a text interface using three verbs: look, take, and use (a few more verblike keywords are also needed, such as inventory to see what items the player currently carries, and help). A lot of modern graphical point-and-click adventure games do actually use such a small vocabulary compared to the early attempts that used a text parser (like the older Sierra games) or a grid of verbs (like the Lucasfilm classics). But these games also have graphics, animation and sound; for the purposes of a text-only game, a richer vocabulary is necessary. A simple extension to our language can require a specific verb to trigger a rule:
Rules define a subject and an object; the verb was inferred automatically. Now, it is also possible to introduce
a verb first, with its subject and object as its two arguments: Verb(Subject, Object)
. You (subject) take
(verb) the stone (object). You drink from the fountain. The stone is dropped in the hole (actually, you drop the stone
in the hole; we have to stretch the notion of subject a little bit in order to keep things simple). Another thing that
we can do to keep things simple is keep verbless rules around, which is especially useful for descriptions (rules
triggered by the verb look).
One common gripe about text adventure games was that their parser could be very picky about the words that could
be used. In our example so far, you can look at the stone
but not examine the fountain
, even though
that was an example command above. In order to alleviate this problem, we need a way to define synonyms for the verbs
that trigger rules: examine or check for look, get or pick up for take, &c.
Defining synonyms should be separated from defining game rule, since we usually want synonyms for look or take to apply to all rules triggered by that verb. Therefore, we need new syntax for synonyms. (Our user interface
also has autocompletion, which can be helpful as it hints at what verbs are pertinent to the game.)
Although we have not made much progress on that front just yet (look out for a further installment in this series
in the future), the original goal of defining an adventure game in terms of rules was to create a declarative language amenable to static analysis; where the logic is clearly defined so that an automatic process is able to find
dead ends or other issues. Synonyms are just a presentation issue and not really part of the logic of the game: whether
the player types take
or get
has exactly the same effect. Adding rules for synonyms would only add
noise that the analyser would have to filter out. However, we could look at synonyms as metadata, describing
additional properties of rules that the renderer can make use of, and that the analyser can gleefully ignore.
Metadata is useful for our system in general. It allows the description of more facts about the game that may be useful, but again do not concern the core logic itself: the game title, its author(s), publication date(s), what (natural) language is it written in (more on that topic later), and so on. We already have comments in the language, which could be considered as a kind of metadata, but these should not have any systematic meaning. It should make no difference whatsoever if they were all stripped from the source. Our metadata should on the other hand have systematic meaning, even structured meaning in some cases; therefore some kind of markup would be useful for that, hosting both rules and data about the rules. Fortunately, we happen to have such a language in our back pocket: the Dodo 🦤 markup language!
Above is the source file for the game embedded in this article (with most rules omitted; we want to focus on the
container, not the contents, at the moment). The root element is golem
and the title of the game is given
as the default attribute. Here we also have a completion date, and we declare that the language of the document, and
hence the game, is English. The rules are embedded in the rules
element. It is followed by a synonyms
element that maps the verbs used in the rules (take
, go
, put
) to their synonyms
(with a bit of funky Dodo syntax to make lists and escape whitespace); the verb look
does not appear in the
rules, but it is a default verb for descriptions, so we can define some synonyms for it as well.
A bit more about the parser and the importance of natural language. Our parser is extremely simplistic and only attempts to match verbs and nouns that are part of rules of the game; so when typing “go down the hole”, all the parser really sees is the verb go and the noun hole which match the vocabulary derived from the rules. You could also type “I wonder if it is possible to go down the hole?” or “hole go!” for the same effect. Finally, defining a language for the game would be useful if the system supported proper internationalization, so that all the user interface text (the prompt placeholder, the response to commands that cannot be parsed, the proper rendering of location description, &c.) can be localized to match games written in languages other than English. But this is future work. ⚀⚂