I wrote this article awhile back, and wanted to share it
with everyone here. This article discusses text adventure
data structures, and the article applies to all computers
with a Microsoft-compatible BASIC interpreter.
"Text Adventure Structures"
By: Paul Panks (dunric@yahoo.com)
July 11, 2004
Since the mid-1970s, attempts have been made to write
text adventures using a variety of methods. Zork (to
use an early example) was originally written at M.I.T.
on a PDP series mainframe (using an obscure
programming language known as MUDDLE). Zork was then
translated into FORTRAN IV by unknown persons, and by
1979 Infocom was formed to sell Zork to the computer
industry at large.
The fact that Zork was plainly inspired from the
original Adventure by Will Crowther and Don Woods
suggested that adventure games were appealing enough
to stick around for awhile.
By the time Zork took off, smaller memory personal
computers were becoming commonplace. And so many
people took it upon themselves to write adventure game
drivers to fit an entire adventure game into a limited
amount of RAM. People like Scott Adams and David
Malmberg developed adventure games based on the
two-word parser of the original Adventure.
The structure of a text adventure is essentially the
same today. You have several key components, including
the parser and data structures. The parser can be a
simple (or complex) routine. It is essentially
responsible for breaking down small sentences into
individual words useful to the computer. Once matched
against an array of data within the data structures
themselves, the computer then branches to specific
subroutines in order to effectively process the
inputed data.
Data structures (on the other hand) rely both on
numerical and alphanumerical data. Since data
structures are almost entirely made up of a word list,
the computer adventure can convert each word or phrase
into a number used by the parser. So one can have an
almost limitless word list consisting of verbs, nouns,
adjectives and common phrases.
Just what does a parser or data structure look like?
While a parser can vary wildly from one adventure to
the next, data structures are more or less the same
across all adventure games.
A very simple two-word parser might look like this:
100 v=0:n=0:ne$="":n$="":n2$="":v$="":v2$="":pr=0:pt=0:
nm=0:bz=0:FOR X=1 TO 10:wd$(x)="":NEXT x:INPUT A$:pt=1:
nm=0:D$=A$:FOR a=1 TO LEN(D$)
101 IF MID$(D$, a, 1)=" " THEN A$=MID$(D$,pt,a-pt):pt=a+1:
nm=nm+1:wd$(nm)=A$
102 NEXT a:nm=nm+1:a$=MID$(D$,pt,a-pt):wd$(nm)=A$
103 v$=wd$(1):n$=wd$(2):IF wd$(3)="and" OR wd$(3)="then"
THEN v2$=wd$(4):n2$=wd$(5):co=1
104 IF wd$(3)="in" OR wd$(3)="from" OR wd$(3)="to" THEN
v$=wd$(1):ne$=wd$(2):pr=1:bz=1
What lines 100 through 105 accomplish is to break the
sentence into individual words, and then assign each
of those words into a string array -- wd$(nm). "nm"
equals the number of words entered in this case. The
parser also allows from complex commands, including
PUT and GET FROM (e.g. "put medallion in bag", "get
medallion from bag", "give medallion to hobbit", etc.)
The next step is to check the entered data against a
word list. This can be accomplished as follows:
105 v=0:FOR x=1 TO 30:IF v$=vb$(x) THEN v=x
106 NEXT:IF v=0 THEN PRINT"What? Check your verb.":
GOTO 100
107 n=0:FOR x=1 TO 299:IF ne$=no$(x) THEN n=x
108 NEXT:IF n=0 THEN PRINT"Huh? Check your noun.":
GOTO 100
109 ON v GOSUB 120,130,140,150,160,170,180,190,200,210
110 IF co=1 THEN co=0:GOTO 105
111 GOTO 100
Note Lines 105 and 107. Line 105 assumes the data
table has a total of 30 verbs, and checks it against
the values stored in vb$(x) or v2$. If a match is
found, v is set to x (v=x), and the parser jumps to
Line 106. If a match is not found (v=0), then the
message "What? Check your verb" is printed out and the
parser returns to Line 100.
Line 107 checks for a valid noun, and assigns n to x
if found (n=x). If not, n=0 and the message "Huh?
Check your noun" is displayed, sending the parser back
to Line 100.
Line 109 branches off to verb subroutines based on the
value stored in v (ON v GOSUB...). In my own verb
table, I set my verbs as follows:
1 - Go
2 - Get/Take
3 - Drop
4 - Inventory
5 - look
6 - examine
7 - read
8 - use
9 - climb
10 - light
Ten verbs should be enough for most adventures,
although with a larger verb list, the adventure game
can become far more playable and interesting.
Also, note Line 110. IF co equals 1 (IF co=1), then we
set it back to 0 (THEN co=0) and hop back over to
process the input again (to Line 105). This ensures
that if a larger command has been entered -- "get
sword and then go east" -- the parser recognizes it
and works each command separately ("get sword"
followed by "go east"). The advanced Infocom parsers
used in Zork and other adventures utilized such a
parser system.
Now on to data structures. What do they look like?
Well, they can look like anything you want, so long as
they contain the basis of the adventure game. For the
purposes of this article, I will list a short data
table and explain what each DATA statement means.
A simple data table might look like this:
500 DATA"go",1,"get",2,"take",2,"drop",3,"inventory",4,"look"
,5,"examine",6
501 DATA"read",7,"use",8,"climb",9,"light",10
502 DATA"north",99,"south",99,"east",99,"west",99,"up",99,"down",99
503 DATA"lantern",17,"oil",5,"torch",6,"book",12,"food",1,"wine"
,1,"water",2,"well",2,"altar",5,"bible",5
504 DATA"rope",6,"barrels",6,"knapsack",6
505 DATA"ogre",23,"werewolf",18,"villager",2,"clerk",3,"priest"
,5,"bartender",1,"paladin",17,"hobbit",24
506 DATA"goblin",28,"knight",31,"barbarian",29,"dragon",20,"vampire"
,33,"ghost",38,"spider",40
Lines 500 through 501 list the appropriate verbs
understood by the adventure game. In this instance,
the verbs are followed by the appropriate verb number.
The verb number is important because you can assign
multiple verb names to the same verb number. In the
case of "get" and "take" verbs, this branches to the
same routine simply because both verbs do essentially
the same thing. Such a verb list would allow you to
create an entire dictionary of verbs that are
different words but do much the same action or
actions.
Lines 502 through 506 contain the noun list used by
the adventure. Each name is again followed by a
number. But this time each number isn't a noun number,
as it was in the above verb list. No, this time we are
actually listing the noun locations for each object.
For example, the lantern is located in room number 17,
the oil in room 5, and the torch in room 6. This may
also relate to monsters throughout the adventure, as
the "ogre" lives in room 23, and the "werewolf" in
room 18.
This simple data table is very limited, but it can be
used as the starting basis for a more complex
adventure. Also, remember that the player needs to be
able to move about the adventure game. A data table
for moving about the adventure would suffice as well.
Such a data table might resemble the following:
507 REM N, S, E, W, U, D
508 DATA0, 2, 0, 0, 4, 0: REM Room 1 (Tavern)
509 DATA1, 7, 3, 5, 0, 0: REM Room 2 (Village Well)
510 DATA0, 0, 0, 2, 0, 0: REM Room 3 (Town Shop)
511 DATA0, 1,10, 0, 0, 1: REM Room 4 (Upstairs Hall)
512 DATA0, 0, 2, 6, 0, 0: REM Room 5 (Village Church)
513 DATA0, 0, 5, 0, 0, 0: REM Room 6 (Storage Room)
514 DATA2, 8, 0, 0, 0, 0: REM Room 7 (In the Forest)
515 DATA7, 9,11,12, 0, 0: REM Room 8 (By a Clearing)
516 DATA8,13, 0, 0, 0, 0: REM Room 9 (On a Bridge)
517 DATA0, 0, 0, 4, 0, 0: REM Room 10(Small Room)
518 DATA0, 0, 0, 8, 0, 0: REM Room 11(By the Lake)
519 DATA0, 0, 8, 0, 0, 0: REM Room 12(By a Boulder)
520 DATA9, 0, 0,14, 0, 0: REM Room 13(By the Castle)
521 DATA0, 0,13,15, 0, 0: REM Room 14(In the Hall)
522 DATA16,0,14, 0, 0, 0: REM Room 15(In the Parlor)
523 DATA0,15, 0, 0, 0, 0: REM Room 16(By the Throne)
Line 507 is a REM statement that doesn't do anything
remarkable. But what it does list is each cardinal
direction the next DATA statements correspond with. So
the first column of each DATA statement which follows
represents the movement direction of NORTH, while the
second is SOUTH, the third EAST, the fourth WEST, the
fifth UP and the sixth DOWN. Notice that each of these
DATA columns corresponds to a room location number.
Lines 507 through 523 are thus the basis for a
6-directional map for a 16 room adventure game. It can
obviously be expanded to include many more rooms, but
this will suffice for now.
There is much more to the structure of an adventure
game than either the parser or data tables themselves.
The length of such an explanation is beyond the scope
of this article. However, a storyline and introduction
would help the casual game player to understand what
your adventure game is all about. You might also add
in the ability to talk to game objects (such as the
villager or clerk), face combat with various monsters
(such as the werewolf or barbarian) and handle random
gaming events (such as time, weather, magical rooms,
etc).
As you can see, the structure of an adventure game
(even the parser and data structures) is fairly
straightforward. Even a novice with little coding
experience can sit down and write a simple text
adventure in as few as three weeks. All it takes is
imagination, a willingness to learn and the ability to
develop a storyline.
The limits of the imagination (and available RAM) are
the only limitations to what you can accomplish while
writing a text adventure.
Sincerely,
Paul Allen Panks
dunric@yahoo.com