Trevor Toms
The ZX81 Pocket Book
Reston Publishing Co., Reston, Virginia, 1981

ZX81 Adventure - Create Your Own

Suitable for : 16K RAM

This program allows you to create your own adventure-type games on the ZX81! A complete game is included for you to see how it is done, and also to give you a bit of fun into the bargain.

If you are already acquainted with the original Adventure game, then you may prefer to skip the next few paragraphs.

Adventure was originally written to run on computers somewhat larger than a ZX81 (having roughly 256K bytes of memory available - think about that!), and running faster as well. The game does not vary from one run to another, as the layout of the game remains fixed. Although this may seem a bit limited, the original version is so large that you become bored with playing before you find out all there is to know.

So how is it played? The game takes place in a network of caves, and the object of the game is to gather all the treasure that is dotted around in these caves. Some of the treasure cannot be taken straight away - for example, there is a pearl stuck inside a giant clam, and part of the fun of the game is to discover a way of getting the clam open.

At each turn, you are given a description of your current location. Then the game waits for you to type in up to two keywords. These keywords may ask for you to be moved in a certain direction (for example: GO SOUTH or WALK EAST or CLIMB UP) or to manipulate an object which is in sight - TAKE GOLD or TAKE JEWELS etc.

The objects are not necessarily treasures; they may seem useless at times, but nearly always have some use throughout the game to enable you to get past an obstacle.

In order to give the game some "spice", dwarves pop up at random and throw knives at you (if one hits you, you are killed), although you can retaliate with an axe or some other weapon.

Since the original game is too vast to run on a ZX81, I have borrowed several ideas from different sources to bring a version which can be tailored to run many different games - you will be quite capable of producing your own and swapping them with friends. The game comes in three portions:-

Adventure Master programwhich controls the flow of the game and checks that all commands are suitably obeyed
Adventure Loaderwhich allows you to set up games of your own
Adventure Informationthis makes each game unique - it contains the room descriptions, keyword actions, objects etc.

Steps in creating your Adventure

If this is your first encounter with Adventure-type games, I would suggest that you start by entering the games in this section, playing them, then returning to this text when you have a better idea of the capabilities of the game.

The steps involved in creating a game are as follows:-

1.Enter the Master program and the Loader routine together. Save this combination on tape, as it becomes the basis for all your own games.
2.Enter the text messages and room descriptions (use either "The City of Alzan" or the mini-test game found later on).
3.Type RUN 9000 to start the Loader program. Enter all the arrays and variables as given in the appropriate game. The Loader program will automatically save the program for you.
4.Start the game by GOTO 10 (not normally required, since the Loader program ensures that the game starts once loaded from tape).

How the Master program works

The following discussion may seem involved, but if you follow the Test Adventure carefully (I have annotated it fully), you should quickly grasp the way that the Master program works.

Referring to the three portions of the game mentioned above, the Information section requires several items in order to make a complete game. You may like to look at the Test Adventure while you see how the Information section is built up. The items required are:-

1. Room descriptions

Each room has a unique number associated with it in the range 1 to (max. no. of rooms), and the Master program causes a subroutine call to line 8000+(room*10) so that the room description can be printed. This means that the description for room number 1 should start at line 8010, and a RETURN statement should be included after the description is printed, Room 2 description will be at line 8020, room 3 at 8030, and so on.

2. Text messages

These are messages which are printed by the Master program on request (see later). The reason for printing these messages can be extremely varied - for example, if the keywords "LIGHT LAMP" are entered, and the lamp is already lit, then you may want to print a message saying so. As for rooms, each message has a unique number starting from 1, and message number 1 should be placed at line number 7010 (followed by a RETURN statement). Message 2 should be placed at line 7020, and so on.

3. Objects

Objects can be used by the player throughout the game either carried or just manipulated in some way. Each object needs an entry in two arrays - O() which tells the Master program in which room the object is (initially) located, and O$() which contains the text describing the object. This description is 16 characters in length (although you could alter this if required for a particular game). The simple variable O contains the total number of objects. An object which does not initially exist must be given a room number of zero.

4. Vocabulary

This table gives a list of the keywords that your game will recognise as words to be acted upon (in some way). With each word is a two-digit number that this keyword is translated into, so that two different keywords can be translated into the same action (e.g. LEAVE and EXIT would both be given the same two-digit code as they both have the same interpretation). The first twelve keywords are reserved for direction commands (NORTH, SOUTH, UP, DOWN etc), but this is not totally inflexible. These keywords are held in array V$(), and each entry is 6 characters long. The first four are the keyword (only the first four characters of the keyword are matched) and the last two are the two-digit "translated code" number. Note that the code number must have a leading zero for codes less than 10. Variable V should contain the total number of keywords in the array V$().

5. Room connection table

Array M$() contains a table of the "tunnels" connecting each room. For every room, there is an entry showing the number (and direction) of tunnels leading away from the room. Each tunnel requires four characters - two to give the keyword code corresponding to the direction of this tunnel, and two representing the room number that the tunnel leads to (with leading zeros if necessary). A keyword code of "00" indicates the end of the list for this room. As an example, room 1 would be held in M$(1) and might look like:-

M$(1) "0127061300"

This indicates that keyword code 01 will cause the Master program to continue at room 27, while keyword code 06 will cause the Master to continue at room 13. The final 00 signifies the end of the list.

Variable R should contain the total number of rooms. Array M$ allows for 32 characters per room maximum - this will be adequate for almost any set-up.

6. Action table

The action table gives a list of actions to be performed when certain keywords (or combinations of keywords) are entered. Note that direction movements are catered for by the Room Connection table above. Each entry in the Action table gives:-

Keyword 1 code (or 00 if any word is sufficient)
Keyword 2 code (or 00 if any word is sufficient)
Further conditions

Actions to be performed if all conditions are met. A small example at this stage might be :- "If the keywords "LIGHT LAMP" are entered and the lamp is already alight, then display message 5"

A full list of available conditions and actions can be found below, but the overall format of each entry is:

AABBC01C02.A01A02A03.

...where AA and BB represent the keyword codes for two keywords, C01 C02 represent additional conditions (you may have more than two) followed by a full-stop which indicates the end of conditions. Next follows the appropriate action codes (A01 A02 and A03 - again, you may have more if you wish) also terminated by a full-stop. A complete example is given after the tables below.

Array A$() contains the action table, and variable A must contain the total number of items in the array.

The limit of each entry in array A$() is 31 characters. If this should be insufficient, you can get round the problem by including one action that sets a temporary marker. Further entries can be added into the array C$() which test for this marker and continue the required effects, then unset the temporary marker. This idea is used in "The City of Alzan"

7. Conditional table.

This table is almost identical to the Action table, but does not have any associated keywords. This table is scanned before each command is entered, and allows you to cater for some special circumstances, such as having a dwarf pop up in front of the player, or displaying different messages dependant on certain conditions. Array C$() contains the conditions and variable C contains the total number of items in the array. The format of each entry is:-

C01C02.A01A02.

...where C01 C02 A01 etc are defined as for the Action table. Notice the full-stops that terminate both the conditions and actions.

The various conditions you may use consist of three-character codes. The first is a letter which signifies the desired condition, the last two are a two-digit parameter associated with the condition (shown as nn below):-

Condition codeTest made
Ann is the current room number
BObject nn is here (or being carried)
CObject nn is not here (or being carried)
DObject nn is being carried
EMarker nn is set
FMarker nn is not set
GCountdown nn has reached value 1
HRandom number from 1-99 is less than nn

Action codeAction performed
APrint list of objects carried
BCarry object nn
CPut down object nn
DDisplay text message nn - causes GOSUB to line 7000+(nn*10)
ESet marker nn
FUnset marker nn
GSet countdown nn to the value mm
HSwap objects nn and nn+l in the object table
ISet object nn into current room number
JSet object nn room number to 00
KSet current room number to nn (i.e. forced move to room nn)
LPrint "OKAY" and await a new command
MAwait a new command
NAwait a new command, but the Conditional table is not scanned first
ODescribe current room then await new command
PAbandon the game (player is asked "ARE YOU SURE?" and if the answer is Y then the game is abandoned)
QStop the game

Here is an example of these in use:-

The keyword "TAKE" has (say) the keycode 15, and "GOLD" has the keycode 22. The object "gold" is number 3.

Suitable entries into the Action table might be:-

1522B03.B03L.

This means:-

Keywords 15 and 22 must be typed (TAKE GOLD), and the condition B03 must also be true (i.e. object 03 must be here or being carried). If this is true, then actions B03 and L are obeyed - object 03 is now carried, and then the message "OKAY" is printed and a new command is input.

There are 10 "markers" that can be set/unset and tested (see the above tables). All markers are initially unset. Markers 1 to 3 have a special significance to the Master program, but all others can be used as required. The special ones are:-

1Indicates the total number of objects being carried
2Tells the Master program whether the room is a "dark" room or "light" room - i.e. whether a lamp is required in order to see.
3Tells the Master program whether a lamp is off or on.

If the room is a "dark" room, and the lamp is off, the Master program prints a message "IT IS DARK. BETTER GET SOME LIGHT OR YOU MAY BE IN TROUBLE".

Marker 2 should be unset when the player is above ground, and set once he goes underground.

There are also 5 countdown markers that are for general use. They can be set to any desired two-digit value by using Action code G. This code requires two parameters - the countdown number and the value it is to be given. E.g. G0105 would set countdown 1 to the value 5. Countdowns 1 to 4 are automatically reduced under certain conditions by the Master program:-

1Reduced each time a command is entered.
2Reduced each turn when marker 2 is set (i.e. when the player is in "dark" rooms).
3Reduced each turn when marker 2 is set but marker 3 is not - i.e. when the player has not got a lamp on but it is dark. This lets you drop the player in a pit after (say) three moves in total darkness.
4Reduced each time a command is entered (as for countdown number 1).

Condition 7 lets you test if a countdown marker has reached the value 1, so that you can perform some actions once a limit has been reached.

You should note the following points:-

1.A maximum of 5 objects can be carried at any one time (line 4100 in the Master program). Further objects can only be picked up if another object is dropped first.
2.The Master program checks that you are not already carrying an object when it obeys action B, and that you are carrying the object when it obeys action C. This saves quite a considerable number of items in the Action table.

At the end of the program listing, you will find a small "test" adventure of four rooms, which will allow you to see what is going on and also see if your new program works.

You may like to send a copy of your own Adventure games to us at the address given at the front of this book - if we receive enough good ones to publish, we will pay for all those included.

1REM ZX81 ADVENTURE MASTERTape name: "ADVENT"
2REM *********************
3PRINT "DO NOT USE ""RUN""."(see pages 95-96
10DIM S(10)(switch array
20DIM C(5)(countdown array
30LET ROOM=1(initial room no.
40DIM P$(2,2)(keywords 1 & 2
50DIM O(O)(objects array - type the
(letter "O" and not "0".
60FOR X=1 TO O(set up objects initially
70LET O(X)=Q(X)
80NEXT X
100IF NOT S(2) THEN GOTO 200(test if darkness
110IF C(2) THEN LET C(2)=C(2)-1(darkness countdown
120IF S(3) THEN GOTO 200(see if lamp on
130PRINT "IT IS DARK - BETTER GET SOME",
"LIGHT OR YOU MAY BE IN TROUBLE."
140IF C(3) THEN LET C(3)=C(3)-1(no lamp countdown
150GOTO 1000(wait for a command
200REM DESCRIBE ROOM
210PRINT
220GOSUB 8000+ROOM*10(print room description
300LET F=0(reset flag
310FOR X=1 TO O(print any objects here
320IF O(X)<>ROOM THEN GOTO 500
330IF F THEN GOTO 400
340PRINT ,,"THERE IS ALSO:"
350LET F=1
400PRINT " ";O$(X)
500NEXT X
1000REM ACCEPT COMMAND(await a command
1010LET T=1(first check automatics
1020GOTO 2000
1100IF C(1) THEN LET C(1)=C(1)-1(countdown every command
1110IF C(4) THEN LET C(4)=C(4)-1(countdown every command
1120PRINT ,,">"(prompt - use inverse
1130INPUT Y$(input command
1140CLS
1150LET Y=0(command scan
1160PRINT ">";Y$(print command at top
1170LET P$(2)="00"
1200FOR W=1 TO 2(get (up to) two keywords
1210GOSUB 6000
1220IF Y>=LEN Y$ THEN GOTO 1300(check if all scanned
1230IF P$(W)="00" THEN GOTO 1210(was the keyword found?
1240NEXT W(next keyword
1300IF P$(1)<>"00" THEN GOTO 1600(was at least one word?
1310PRINT " PARDON?"(printed if nothing found
1320GOTO 100(try again
1600REM CHECK FOR MOVEMENT
1610LET Z=1(now scan movement table
1620LET T$=M$(ROOM)(Z TO Z+1)(get matching keyword
1630IF T$="00" THEN GOTO 1900(check if end of entry
1640IF T$<>P$(1) THEN GOTO 1700(see if it matches word 1
1650LET ROOM=VAL (M$(ROOM) (Z+2 T0 Z+3))
1660GOTO 100(continue in new room
1700LET Z=Z+4(try next match
1710GOTO 1620
1900LET T=0(set "Action table" flag
1910LET MATCH=0(no match found yet
2000REM CHECK FOR CONDITIONALS
2010LET CP=0(table subscript number
2100LET CP=CP+1
2110IF NOT T THEN GOTO 2300(see if scanning Action
2120LET E$=C$(CP)(get from Conditionals
2130GOTO 2600
2300IF CP<=A THEN GOTO 2400(have all been scanned?
2310IF MATCH THEN GOTO 1000(has a match been found?
2320PRINT "YOU CANT";(print message
2330IF VAL (P$(1))<13 THEN PRINT " GO THAT WAY";
2340PRINT "."
2350GOTO 100(try again
2400IF A$(CP) (1 TO 2)<>P$(1) THEN GOTO 2100
(check if matches key 1
2410LET Y$=A$(CP)(3 TO 4)(get keycode 2
2420IF Y$<>"00" AND Y$<>P$(2) THEN GOTO 2100
2430LET E$=A$(CP)(5 TO )(get conditions/actions
2600REM CONDITIONS
2610LET E=1(now scan further conds.
2700IF E$(E)="." THEN GOTO 3000(full-stop ends conds.
2710LET TYPE=CODE (E$(E))-38(get condition code
2720LET N=VAL (E$(E+1 TO E+2))(get parameter
2800GOSUB 2900+TYPE*10(evaluate if true/false
2810IF NOT OK THEN GOTO 2100
2820LET E=E+3(try next condition
2830GOTO 2700
2900LET OK=(N=ROOM)(condition A - see
2905RETURN( text
2910LET OK=(O(N)=ROOM OR O(N)<0)(condition B
2915RETURN
2920LET OK=(O(N)<>ROOM AND O(N)>=0)(condition C
2925RETURN
2930LET OK=(O(N)<O)(condition D
2935RETURN
2940LET OK=S(N)(condition E
2945RETURN
2950LET OK=(NOT S(N))(condition F
2955RETURN
2960LET OK=(C(N)=1)(condition G
2965RETURN
2970LET OK=((INT (RND*100)+1)<=N)(condition H
2975RETURN
3000REM ACTIONS
3010LET MATCH=1(now perform actions
3020LET E=E+1
3100IF E$(E)="." THEN GOTO 2100(all done?
3110LET TYPE=CODE (E$(E))-38(get action code
3120IF E$(E+1)<>"." THEN LET N=VAL (E$(E+1 TO E+2))
(get any parameter
3200LET BREAK=0(return line number
3210GOSUB 4000+TYPE*100(perform action
3220IF BREAK THEN GOTO BREAK(goto relevant line
3230LET E=E+3(next action
3240GOTO 3100
4000PRINT(action A - see table
4010PRINT "YOU ARE HOLDING:"
4020LET F=1
4030FOR X=1 TO O(the letter "O" not "0"
4040IF O(X)>=3 THEN GOTO 4070
4050PRINT " ";O$(X)
4060LET F=0
4070NEXT X
4080IF F THEN PRINT " NOTHING."
4090LET BREAK=100
4095RETURN
4100IF S(1)<5 THEN GOTO 4140(action B
4110PRINT "YOU CANNOT CARRY MORE."
4120LET BREAK=100
4130RETURN
4140IF O(N)=-1 THEN GOTO 4180
4150LET O(N)=-1
4160LET S(1)=S(1)+1
4170RETURN
4180PRINT "YOU ALREADY HAVE IT."
4190GOTO 4120
4200IF O(N)=-1 THEN GOTO 4240(action C
4210PRINT "YOU DONT HAVE ";O$(N)
4220LET BREAK=100
4230RETURN
4240LET O(N)=ROOM
4250LET S(1)=S(1)-1
4260RETURN
4300PRINT(action D
4310GOSUB 7000+N*10
4320RETURN
4400LET S(N)=1(action E
4410RETURN
4500LET S(N)=0(action F
4510RETURN
4600LET C(N)=VAL (E$(E+3 TO E+4))(action G
4610LET E=E+2
4620RETURN
4700LET X=O(N)(action H
4710LET O(N)=O(N+1)
4720LET O(N+1)=X
4730RETURN
4800LET O(N)=ROOM(action I
4810RETURN
4900IF O(N)<0 THEN LET S(1)=S(1)-1(action J
4910LET O(N)=0
4920RETURN
5000LET ROOM=N(action K
5010RETURN
5100PRINT " OKAY."(action L
5200LET BREAK=1000(action M
5210RETURN
5300LET BREAK=1100(action N
5310RETURN
5400LET BREAK=100(action O
5410RETURN
5500PRINT " ARE YOU SURE? ";(action P
5510INPUT W$
5520PRINT W$
5525LET BREAK=1100
5530IF CHR$ CODE W$<>"Y" THEN GOTO 5400
5600GOTO 9999(action Q
6000REM REMOVE WORD
6010DIM W$(4)(first four letters
6015LET P$(W)="00"(set "not found" reply
6020GOSUB 6600(find first character
6025IF END THEN RETURN(test if end of command
6030FOR Q=1 TO 4(get four letters
6040LET W$(Q)=Y$(Y)
6050GOSUB 6500(check if word end
6060IF END THEN GOTO 6100
6070NEXT Q
6080GOSUB 6500(look for end of word
6090IF NOT END THEN COTO 6080
6100IF W$=" " THEN RETURN(no word entered
6110FOR Q=1 TO V(scan vocabulary table
6120IF W$=V$(Q)(3 TO ) THEN GOTO 6200
6130NEXT Q
6140RETURN(not found in table
6200LET P$(W)=V$(Q) ( TO 2)(get keyword code number
6210RETURN
6500LET Y=Y+1(check for end of word
6510LET END=(Y>LEN Y$)
6520IF END THEN RETURN
6530LET END=(Y$(Y)=" ")(don't forget the space!
6540RETURN
6600LET Y=Y+1(look for end of word
6610LET END=(Y>LEN Y$)
6620IF END THEN RETURN
6630IF Y$(Y)=" " THEN GOTO 6600(don't forget the space!
6640RETURN
7000REM ACTION MESSAGES
7001REM MESSAGE NO. 1 CAUSES
7002REM COSUB TO LINE 7010
7999RETURN
8000REM ROOM DESCRIPTIONS
8001REM ROOM 1 CAUSES A
8002REM GOSUB TO LINE 8010
9999STOP

Now that you have the "central manager" portion, you need two further items before you can start running a game. First is a "game loader" routine that initialises all the essential arrays (like the object table, interconnecting room table, vocabulary table, and the automatic and conditional event tables) plus a few other variables. The second item is the game itself - all you have here is something that allows you to quickly create your own adventures.

Two complete mini-adventures are included here for you to load and run yourself, so that you can see how it all fits together (and have a laugh, I hope!), but first, here's the loader routine.

Adventure Loader

This routine should be included with the manager program above, but it can be removed once the various arrays have been properly installed. I would advise you to keep the routine in your game until you have tested it properly - if you miss a few words out of the vocabulary table (or any other table) and you want to re-enter it, then you'll feel mad if you've just deleted the loader routine!

When you run it, it asks how many items are required in each array (like the vocabulary table), then dimensions the array, and inputs the elements one-by-one. It stops after each array has been created, thus giving you an opportunity to check what you’ve done. If you are re-entering an array that was incorrect, it also gives you a chance to re-input only one array and not all of them.

9000REM GAME ARRAY LOADER
9010CLS
9020PRINT "NO. OF OBJECTS?"
9030INPUT O
9040DIM Q(O)
9050DIM O$ (O,16)
9080FOR X=1 TO O(type the letter "O" not "0".
9090SCROLL
9100PRINT "NO. ";X;" ROOM?",
9110INPUT Q(X)
9120PRINT Q(X)
9130SCROLL
9140PRINT "DESCRIPTION?",
9150INPUT O$ (X)
9160PRINT O$(X)
9170NEXT X
9199STOP(use CONT to continue
9200CLS
9210PRINT "NO. OF WORDS?"
9220INPUT V
9230DIM V$(V,6)
9240FOR X=1 TO V
9250SCROLL
9260INPUT V$(X)
9270PRINT V$(X)
9280NEXT X
9299STOP(use CONT to continue
9300CLS
9310PRINT "NO. OF ROOMS?"
9320INPUT R
9330DIM M$(R,32)
9340FOR X=1 TO R
9350SCROLL
9360INPUT M$(X)
9370PRINT M$(X)
9380NEXT X
9399STOP(use CONT to continue
9400CLS
9410PRINT "NO. OF CONDITIONALS?"
9420INPUT C
9425LET C=C+1
9430DIM C$(C,21)
9440FOR X=1 TO C-1
9450SCROLL
9460INPUT C$(X)
9470PRINT C$(X)
9480NEXT X
9490LET C$ (C)=".N."
9499STOP(use CONT to continue
9500CLS
9510PRINT "NO. OF ACTIONS?"
9520INPUT A
9530DIM A$ (A,31)
9540FOR X=1 TO A
9550SCROLL
9560INPUT A$ (X)
9570PRINT A$ (X)
9580NEXT X
9599STOP(use CONT to continue
9600CLS
9610PRINT "ENTER THE ADVENTURE NAME"
9620INPUT N$
9630PRINT ,,"START THE TAPE..."
9640PAUSE 150
9645POKE 16437,255
9650CLS
9660SAVE N$
9670GOTO 10
9999STOP

Before you get a real-live game, here follows a "test" Adventure for you to enter. It should give you a good idea as to how the program works, how you can create your own Adventures, and whether all your typing has been accurate.

Test Adventure

This mini-test adventure uses 6 rooms. Room 1 is above ground, and a lamp can be found there. The objective is to get the bar of gold out of the caves back above ground. The gold is hidden in cave 6 behind a rusty door (cave 4), which will not open. Cave 5 contains a vase and cave 6 contains a pool of oil. Obviously, you must fill the vase with oil and then oil the door! Once this has been done, you can open the door and reach the gold.

A map of the cave looks like this:-

Markers 2 and 3 are used, as usual, to represent "dark" rooms and lamp off/on respectively. Notice that when the "lit" lamp (object number 2) is dropped, the lamp is marked as off, which prevents you from lighting the lamp then leaving it somewhere while you wander off.

Marker S is used to indicate when the door has been oiled, and marker 6 is set when the door is open.

Enter the text messages and room descriptions, then RUN 9000 to start the Loader routine. The objects, vocabulary, room connections, conditionals and keyword actions are all entered at this stage.

Once you have completed this, SAVE THE PROGRAM!!!

Start the program by GOTO 10 (otherwise you'll destroy the variables). Check that it works according to the rules above and you can be fairly sure that you have entered your Master program without any serious defects.

You should notice the way this is created in order to assist you with producing your own games.

One item of importance is shown between rooms 1 & 2 and also 4 & 6. In the first case, there is no tunnel indicated in the room connection table between rooms 1 and 2. Instead, an entry has been included in the Action table under the appropriate keyword (06). This is because I want to make sure that the "darkness" marker is set on whenever the keyword "DOWN" is given from room number 1.

Similarly, there would be no point in entering a connection between rooms 4 and 6, since the door is supposed to block the path. Consequently, an entry is found in the Action table (03 00 A04 F06....) which checks marker 6 whenever "SOUTH" is entered at room 4.

The rule is:- If you want to place some conditions on the player when he travels from one particular room to another, don't put an entry in the room connection table - use the Action table instead.

Text Messages:-

7010PRINT "THE DOOR IS SHUT FAST"
7015RETURN
7020PRINT "THE DOOR IS OPEN"
7025RETURN
7030PRINT "IT IS ALREADY ALIGHT"
7035RETURN
7040PRINT "WITH A GRUNT YOU MANAGE TO",
"OPEN THE DOOR."
7045RETURN
7050PRINT "IT IS TOO STIFF FOR YOU",
"TO OPEN."
7055RETURN
7060PRINT "YOU DID IT. WELL DONE."
7065RETURN
7070PRINT "YOU CANNOT GET PAST THE DOOR."
7075RETURN

Room Descriptions:-

8010PRINT "YOU ARE STANDING BY A POTHOLE."
8015RETURN
8020PRINT "THIS IS A VAST CAVERN WITH",
"PASSAGES LEADING EAST,SOUTH,"
"AND WEST. A DIM PASSAGE SLOPES"
"UPWARDS BEHIND YOU."
8025RETURN
8030PRINT "THIS CAVE CONTAINS ONLY A POOL",
"OF OIL."
8035RETURN
8040PRINT "HERE IS A GIANT RUSTY DOOR."
8045RETURN
8050PRINT "YOU ARE IN THE WESTERN ALCOVE."
8055RETURN
8060PRINT "YOU ARE IN THE TREASURE CAVE."
8065RETURN

Objects:-

Number of objects:- 5

No.Room numberDescription
11A LAMP
20A LIGHTED LAMP
35A MING VASE
40A VASE OF OIL
56A BAR OF GOLD

Vocabulary:-

Number of words:- 25

Each entry below requires a maximum of six characters, the first two being the word number.

01N14DROP
01NORT15VASE
02E16GOLD
02EAST17DOOR
03S18OPEN
03SOUT19LAMP
04W20LIGH
04WEST21FILL
05U22OIL
05UP23INVE
06D24QUIT
06DOWN25LOOK
13TAKE

Number of rooms:- 6

Room connection table (the numbers in brackets are for reference only - do not enter them) :-

(1)00
(2)02030304040500
(3)040200
(4)010200
(5)020200
(6)010400

Number of conditionals:- 3

Conditionals (do not enter the spaces!) :-

A04 E06. D02 N.(room 4 and marker 6 is set -
(i.e. the door is open.
A04 F06. D01 N.(room 4 and M6 is not set ie
(the door is shut
A01 D05. D06 Q.(room 1 carrying object 5
(got out with the gold - win!

Number of keyword actions:- 21

Keyword actions:-

13 19 B01. B01 L.(take lamp - object 01
14 19 B01. C01 L.(drop lamp
13 19 B02. B02 E03 L.(take (lit) lamp - object 02
( - also sets lamp marker 3
14 19 B02. C02 F03 L.(drop lit lamp - unsets lamp
( marker 3
20 00 D01. H01 E03 L.(light lamp - swaps objects 1
(and 2, also sets lamp mark
20 00 B02. D03 M.(light lamp and object 2 is
( already here - display 03
06 00 A01. E02 K02 O.(DOWN when at room 1, so set
( "dark" marker 2, continue at
( room number 2
05 00 A02. F02 K01 O.(UP when at room 2, so unset
( "dark" marker and continue
( at room number 1
13 15 B03. B03 L.(take vase
14 15 B03. C03 L.(drop vase
13 16 B05. B05 L.(take gold
14 16 B05. C05 L.(drop gold
21 00 B03 A03. H03 L.(fill vase - must have
( object 3 and be in room 3
( swaps objects 3 & 4
22 00 A04 B04. H03 E05 L.(oil door - must have object 4
( a full vase and be at room 4
( "empties" bottle 6, set mark5
18 00 A04 E05. D04 E06 M.(open door - must be oiled i.e.
( marker 5 must be set, and
( must be at room 4. Sets M6.
18 00 A04 F05. D05 M.(open door when not oiled.
( - displays message 5.
03 00 A04 F06. D07 M.(SOUTH when marker 6 not set -
( i.e. door not open.
03 00 A04 E06. K06 O.(SOUTH at door when open [mark
( 6 is set]. Continues at room
( number 6.
23 00 .A.(give inventory
24 00 .P.(quit
25 00 .O.(look to see where we are

Testing Your Adventures

What do you do if your new Adventure does not work? Here are a few guidelines to help you track down any errors.

From my own experience, the most common problem occurs in the Conditional and Action tables - either specifying incorrect actions, or not entering appropriate items.

You can run the program in either slow or fast mode, but I must point out that it can take quite a few seconds to scan the Action table to match your keywords and so I would recommend fast mode.

If nothing happens for one or two minutes, then suspect a fault in the Conditional table. Press the BREAK key, and inspect any of the following variables by using direct PRINT commands:-

CPContains the current Conditional/Action table entry number being processed.
Tindicates whether the Conditional or Action table is being scanned. Zero means Action table, 1 means Conditional table.
E$contains a copy of the Conditional/Action table entry.
P$(1)contains the keyword number of the first keyword found in any input command.
P$(2)contains the keyword number of the second keyword found, or "00" if no second keyword was entered.
ROOMthe current room number.
S(n)switch n - 0=off, 1=on.
C(n)countdown n - 0=countdown not in use.
O(n)room number containing object n. It the object is being carried, this will have the value -1. If the object does not exist, the value will be zero.

The following arrays/variables are set up by the loader program:-

M$()room connection table
Rnumber of rooms
Onumber of objects
Q()object location table, copied into O()
O$()object descriptions
Vnumber of words
V$()vocabulary table
Cnumber of conditionals
C$()conditional table
Anumber of actions
A$()action table

A common mistake is to terminate a Conditional table entry with action code M instead of N. Action code M causes the conditional table to be scanned again, and since the same conditionals (probably) still exist, the same program will simply loop indefinitely. Check that all conditionals finish with action code N unless you have good reason to use another (look at the tables in the "Test" Adventure).

For further information on Adventure, read the article by Ken Reed, Practical Computing Vol. 3, Issue 8 (August 1980).

City Of Alzan

Suitable for : 16K RAM

Now for a complete Adventure, based on the "Do-it-yourself" Adventure Master program.

This takes place in a fictitious city named Alzan, which is built on top of the sea cliffs and is inhabited by thieves and cut-throats. Your quest is to find a way out of the city before they grab you, or before the plague takes hold of you. Unfortunately, the city is surrounded by extremely high walls and so you must find a way to scale them.

When you enter the game, it is possible for you to work out how the game evolves and how to win, hut this would defeat the pleasure of playing, so :ry to "switch off" while you are typing.

When this program is fully running, you will have roughly 4150 bytes of memory free. This should give you a guide to the size of Adventures you will be able to write. I would advise the use of the "Memory Left" routine (see "Using Machine Code") while developing your own games.

Tape name : "ALZAN"

Enter the text messages:-

7010PRINT "OH DEAR. YOU MUST HAVE CAUGHT",
"THE PLAGUE IN THE TOMB. IT",
"SEEMS THAT YOU HAVE DIED."
7015RETURN
7020PRINT TAB 12;"---WHOOSH---"
7022PRINT "EL GRABBO, THE LOCAL THIEF,",
"SNATCHES YOUR MONEY AND DIS-",
"APPEARS INTO THE SEA MIST."
7025RETURN
7030PRINT """STOP THIEF"" SHOUTS THE USHER,",
"BUT YOU MANAGE TO ESCAPE."
7035RETURN
7040PRINT "THE COVER IS ALREADY OPEN."
7045RETURN
7050PRINT "IT COSTS MORE THAN YOU CAN AFFORD."
7055RETURN
7060PRINT "THATLL DO NICELY, SIR"
7065RETURN
7070PRINT "THE MANHOLE COVER IS OPEN."
7075RETURN
7080PRINT "THE MANHOLE COVER IS SHUT."
7085RETURN
7090PRINT "THE SHOPKEEPER IS BIGGER THAN",
"YOU..."
7095RETURN
7100PRINT "YOU WILL NEED A LADDER TO GET",
"OVER THESE WALLS."
7105RETURN
7110PRINT "IT IS ALREADY ON."
7115RETURN
7120PRINT "WHAT A STROKE OF GENIUS"
7125RETURN
7130PRINT "YOU CATCH THE GUARDS UNAWARE AND";
"MANAGE TO SNATCH A WAD OF NOTES.";
"NO-ONE HAS NOTICED (FUNNY LOT,",
"THESE ALZANS)"
7135RETURN
7140PRINT "YOU HAVE TAKEN ALL THERE IS."
7145RETURN
7150PRINT "I DONT SEE A TORCH?"
7155RETURN
7160PRINT "THE CINEMA IS BOOKED FOR A",
"PRIVATE FUNCTION."
7165RETURN
8010PRINT TAB 8;"WELCOME TO ALZAN",,,
"YOU MUST SCALE THE WALLS IF",
"YOU WISH TO ESCAPE FROM THIS",
"CITY OF THIEVES AND CUT-THROATS."
8015RETURN
8020PRINT "YOU ARE IN THE MAIN STREET OUT-"
"SIDE A HARDWARE SHOP. THE STREET";
"STRETCHES EAST/WEST AND A SMALL",
"ALLEY LEADS NORTH BESIDE THE",
"SHOP."
8025RETURN
8030PRINT "YOU ARE INSIDE THE SHOP. THE",
"SHOPKEEPER LOOKS SHIFTY, BUT HE",
"HAS MANY FINE GOODS ON DISPLAY."
8035RETURN
8040PRINT "YOU ARE IN AN ALLEY BEHIND THE",
"TALL BUILDINGS. THERE ARE MANY",
"FULL DUSTBINS UNDER THE FIRE",
"ESCAPE."
8045RETURN
8050PRINT "YOU ARE ON THE FIRE ESCAPE,",
"WHICH LEADS PAST A DOOR IN THE",
"BUILDINGS."
8055RETURN
8060PRINT "YOU HAVE COME DOWN A SECRET",
"STAIRCASE INTO THE SHOP."
8065RETURN
8070PRINT "YOU ARE ON SOME CATWALKS BETWEEN";
"THE BUILDINGS."
8075RETURN
8080PRINT "THIS IS PART OF THE CITY WALLS.",
"THERE IS AN UNUSED DOOR IN THE",
"WALL HERE."
8085RETURN
8090PRINT "YOU ARE AT A CROSSROADS."
8095RETURN
8100PRINT "HERE IS PART OF THE CITY WALLS.",
"THE SEA MIST IS OUITE THICK,",
"MAKING IT HARD TO SEE FAR."
8105RETURN
8110PRINT "YOO PLUNGE FROM THE WALL - RIGHT";
"DOWN ONTO THE ROCKS BY THE SEA",
"500FT BELOW. WELL, NEVER MIND,",
"BETTER LUCK NEXT TIME."
8115RETURN
8120PRINT "YOU ARE OUTSIDE THE TOWN BANK."
8125RETURN
8130PRINT "INSIDE THE BANK THERE ARE MANY",
"GUARDS WHO SEEM RATHER BORED."
8135RETURN
8140PRINT "YOU HAVE ARRIVED AT A DEAD END,",
"BUT THERE IS A MANHOLE IN THE",
"ROAD..."
8145RETURN
8150PRINT "YOU ARE IN A SMALL ALCOVE UNDER-";
"NEATH THE MANHOLE, A PASSAGE",
"LEADS SOUTH."
8155RETURN
8160PRINT "THE PASSAGE LEADS TO AN ANCIENT",
"TOMB, WHERE MANY SARCOPHAGI LIE",
"SCATTERED ABOUT. "
8165RETURN
8170PRINT "THE USHER WILL NOT LET YOU IN AS";
"THE PROGRAMME HAS STARTED. HE",
"BLOCKS YOUR PATH WITH HIS TORCH."
8175RETURN
8180PRINT "YOU ARE OUTSIDE THE CINEMA.",
"SOUNDS OF GUNFIRE COME FROM",
"WITHIN."
8185RETURN
8190PRINT TAB 8; "***CONGRATULATIONS***" ,
"YOU MADE IT OUTSIDE THE CITY",
"WALLS. THIS IS INDEED A RARE",
"OCCASION. WELL DONE."
8195RETURN

Now type RUN 9000 to start the initialisation routine. The arrays should be set as follows:-

Number of objects : 11

Object roomDescription
0A LIGHTED TORCH
0A TORCH
3A LADDER
3A HAMMER
0A HAMMER
0A WAD OF NOTES
0MANHOLE COVER
15A BAG OF NAILS
16A BARCLAYCARD
0A ROUGH LADDER
4SOME WOOD

Number of words : 43

01N19HAMM
01NORT20WAD
02E20NOTE
02EAST22BAG
03S22NAIL
03SOUT23BARC
04W05SCAL
04WEST05CLIM
05U29OPEN
05UP29LIFT
06D30MAKE
06DOWN30BUIL
13TAKE31SWIT
14PUT31LIGH
14DROP32BUY
15ENTE33WOOD
15IN34ROB
16OUT34STEA
16EXIT35INVE
16LEAV36QUIT
17TORC37LOOK
18LADD

Number of rooms : 19

Room noConnections
100
201 04 02 09 04 18 00
300
402 02 05 05 00
506 04 04 07 00
600
701 08 03 05 00
803 07 00
901 12 02 10 03 14 04 02 00
1004 09 00
1100
1202 09 04 18 00
1300
1401 09 00
1503 16 00
1601 15 00
1700
1801 12 02 02 00
1900

Number of conditionals : 9

Conditional table (the spaces are only to make it easier to read - do not enter them) :-

A01. K02 O.
A16 H30. G0121.
G01. D01 Q.
B06 H10. D02 J06.
A14 E07. D07 N.
A14 F07. D08 N.
A11. Q.
A19. Q.
A06. K03 O.

Number of actions : 47

Action table (the spaces are to make it easier to read - do not enter them) :-

13 17 B01. B01 E03 L.
13 17 A17 C01 C02. I02 B02 D03 K18 E10 O.
32 18 B03. D05 N.
13 19 B05. B05 L.
13 20 B06. B06 L.
29 00 A14 E07. D04 N.
29 00 A14. E07 M.
13 22 B08. B08 L.
13 23 B09. B09 L.
14 17 B01. C01 F03 L.
14 17 B02. C02 L.
14 19 B05. C05 L.
14 20 B06. C06 L.
14 22 B08. C08 L.
14 23 B09. C09 L.
05 00 A10 C10. D10 M.
05 00 A08 C10. D10 M.
05 00 A10. K11 O.
05 00 A08. K19 O.
05 00 A15. F02 K14 O.
06 00 A14. E02 K15 O.
31 00 D02. H01 E03 L.
31 00 B01. D11 N.
32 19 B04 B06. H04 J06 B05 L.
32 19 B04 B09. H04 D06 BO5 M.
30 00 B05 B11 B08. D12 I10 J08 J11 M.
13 33 B11. B11 L.
14 33 B11. C11 L.
15 00 A02. K03 O.
15 00 A12. K13 O.
15 00 A18 F10. K17 O.
16 00 A03. K02 O.
16 00 A13. K22 O.
16 00 A17. K18 O.
15 00 A05. K06 O.
34 00 A03. D09 M.
34 00 A13 E08. D14 M.
34 00 A13. E08 D13 I06 B06 M.
15 00 A18 E10. D16 M.
13 18 B10. B10 L.
14 18 B10. C10 L.
13 18 B03. D09 M.
13 17 B02. B02 L.
35 00 .A.
36 00 .P.
37 00 .O.
50 00 .N.

Now use the "save" routine giving the name ALZAN to this adventure. When you next load the program, it will automatically start running, but if you wish to begin again for any reason, use GOTO 1, as the RUN command will clear all variables thus destroying the game.

Have fun!