Discovering a Text Adventure Game

In this session, we are going to be evaluating code extracted from a text adventure called ‘Old West’. I came across this interesting program after browsing a copy of a book called Compute!’s Commodore Collection Volume One at my local library in the early 80’s. It was bundled with other programs in Chapter 1 titled ‘Games’ on page 15. This program was more than just an average text adventure, since it utilized two dimension arrays to track room movement accessibility, strings that contained the verbs and nouns, DATA statements that created the maps and objects, one dimensional array that displayed the objects that were visible before and after a logical step was completed, and there are variables that are used as flags to show a specific task has been completed. There is much more than this, but that is the gist of the program.

Interacting with the Game

By definition, a text adventure is a role playing adventure that interacts with a user using a two word entry of verb and noun. These were first made popular by a company called Infocom, with an adventure series titled Zork. So in this type of adventure the player utilizes the commands to move around in what is known as a game map, and uses them to take action on objects in range. Many game players learned to create their own map after navigating through a text adventure to learn about all of the opportunities that existed around them. Making a log like this also helped users to uncover clues that could easily be missed if you are walking around a very large map. Simple commands consisted of the word ‘LOOK’ to examine your surroundings, ‘GET OBJECT’ (name inserted with OBJECT) to pick up items in range, ‘INV’ (for inventory) to see what you are holding, and sometimes ‘QUI’ to quit the game. The goal is to discover new commands throughout the game as you communicated with beings, picked up objects, and very often examined things around you.

Analyzing the Text Adventure

When ‘Old West’ starts up on the C64 the screen is cleared, arrays are initialized, data is read into arrays, and soon we see the words ‘I hear a horse’ on the screen. Within a few seconds more words fade into view and we see the words ‘Cloppity’ repeated in succession down the screen. This creates a vision of a horse coming into range, and since we currently live in the age of automobiles, it is no surprise that we have been planted in a western town, hence the name of the program.

Several seconds after the cloppity words are removed from view, we get our first taste of this adventure. Apparently our horse is nearby. The room locations tell us this moment that we are in a Dusty Street. Some adventures don’t explain if you are standing or sitting and leave that up to you to figure it out. However, this one allows you to instantly move around, so it is obvious you are on your feet. The game says you see a poster and your obvious exists are North, South, or East (N, S, E). So to move around you choose a location in the game advances you in that direction. Before exploring a new room you type the words READ POSTER to look at the poster in view. The words Wanted Alive-Black Bart! $1000 reward appear. So the goal of the game has been revealed already.

Warning: Many clues will be given to this game, so you can cease reading if you decide to play the game and want to figure it out for yourself.

Next you decide to walk to the North (choosing N). The previous text is erased and the new room appears. You are still in a Dusty Street. In range you see a horse trough and a bucket. The obvious exists are South, East, or West. Next you type the words GO TROUGH. The words ‘Splash I’m all wet. You found something’ appear. Then the text fades and you now see an object called shiny star in the horse trough. At this point you can pick up the object. So typing the words GET STAR causes the computer to respond with ‘Okay’.

In this adventure only one command is needed. Next you decide to check your inventory.  You type the letter ‘I’ and the system soon says ‘I’m carrying shiny star’. When playing a role playing adventure it is often important to check your inventory. Many times you will discover clues with the objects you possess.

Walking to the West seemed ideal to to learn more about your world. So the letter ‘W’ is typed and the Return is pressed (on a typical Commodore 64 or Enter when using the VICE emulator) and your new room is seen. Now you are in a Saloon. You see a room in back, and a bottle of elixir. The only direction you can move in is east. You enter ‘GET ELI’ and are quite surprised when the game responds with ‘I don’t see it here’. At this point, I noticed the game was requiring you to learn a new noun to pick up the elixir. A quick search of Google confirmed that elixir is a sweetened liquid usually containing alcohol. However, the game is actually waiting on the clue words GET WHI (for whisky). Later, I decided to change the string context to accept the letter WHI instead of ELI since it made for an easier playing game.

At this time you have arrived at a hidden location, but it is not known yet. There is a secret room in range, but the interpreter is waiting patiently for you to discover it. There is a room in back’, but you cannot proceed in that direction. The answer is to type the words GO ROOM’ (or GO ROO) to get into the hidden room. Many text adventure led game players down rabbit holes until they could learn how to get out of a dark tunnel, hole, or in this case move to a room that seemed to be mentally barred.

Soon the new room is revealed as Room in Back. Suddenly you see Black Bart standing before you. The game decided not to trap you in this room (as was common with many adventures), but instead still allows you to move East from the direction you came in. If you try to GET BART the game will end since he gets mad and finishes you off. The secret is to GIVE WHI. Then you see the words ‘Black Bart gulps elixir and immediately falls asleep’. Now it is safe to GET BLA (get Black Bart).

To keep this article from getting too long, I will now dig into the code some more so we can learn how it works. You can also watch the YouTube video at the top of this page to hear my verbal explanation. The game map consists in total of 10 rooms (several are hidden). As we delve into the code, you will get a clearer picture of how the game logic works, and hopefully be inspired to write your own text adventure soon.

Examining the C64 Game Map

To make the logic easier to follow I have broken down the context of the program into bullet points below. Otherwise this would involve a lot of explaining line by line. It is easier to lose a reader in this manner, so I shifted gears here.

My goal is to hopefully find a way to allow access to a Basic download through d64 images. However, to my disappointment, I discovered that WordPress does not allow these type of uploads (because of the MCE Editor). It is used to also rip out scripts that pose a threat. So I created the PDFs by copying snapshots from VICE to Word for now. The only disadvantage is that it is unable to copy the special characters, so listings are not completely accurate. For now this will have to do unless I decide to eventually port everything to Github. You can view the PDF listing for Old West on my Basic Old West Files page or click on the image below.

C64 3D Books

Listed below is a PDF for the Old West Basic programming code and the original book. I found this text adventure within the pages of Compute!’s Commodore Collection Volume One. You can view the program and information starting at page 15. These PDFs can be opened like a 3D book. Just click on each individual image to view them.

[3d-flip-book mode=”thumbnail-lightbox” urlparam=”fb3d-page” id=”1859″ title=”false” lightbox=”dark”]

[3d-flip-book mode=”thumbnail-lightbox” urlparam=”fb3d-page” id=”1874″ title=”false” lightbox=”dark”]

Variables Defined

Variable Description Program Lines
C1,K1,L1,B1,W1,J1,S1 Flags that control tasks completed 100,310,430,435,440,450,460,465,490,805,842,845,850,890,995
N$(x) Contain the objects and hidden objects 500,860,890
V1$ Move directions 550,780,1110
V$ Game verbs (two letter commands) 150,160,560
N$ The game’s objects (two letter commands) 210,220,465,570,730,855,856,1120
L(x) Controls the items you can see (or that are concealed currently) 135,310,381,382,410,425,435,444,445,460,490,600,610,730,810,842,845,850,856,860,870,880,900,995
M(x,y) Contains the room matrix, which shows the direction you can move in. A zero found here means that movement is blocked. 135, 310,355,360,620,630,640,642,775,860
R$(x) Current room location 650,675,700
TD Delay loop – to pause the message ‘I hear a horse’ seen on the screen 120
CY Loop that changes the ‘cloppity’ colors and repeats the words down the screen 126
N noun variable that tracks the noun entered. Example: N=13 (line 132) is pointing to ‘BL’ – Black Bart 132,225,227,310,350,355,360,370,380,385,405,420,425,430,435,440,441,444,460,480,800,805,842,845,900,910,950,980
S Flag that tracks if you can see something on the screen. S=0 will print ‘nothing special’ otherwise 145,750,760,1080,1140
I Loop that reads through the verb entered (V$). There are 20 verbs. It reads it in two step increments to read each addition verb in the string. Example: V$=”GOTAGEPIOPPUDRMILOGISWFIREUN”. So if you enter GO it reads the first section. Then skip two letters and you will see TA to read TAKE. This reads through based on the verb you typed in 720
L Current room. This is tracked in line 730 to show the objects displayed in each room. It is matched against the array L(x). The variable is created in line 370 to read the room matrix into it. Example: L=M(L,N-21) 132,310,355,360,370,380,385,425,430,460,490,730,765,775,845,860,876,950,980,1080
A$ String variable that reads the input for the player (consisting of move directions (N,S,E,W), (I – inventory), (QU – quit), and the verb and nouns entered 875,1000,1005,1010,1020,1030,1045,1060,1110,1120
B$ String variable that stores the noun entered. Line 1120 reads the noun from the array N$(x). In line 1120 it ends up here if you have type in a move direction (N,S,E,W) and stores it in the variable B$. This ends up storing the two letter movement (SO,EA,WE,LO) there, reading in increments of two letters. Example: B$=MID$(N$,2*I+41,2) 200,220,1000,1030,1120
V Stores the verb variables. Line 160 reads through each verb. Example: V=(I+1)/2 – to read every second two letter combination in the V$ variable 160,300
C Variable that keeps a count of how many items you are carrying. Line 400
NN$(x) – This variable changes an object to indicate further tasks have been completed. Example: Line 430 changes the ‘sink’ seen to ‘sink full of water’ when checking your inventory after you type ‘FILL SIN’ (fill sink)
NN$(x) This variable changes an object to indicate further tasks have been completed. Example: Line 430 changes the ‘sink’ seen to ‘sink full of water’ when checking your inventory after you type ‘FILL SIN’ (fill sink) 430,435,445,810,850,860,890,900
C$ This variable is used when you need to complete a second part to a task: Example: Line 845 is used to interact with the window (‘WI’) 830,840,845,855,990,995

C64 Game Disassembly

100-110 – Clear the screen, setup flag variables, initialize variables, and arrays.
120 – Reads the rooms, move directions, verbs, nouns, objects in range (or hidden), and the room matrix that allows move in a specific direction. Sets the current room to one (L=1). Write the message ‘I hear a rasping noise’
125 Write the message ‘I hear a horse’
126 Write ‘cloppity’, repeated 10 times
130 Goes to line 700
132 If user types ‘LOO BLA’ the system responds with ‘He’s a dangerous outlaw. Be careful.’
135 If not in room Window or you don’t have Black Bart (in inventory) then skip to line 140
136-138 Write ‘You caught black bart! The reward is yours! Then end the game.
142 Write ‘Tell me what to do’. Goes to line 1000.
145 If objects are shown on the screen reset S=0. Then go to line main loop (line 140)
150-170 Check to see a verb matches what is in the variable V$. Read through every other two letters.
180 Write ‘I don’t know how to do that’. Then go to main loop
200 If a verb is not entered or found go to line 300
210-230 Look up a noun in a the variable N$. If a noun was found that track that location in the variable N. Line 227 says if the user entered the noun ‘PI’ then set the noun to ‘BO’. So if the user typed in PIN then set it to ‘BOBBY PIN’.
300 Search for a verb through various lines.
310 If the noun is ‘JAIL’ and you are carrying ‘KEY’ and in room 2 (Sheriff’s Office) then the jail flag is set, and the East location is accessible in room 2. Then go to line 1150. After returning, set room 3 exit to show south direction open. Then go to line 130.
320 Write ‘Can’t do that yet’
330 Go to line 130
350 If noun is not ‘WI’ (window) and the noun is less than 22 (N<22), which means you have ented a noun that can’t be picked up. Then go to line 380
360 If you try to enter a blocked direction location (N,S,E,W) then go to line 395
370 Set the room location to move in since that area exits now. Then go to line 130
380 If the noun entered is not ‘WI’ (window) or the current room is not room 7 Dusty Street then go to line 385
381 Write “Splash–I’m all wet’. Then set the Item you see to ‘water’
382 If the shiny star is hidden then write ‘I found something’. Set the shiny star flag (to keep it visible). Then go to line 130
385 If the entered noun is ‘OP’ (open) and the current room is 9 (Saloon) or the current room is 10 then set room 9 to room 10. Then go to line 130
395 Write “Can’t go that way’. Then go to line 130
400 If you are carrying more than 4 objects then write ‘Got too much–Take inventory’. Then go to main loop
410 If the visible object is not found then write ‘I don’ see it here’. Then go to main loop
420 If the noun is less than 8 in the list or the noun is greater than 19 then write ‘Can’t take that’. Then go to main loop. This tracks an object that you can’t pick up.
425 If the noun is ‘WA’ (water) and you are not in room 2 (Sheriff’s Office) and you are not carrying the bucket then write ‘Can’t do that yet’. Then go to main loop
430 IF the noun is ‘WA’ (water) and you in room 2 (Sheriff’s Office) then change the ‘sink’ object to ‘sink full of water’. Set the water flag. Then go to line 130
435 If the noun is ‘WA’ (water) and you are carrying the bucket then change the bucket object to ‘bucket of water’. Set the water flag. Then go to line 130.
440 If the noun is ‘BL’ (Black Bart) and the sink was already filled with water then go to line 444
441 If the noun is not equal to ‘BL” (Black Bart) then go to line 444
442 Write “Black Bart gets mad! He draws his revolver! That’s the end’. Game ends here
444 If the noun is ‘BL’ (Black Bart) and you not carrying the shiny star then write ‘Can’t do that yet’. Then go to main loop
445 Write ‘Okay’. Add object to your inventory. Reset the items you see array to zero since you picked it up. Go to main loop
450 If you already unlocked the door then write ‘It’s not locked’. Go to main loop
460 If the current room is 2 (Sheriff’s Office) and you are carrying the bobby pin and the jail is still locked and the noun entered is ‘DE’ (desk), ‘DR’ (drawer), or ‘LO’ then go to line 465
462 Go to line 470
465 Set unlocked flag. Set key flag. Write ‘okay’. The object desk is changed to ‘unlocked desk’.
470 Go to main loop
480 If the noun entered is not ‘DE’ (desk) and the noun is not ‘DR’ (drawer) and the noun is not ‘LO’ (look) then write “Can’t’. Go to main loop
490 If the key flag is set and the current room is 2 (Sheriff’s Office) and the key is still hidden then set the key to visible. Then go to line 495
492 Write ‘Okay–there’s something in there’. Go to main loop
500-680 Read in game data (room object, direction movement, verbs, nouns, visible items, room matrix, and the current rooms for the game. Return to line 120
700 Clear the screen. Write ‘I am in a ‘. This will show the current room.
710 Write ‘I see’
720-740 Get a list of the objects seen on the screen.
750 If no objects were found write ‘nothing special’
760 If an object was found reset S=0 to prevent reading other objects in the array
765 If room was no found yet then return
770 Write ‘Obvious exits are ‘
780 Show the directions the player can move in’
790 Return back
800 If the noun is ‘CE’ (cement) or ‘BA’ (bars) then go to line 830
805 If the noun is ‘WH’ (whisky) and Black Bart is not sleeping yet then go to line 870
810 If you are carrying an object then set the flag to remove the object from your inventory. Reduce the item count. Write ‘Okay’. Go to line 130
820 Write “I’m not carrying it’. Go to main loop
830 Write ‘Where’. Wait for input from user
840 If action object entered is not ‘SI’ (sink) and it’s not ‘WA’ (water) and it’s not ‘BU’ (bucket) then go to line 845
842 If the water flag is set and the noun is ‘CE’ (cement) and you not yet carrying the sack of cement then go to line 850
843 Go to line 847
845 If the noun entered is ‘WI’ (window) and you are carrying the bars and you mixed the cement already and the current room is 4 (Window) and the noun is ‘BA’ (bars) then go to line 860
847 Write ‘Cant’ do that yet’. Go to main loop
850 Write ‘Okay. It’s mixed’. Set cement flag. Set sack of cement to hidden. Remove cement from inventory.
855 If the action noun you entered is ‘BU’ (bucket) then set object bucket to ‘bucket of cement mixture’. Go to line 130
856 Set cement object to ‘cement mixture’. Set the water object to show in the room. Go to line 130
860 Write ‘Okay’. Set empty window to ‘barred window’. Set room to 3 (Jail). Open exit in room 4 (Window). Set object bars to hidden. Remove object from inventory. Go to line 130.
870 If you don’t have the bottle of elixir then go to line 847
875 If the verb you entere is ‘GI’ (give) then go to line 900
876 If the current room is not 10 (Room in Back) then go to line 847
880 Set the bottle of elixir to hidden. Write ‘Black bart gulps elixir and immediately falls asleep’.
890 Set sink flag. Remove object from inventory. Set object Black Bart to ‘Sleeping Black Bart’. Go to main loop
900 If the noun is ‘WH’ (whisky) and you are carrying the bottle of elixir then write ‘Glug glug glug’. Remove object from inventory. Go to main loop
910 If the noun is ‘WH’ (whisky) then write ‘Can’t do that yet’. Go to main loop
920 Write ‘Can’t drink that’. Go to main loop
950 If the noun is not ‘PO’ (poster) or the room is not room 1 (Dusty Street) then write ‘Can’t’. Go to main loop
960 Write ‘Wanted alive-Black Bart! $1000 reward’
970 Go to main loop
980 If the noun is not ‘SI’ (sink) or you are not in room 3 (Jail) then write ‘Can’t’. Go to main loop
990 Write ‘How’. Wait for user input.
995 If the noun is ‘WA’ (water) then set the hidden object to water. Set water flag
996 Go to line 130
1000 Wait for user input. Reset navigational move string.
1005 If the noun entered is ‘QU’ (quit) then end the game
1010 If the length of the noun is one go to line 1060
1020-1040 Loop through user input and take store second verb. Then go to line 1045
1030 If the user input contains a space then assign a new string to the first two letters of the word entered after the space (this receives the noun).
1040 End the loop
1045 Assign the noun (first two characters) to a string and return back.
1060 If the user input is not equal to the letter ‘I’ then go to line 1100
1070 Write ‘I’m carrying ‘. Set a variable equal to the current room. Reset room variable to zero. Go to line 720
1080 Set current room variable equal to a new string.
1100-1130 Read through navigational directions string. If the entered direction is not found go to line 1130
1120 Assign the variable A$=”GO”. Assign two letter command movement to a variable, then return
1140 Write ‘Can’t do that’. Reset variable S=1 to indicate that an object exists in your inventory
1150 Set object jail to ‘open jail cell’ and return back.