"Text Adventure Structures" 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: 500DATA"go",1,"get",2,"take",2,"drop",3,"inventory",4,"look",5,"examine",6 501DATA"read",7,"use",8,"climb",9,"light",10 502DATA"north",99,"south",99,"east",99,"west",99,"up",99,"down",99 503DATA"lantern",17,"oil",5,"torch",6,"book",12,"food",1,"wine",1,"water",2,"well",2,"altar",5,"bible",5 504DATA"rope",6,"barrels",6,"knapsack",6 505DATA"ogre",23,"werewolf",18,"villager",2,"clerk",3,"priest",5,"bartender",1,"paladin",17,"hobbit",24 506DATA"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 in 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 -- panks@sdf.lonestar.org SDF Public Access UNIX System - http://sdf.lonestar.org Oops, made an error. Line 103 should actually read: 103 v$=wd$(1):ne$=wd$(2):IF wd$(3)="and" OR wd$(3)="then" THEN v2$=wd$(4):n2$=wd$(5):co=1 Note the "ne$=wd$(2)" and not "n$=wd$(2)". "ne$" sets the valid noun for the parser routine. Sincerely, Paul Allen Panks dunric@yahoo.com