Commodore 64 (C64) Forum Index
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
Writing text adventures

 
Post new topic   Reply to topic    Commodore 64 (C64) Forum Index -> General
View previous topic :: View next topic  
Author Message
Paul Panks
Lemon64 Donator!
Lemon64 Donator!


Joined: 25 Jul 2003
Posts: 951
Location: Phoenix, AZ (USA)

PostPosted: Wed Feb 20, 2008 5:24 pm    Post subject: Writing text adventures Reply with quote

Writing text adventures
By: Paul Panks (dunric@yahoo.com)

NOTE: This document may be reproduced in any form, for any purpose, provided that this notice and the above title remain fully intact.

Text adventures have a long history stretching back to the early 1970s, when Crowther and Woods developed the original Adventure on a mainframe computer. Soon, a company named Infocom came along and added Zork to the mix. Zork was revolutionary in that the included parser could understand multiple commands on a single line. For example, Zork understood "TURN ON THE LAMP AND GO WEST".

Although fun to play in their own right, there is something to be said about sitting down to write a text adventure. Over at the interactive fiction archive (www.ifarchive.org), there are literally dozens of tools provided for in the creation of new adventure games, many which run on modern platforms like Windows, Linux and the Mac.

Today I will be going over some of the preliminary details of fleshing out a text adventure from scratch. I will start with data structures -- the brains behind the game engine -- and then progress to simple commands such as GO NORTH and GET SWORD. Finally, I will wrap up this article by commenting on future expansion of the adventure game shell provided in this article.

DATA STRUCTURES

Data structures are tables of data which are indexed into arrays, giving the computer something better to work with -- numbers (for computers do far better with numbers than words.)

But the first thing anyone considering writing a text adventure must do is to create some ideas on paper first. An example might be writing down a short introduction to the game and what the ultimate goal of the adventure is. Another good thing to do while fleshing out the storyline is to create a small list of objects that could be useful during gameplay.

As an example, suppose you have the idea to create an adventure whereby the goal is to retrieve a stolen gem from a large, menacing dragon. Your word list might look something like this (along with any object descriptions of the objects):

NORTH (A direction heading north.)
SOUTH (A direction heading south.)
EAST (A direction heading east.)
WEST (A direction heading west.)
UP (A direction heading up.)
DOWN (A direction heading down.)
LANTERN (A brass lantern with blood-stains on it.)
OIL (A flask of oil. Used with the lantern.)
ROPE (A coil of rope about ten feet in length.)
SWORD (A long sword with a ruby hilt.)
RUBY (A gleaming ruby! It shines brightly.)
HELLHOUND (A fiery hellhound from the gates of hell!)
DRAGON (A large, menacing dragon with sharp scales and claws!)

...

and so on. Obviously, you can add more as the game goes along.

The stated goal should be to fill your adventure with as many useful objects as possible. Even in small adventures where you might not have many rooms, it always helps to have objects that can be picked up, used or otherwise manipulated in some way. This not only enhances the adventure experience, but it provides for useful puzzles down the road.

To put these objects into a data array (data structures, as you might recall, are simply tables of data used by the program) you would do the following:

10 NM=13:R=13:VL=8:DIM NO$(NM),EX$(NM),M%(R,6),DE$(R)
15 DIM VB$(VL),LO(NM)
20 FOR X=1 TO NM:READ NO$(X):READ EX$(X):NEXT
1001 DATA"NORTH","(A direction heading north.)
1002 DATA"SOUTH","(A direction heading south.)
1003 DATA"EAST","(A direction heading east.)
1004 DATA"WEST","(A direction heading west.)
1005 DATA"UP","(A direction heading up.)
1006 DATA"DOWN","(A direction heading down.)
1007 DATA"LANTERN","(A brass lantern with blood-stains on it.)
1008 DATA"OIL","(A flask of oil. Used with the lantern.)
1009 DATA"ROPE","(A coil of rope about ten feet in length.)
1010 DATA"SWORD","(A long sword with a ruby hilt.)
1011 DATA"RUBY","(A gleaming ruby! It shines brightly.)
1012 DATA"HELLHOUND","(A fiery hellhound from the gates of hell!)
1013 DATA"DRAGON","(A large, menacing dragon with sharp scales and claws!)

Now that you have a list of objects, it is time to determine a map for the adventure. You need a map for two reasons: first, to be able to move around the adventure from room to room, and secondly, to place objects within these rooms so that the player can interact with them in some meaningful way.

I usually just use the six compass directions of North,South,East,West,Up and Down. Some exclude both the up and the down to use only 4 directions, but I find that including UP and DOWN can be helpful for rooms that require moving up and down flights of stairs, for example.

Let's say you've drawn up a small map as follows:

3-4 9
/ /
1-2 7-8
| |
5-6
|
10-11
|
12-13

In data structure form, your map may look like this:

1999 FOR X=1 TO R:FOR Y=1 TO 6:READ M%(X,Y):NEXT:NEXT
2000 REM N, S, E, W, U, D
2001 DATA 0, 0, 2, 0, 0, 0
2002 DATA 3, 5, 0, 1, 0, 0
2003 DATA 0, 0, 3, 0, 0, 0
2004 DATA 0, 0, 0, 3, 0, 0
2005 DATA 2,10,6, 0, 0, 0
2006 DATA 7, 0, 0, 5, 0, 0
2007 DATA 0, 6, 8, 0, 0, 0
2008 DATA 9, 0, 0, 7, 0, 0
2009 DATA 0, 8, 0, 0, 0, 0
2010 DATA 5, 0, 11, 0, 0, 0
2011 DATA 0, 0, 0, 10, 0, 0
2012 DATA 11, 0, 13, 0, 0, 0
2013 DATA 0, 0, 0, 12, 0, 0

This map is fairly small -- only 13 rooms -- but it can easily be expanded by changing the variable "R" in the DIM statement in line 10.

Now for a quick verb list. Verbs are useful in the game for GOing places and DOing things. Verbs can be as easy as this:

2100 FOR X=1 TO VL:READ VB$(X):NEXT
2101 DATA "GO","GET","DROP","INVENTORY","EXAMINE","READ"
2102 DATA "USE","LIGHT"

This is a sufficient verb list for most small adventures. But remember to add to it as you think of new verbs along the way.

It is always helpful to define where an object will be in the adventure. You can do that as follows:

2500 FOR X=1 TO NM:READ LO(X):NEXT
2501 DATA 99,99,99,99,99,99
2507 DATA 4,4,8,11,1013,10,13

You also need room descriptions for each room. This isn't as hard as it might seem. Just store the results in DE$(x), as follows:

3000 FOR X=1 TO R:READ DE$(X):NEXT
3001 DATA"You are inside a small tavern. A staircase leads upstairs onto a narrow hallway."
3002 DATA"You are standing before a staircase within the tavern. You can can ascend the staircase here."
3003 DATA"You are on a narrow hallway upstairs of the main tavern. A room lies to the east."
3004 DATA"You are inside a small room. There isn't much here save for a small bed. It looks comfortable."
3005 DATA"You are standing outside the tavern by a large fountain. Water pours out into a mottled basin below. A church is east."
3006 DATA"You are standing inside a small church. Pews down the room, while an altar is directly north."
3007 DATA"You are standing in front of a stone altar. Sacrifices are made here to the Gods. A room is east."
3008 DATA"You are inside a small room. Large wooden barrels can be seen near the back wall. A door is north."
3009 DATA"You are walking in a neglected garden overgrown with weeds. No one seems to have cared for it lately."
3010 DATA"You are walking in a forest. A path heads east into a dark cave."
3011 DATA"You are standing inside a dark cave. Very little light can be seen here. It turns south around a bend just below. There are words scratched upon the wall. You also notice a hole here, where you can descend down into the cavern below."
3012 DATA"You are walking in a small tunnel inside the cave. It feels wet here, like water is dripping nearby."
3013 DATA"You have reached an underground pool of water, complete with cascading waterfall. The smell of smoke and ash is quite heavy here!"

We now have most of the data we'll need to make a simple adventure. But how to process this data? A parser is need to read in user imput. Parsers can be easy or they can be complex. A simple one is listed below:

100 v=0:n=0:ne$="":n$="":n2$="":v$="":v2=0:
a$="":pr=0:pt=0:nm=0:bz=0:FOR X=1 TO 10:wd$(x)="":NEXT x
101 INPUT A$:pt=1:nm=0:D$=A$:FOR a=1 TO LEN(D$)
102 IF MID$(D$, a, 1)=" " THEN A$=MID$(D$,pt,a-pt):
pt=a+1:nm=nm+1:wd$(nm)=A$
103 NEXT a:nm=nm+1:a$=MID$(D$,pt,a-pt):wd$(nm)=A$
104 v$=wd$(1):n$=wd$(2):IF wd$(3)="and" OR
wd$(3)="then" THEN v2$=wd$(4):n2$=wd$(5):co=1
105 IF wd$(3)="in" OR wd$(3)="from" OR wd$(3)="to"
THEN v$=wd$(1):ne$=wd$(2):pr=1:bz=1

This parser takes each word in a sentence, breaking them into individual words used by the program. This is the easiest and most efficient way that I know of to do this. An advantage to a parser like this is the ability to "put" objects in other objects and use multiple commands, i.e. "GET LAMP AND GO NORTH".

Now that the parser has been written, we need to extend it slightly by checking words entered against our own object list stored in NO$(x). A way to do this follows:

106 V=0:FOR X=1 TO VL:IF VB$(X)=V$ THEN V=X:X=100
107 NEXT:IF V=0 THEN PRINT"I don't understand your verb.":GOTO 100
108 N=0:FOR X=1 TO NM:IF NO$(X)=N$ THEN N=X:X=100
109 NEXT

Here comes the best part: the verbs and nouns can now branch to certain, specific routines used in the game. We will use the ON x GOTO command below:

115 ON V GOTO 120,130,140,150,160,170,180,190

Listed below are the command subroutines for GO, GET, DROP, INVENTORY,EXAMINE,READ,USE and LIGHT:

119 REM GO
120 IF LT=0 THEN IF RM=11 AND N=2 THEN PRINT"It is much too dark to see!":GOTO 100
121 IF RM=11 AND N=2 OR RM=11 AND N=6 THEN IF LO(9)<>0 THEN PRINT"You need the coil of rope to descend down the cavern.":GOTO 100
122 IF M%(R,N)=0 THEN RM=M%(R,N):PRINT DE$(RM):GOTO 100
123 PRINT "You can't go that way!":GOTO 100

129 REM GET
130 IF LO(N)<>0 AND LO(N)<>RM AND LO(N)<>105 AND LO(N)<>205 THEN PRINT"That isn't here.":GOTO 100
131 IF N=12 OR N=13 THEN PRINT"It's beyond your power to do that!":GOTO 100
132 IF IC>5 THEN PRINT "You are carrying too much!":GOTO 100
133 LO(N)=0:IC=IC+1:PRINT "OK.":GOTO 100

139 REM DROP
140 IF LO(N)<>0 THEN PRINT"You can't drop that.":GOTO 100
141 LO(N)=RM:IC=IC-1:PRINT"OK.":GOTO 100

149 REM INVENTORY
150 SI=0:FOR X=1 TO NM:IF LO(X)=0 THEN PRINT " ";NO$(X):SI=1
151 IF LO(X)=105 THEN PRINT " ";NO$(X);" (wielded)":SI=1
152 IF LO(X)=205 THEN PRINT " ";NO$(X);" (worn)":SI=1
153 NEXT:IF SI=0 THEN PRINT"Alas, you are empty handed.":GOTO 100
154 GOTO 100

159 REM EXAMINE
160 IF LO(N)<>RM AND LO(N)<>0 AND LO(N)<>105 AND LO(N)<>205 THEN PRINT "That isn't here.":GOTO 100
161 PRINT EX$(N):GOTO 100

169 REM READ
170 IF RM=11 THEN ?"The writing on the wall reads: 'BEWARE THE TERRIBLE DRAGON WITHIN!":GOTO 100
171 PRINT "You see nothing unusual.":GOTO 100

179 REM USE
180 IF LO(N)<>RM AND LO(N)<>0 AND LO(N)<>105 AND LO(N)<>205 THEN PRINT "That isn't here.":GOTO 100
181 IF N=7 THEN PRINT "Please use 'light' instead.":GOTO 100
182 IF N=9 AND RM<>11 THEN PRINT "You can't use the rope here.":GOTO 100
183 IF N=9 AND RM=11 THEN RM=12:?"You use the rope and climb down...":RM=12:PRINT DE$(RM):GOTO 100
184 PRINT "You can't use that here.":GOTO 100

189 REM LIGHT
190 IF LO(N)<>RM AND LO(N)<>0 AND LO(N)<>105 AND LO(N)<>205 THEN PRINT "That isn't here.":GOTO 100
191 IF N=7 AND LO(8)=0 THEN LT=1:PRINT "Poof! The lantern is now aflame.":GOTO 100
192 PRINT "You can't light that here.":GOTO 100

Hopefully, this article has given you some idea of how to get started writing your own adventures. An adventure can be big or small, but the main point is that in creating your own you are painting your own universe upon the window of computing!

Paul
_________________
It's always 2:06.
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger
mtboggs88
Groupie in Training
Groupie in Training


Joined: 17 Apr 2006
Posts: 137
Location: N.E. OHIO, USA

PostPosted: Wed Feb 20, 2008 6:16 pm    Post subject: Reply with quote

I was recently thinking about doing one. Have you ever looked into using Adventure Writer? It seems a bit simplistic but works for those less advanced games.
Back to top
View user's profile Send private message Yahoo Messenger
Mr Do
Lemon64 Donator!
Lemon64 Donator!


Joined: 24 Oct 2003
Age: 36
Posts: 2216
Location: Holland

PostPosted: Wed Feb 20, 2008 6:19 pm    Post subject: Reply with quote

Read
Read what ?
Read the mega long post of Paul Panks
You just died of hunger
_________________

I can wake up in the middle of the night and start searching for a three-headed monkey. (Sir Kidd)
Back to top
View user's profile Send private message Send e-mail AIM Address MSN Messenger
Schema
C64 Enthusiast
C64 Enthusiast


Joined: 28 May 2002
Age: 36
Posts: 898
Location: Toronto, Canada

PostPosted: Wed Feb 20, 2008 6:25 pm    Post subject: Reply with quote

There's a documentary on text adventures under way. It's being made by Jason Scott who also did the BBS Documentary.

http://www.getlamp.com/
Back to top
View user's profile Send private message Visit poster's website
DanSolo
Grandmaster of C64
Grandmaster of C64


Joined: 23 May 2006
Posts: 2746

PostPosted: Wed Feb 20, 2008 11:19 pm    Post subject: Reply with quote

Paul, did you ever try a compiler with one of your text adventures? I wrote one myself years ago (long lost...), and I found the verb finder incredibly slow.
And as for Adventure Writer... what a cop out! No customisation possibilities.
Back to top
View user's profile Send private message
Retrovertigo
Groupie
Groupie


Joined: 21 Mar 2003
Posts: 247
Location: Ireland

PostPosted: Thu Feb 21, 2008 11:10 am    Post subject: Reply with quote

Mr Do wrote:
Read
Read what ?
Read the mega long post of Paul Panks
You just died of hunger


Laughing
Back to top
View user's profile Send private message
Zoozie
Newbie


Joined: 30 May 2005
Posts: 24

PostPosted: Fri Feb 22, 2008 5:40 pm    Post subject: Reply with quote

Interesting! And the code is not that bad as I would have expected
for a Basic implementation of this problem.

But I must say that OO-languages (C++, Java) makes this much easier and the code is also easier to understand.
Back to top
View user's profile Send private message
DanSolo
Grandmaster of C64
Grandmaster of C64


Joined: 23 May 2006
Posts: 2746

PostPosted: Fri Feb 22, 2008 8:26 pm    Post subject: Reply with quote

Not if BASIC 2.0 is your first and only programming language it's not!
Back to top
View user's profile Send private message
Paul Panks
Lemon64 Donator!
Lemon64 Donator!


Joined: 25 Jul 2003
Posts: 951
Location: Phoenix, AZ (USA)

PostPosted: Sat Feb 23, 2008 5:09 pm    Post subject: Reply with quote

Missed a few things in this article:

Add these lines

50 PRINT DE$(RM)
51 FOR X=1 TO 6:IF M%(RM,X)>0 THEN PRINT NO$(X);" ";
52 NEXT:FOR X=7 TO 13:IF LO(X)=RM THEN PRINT NO$(X)
53 NEXT
_________________
It's always 2:06.
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger
mtboggs88
Groupie in Training
Groupie in Training


Joined: 17 Apr 2006
Posts: 137
Location: N.E. OHIO, USA

PostPosted: Sat Feb 23, 2008 5:27 pm    Post subject: Reply with quote

LOL
Back to top
View user's profile Send private message Yahoo Messenger
Display posts from previous:   
Post new topic   Reply to topic    Commodore 64 (C64) Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Tip: Get C64 Forever for super-comfy C64 emulation with pre-installed games, demos and other goodies!


Powered by phpBB © 2001, 2005 phpBB Group