+ Reply to Thread
Results 1 to 1 of 1
  1. #1
    jared's Avatar
    jared is offline Staff
    Join Date
    Oct 2008

    Default Writing Text Adventures

    Found this from Lemon64, thought it would interest people here:

    Writing text adventures - Commodore 64 (C64) Forum

    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 (The Interactive Fiction Archive), 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 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)
    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
    | |

    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
    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):
    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

    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

    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
    Last edited by jared; 02-09-2009 at 10:38 AM.



Similar Threads

  1. writing a text adventure on the commodore 64
    By Guest 1030 in forum Guests
    Replies: 0
    Last Post: 08-07-2010, 06:16 PM
  2. writing text adventure in basic
    By Guest 2452 in forum Guests
    Replies: 0
    Last Post: 06-06-2010, 11:19 AM
  3. Writing Text Adventures
    By jared in forum Commodore
    Replies: 1
    Last Post: 06-04-2009, 01:36 PM

All times are GMT -7. The time now is 11:36 PM. Copyright (c) 2008 - 2011 RarityGuide, Inc. All rights reserved. All trademarks and copyrights are the property of their respective owners.