One important aspect of good dungeon design is sometimes overlooked by the author. This is the job of making the player's task of mapping the dungeon interesting and straightforward, rather than an irritating chore. The ease or difficulty of mapping will affect the player's enjoyment, and the rating that the dungeon receives will gain or suffer as a result.
I am not suggesting that the author shouldn't put mazes or confusing passages in the dungeon; that is an important part of adventuring. What I am talking about is the room description that gives lots of detail and color, but doesn't give the room's correct name nor list the available exits.
Let me give you a fictional example of just what I am talking about. Imagine that the player has just entered a room in a dungeon, and gets the following description:
YOU HAVE JUST ENTERED A LARGE, CATHEDRAL-LIKE ROOM. THE CEILING VAULTS HIGH OVERHEAD. A COUCH IS SET AT ONE END ON A HIGH DAIS, ALONGSIDE AN ALTAR-LIKE CABINET
OK, so the player draws this room on their map, and labels it 'Cathedral Room'. But then, when they reenter the room later on, they find the room's name is VIP HALL or QUEEN'S CHAMBER or something similar that has nothing whatever to do with the room's description! And then they have to make a mess of their map, scratching out, or erasing, or just trying to remember which room is which.
There is a second problem with the above description: it doesn't give a clue what the exits from the room are. This is a valid design stratagem when the author is forcing a minor puzzle on the player, or is hiding something off in a corner of the room, and wants the player to have to search for it. But if it is a simple room, with ordinary doorways, then it is good form to list them somehow. In adventures that have a quest with a time limit imposed on the player, this kind of missing information can become quite irritating.
To correct the above problems, the room description can be rewritten to something like the following:
YOU HAVE JUST ENTERED THE QUEEN'S CHAMBER. A LARGE CATHEDRAL-LIKE ROOM, THE CEILING VAULTS HIGH OVERHEAD. A COUCH IS SET AT ONE END ON A HIGH DAIS, ALONGSIDE AN ALTAR-LIKE CABINET. THERE ARE DOORS NORTH AND WEST.
But this rewritten description has problems of its own. There is an absolute limit of approximately 6 lines for a given description. The above 'corrected' description uses up 50-odd characters in making the necessary additions to ease mapping chores. As Eamon authors know, 6 lines is often not nearly enough to squeeze in all of a room description.
One solution is to put this information somewhere besides the room description. The Eamon version 6.2 MAIN PGM addresses this by adding some programming that prints the normal exits just before the 'YOUR COMMAND?' prompt. The 6.2 code for this is as follows:
205 C = 0: PRINT "EXITS ARE ";: FOR X = 1 TO ND: IF RD%(X) > 0 AND RD%(X) < = NR THEN PRINT C $(X);", ";:C = 1 207 NEXT : IF NOT C THEN PRINT "NON-EXISTENT ";
Now, our example description will look like this:
YOU HAVE JUST ENTERED A LARGE, CATHEDRAL-LIKE ROOM. THE CEILING VAULTS HIGH OVERHEAD. A COUCH IS SET AT ONE END ON A HIGH DAIS, ALONGSIDE AN ALTAR-LIKE CABINET.
EXITS ARE NORTH, WEST
Another solution is to put the second half of room descriptions in the Effects, and them print both the Room Description and the corresponding Effect, thus getting 12 lines of text instead of the normal 6. A good example of this method can be found in #145 'Buccaneer!'. In this adventure, Pat Hurst has put the first 6 lines of each room description in the room location in the EAMON.DESC file, and also put 6 MORE lines in an Effect of the SAME number. The applicable code from his program is as follows:
130 VZ = ( INT (V%(RO) / 2) = (V% (RO) /2)): IF NOT VZ THEN PRINT DK$;"READ EAMON.ROOM NAMES, R;"RO: INPUT A$: PRINT DK$: PRINT "YOU ARE ": PRINT " ";A$: PRINT 140 IF VZ THEN PRINT DK$;"READ EAMON.DESC,R";RO: INPUT A$: PRINT DK$: PRINT A$: PRINT :V%(RO) = V%(RO) + 1:EF = RO: GOSUB 60
60 PRINT DK$;"READ EAMON.DESC,R" ;EF + 200: INPUT A$: PRINT D K$: PRINT A$: PRINT 63 RETURN
Examining the above, code, you can see that line 140 prints the room description, then calls the small subroutine at 60 to print the corresponding effect. This is a very simple, elegant solution to the problem of printing long descriptions.
Yet another way to free up the entire 6 lines for describing the room is to print the Room Name every turn, even when the Room Description is to be printed. This can be done by deleting the code in line 130 that tests for the description flag, as follows:
130 PRINT DK$;"READ EAMON.ROOM NA MES,R";RO: INPUT A$: PRINT D K$: PRINT "YOU ARE ";A$ 140 IF INT (V%(RO) / 2) = (V%(RO) / 2) THEN PRINT DK$;"READ EAMON.DESC,R"RO: INPUT A$: PRINT DK$: PRINT A$: PRINT: V%(RO) = V%(RO) + 1
This code would give us the following example:
YOU ARE IN THE QUEEN'S CHAMBER
YOU HAVE JUST ENTERED A LARGE, CATHEDRAL-LIKE ROOM. THE CEILING VAULTS HIGH OVERHEAD. A COUCH IS SET AT ONE END ON A HIGH DAIS, ALONGSIDE AN ALTAR-LIKE CABINET.
From here, it is a simple matter to tack the visible room exits onto the end of the room name, so that it reads like this:
YOU ARE IN THE QUEEN'S CHAMBER (N/W)
YOU ARE IN THE QUEEN'S CHAMBER (NW)
I personally favor the last example, in which the room name is always printed on every turn, and the visible exits are printed without slashes on the end. This has the added bonus of allowing the author to hint that there is something special about the room by not printing the exits. Thus the alert player will think to look for hidden exits or unmarked corners.
But all of the above methods are good ones. The important thing is to take some of the drudgery out of dungeon exploration. Then the player has more fun, and your adventure gets better ratings!
Real ARRAY variables use 5 bytes each, while Integer ARRAY variables use only 2. Thus DIM AD%(100,9) consumes 2000 bytes of memory, but DIM AD(100,9) uses 5000 bytes! Always use Integer for large arrays.
Real SIMPLE variables use LESS memory than Integer SIMPLE variables, and execute faster, too. ALWAYS use Real Simple variables.
Applesoft only 'sees' the first two characters of a variable name. It can't tell a difference between DIE and DIS, which can cause you some real trouble. Short names also save memory. Use short variable names.
Consider the following routine:
7420 FOR A = 1 TO NA: IF AD%(A,4) < > ROOM OR AD%(A,2) < 2 OR AD%(A,2) > 3
7430 PRINT MN$(OF);" PICKS UP";AN$(A):(other statements):RETURN
This routine has 3 serious problems: 1)Applesoft finds GOTO lines by going to the beginning of the program and checking EVERY line number until it finds it. You have all seen times when a monster broke its weapon during a fight, there were no weapons lying about the room, and things slowed down a LOT each time that monster's turn to fight came up. The above code is responsible. 2)Line 7420 does 3 comparisons for EACH artifact tested, even if the artifact isn't in the room. 3)Line 7430 does a RETURN, leaving an OPEN LOOP. This leaves all of the loop's 'housekeeping' on the program stack, which is only 256 bytes long. If we use up the stack, eventually it 'overflows', and the program crashes with an OUT OF MEMORY error. Note that the program is not really out of memory. This is the cause of Eamon's OUT OF MEMORY problem.
Now look at this routine:
7420 FOR A = 1 TO NA: IF AD%(A,4) < > RO THEN NEXT: RETURN
7425 IF AD%(A,2) < 2 OR AD%(A,2) > 3 THEN NEXT: RETURN
7430 PRINT MN$(OF);" PICKS UP";AN$(A):(other statements):A = 999
7440 NEXT: RETURN
1)Line 7420 avoids doing the time-consuming GOTOs by doing its own NEXT. If it has examined all of the artifacts, the NEXT 'falls through', and the RETURN is executed. This is a huge timesaver. 2)Line 7420 only checks to see if the artifact is in the room. This way we avoid doing unnecessary comparisons. 3)Line 7430 sets 'A' to a number that is greater than NA. Thus when line 7440 is executed, the NEXT statement 'closes the loop', clearing the program stack.
The above listing was to illustrate some points. Here is the optimum listing:
7420 FOR A = 1 TO NA: IF AD%(A,4) = RO THEN IF AD%(A,2) = 2 OR AD%(A,2) = 3
THEN PRINT MN$(OF)" PICKS UP"AN$(A):(other statements):A = 999
7430 NEXT: RETURN
*** MINIMIZING COMPARISONS
Examine the following example: 510 IF RO = 17 AND MD%(5,5) = RO AND PW < 5 AND RND(1) < .5 THEN GOSUB 30000
In this line, all 4 comparisons are ALWAYS done, even if you are not in room 17. Now look at this: 510 IF RO = 17 THEN IF MD%(5,5) = RO AND PW < 5 AND RND(1) < .5 THEN GOSUB 30000
See how this code reduces the comparisons to just one.
510 IF RO = 17 THEN IF MD%(5,5) = RO AND PW < 5 AND RND(1) < .5 THEN GOSUB 30000
See how this line reduces the comparisons to just one. *** EXITING SUBROUTINES
NEVER use GOTO to exit from a subroutine! This is a VERY fast road to a stack overflow OUT OF MEMORY crash. Always use RETURN or POP:GOTO to exit from subroutines, so that the stack is cleared.
This tutorial is necessarily brief do to space limitations. If you have further questions, drop me a line.
Every time a string is modified or read into memory from disk, it is allocated to fresh memory space. Eventually all of the memory space is used up, and Applesoft executes what is called a forced FRE(0) garbage collection. When this happens, everything grinds to a halt until all the old, discarded strings have been identified and flushed from memory. This can take more than a minute on a large Eamon, and looks for all the world like a hung computer. Very large and complicated MAIN PGMs can lead to low levels of free memory for string storage that can result in excessive FRE(0) garbage collections, causing annoying delays in play.
There are several things that you can do to free up more memory (examples are for version 7.0):
1) USE VERSION 7.0: It uses a special string routine that drastically reduces the garbage accumulation, allowing uninterrupted program operation with about 1/8 the free memory required by version 6.2. The routine resides at lines 45-50.
2) DELETE UNUSED COMMANDS: A command can be completely deleted from the pgm. For example, if you have no drinkable artifacts, you don't need the DRINK command. To delete DRINK: change the number in line 31910 from '32' to '31'; delete 'DRINK,' from line 31920; delete '22000,' from line 290, and delete lines 22000-22190. Or you can:
3) 'DUMMY' UNUSED COMMANDS: A lot of code can be deleted by converting a command to a dummy that doesn't do anything. For example, to 'dummy' DRINK, delete lines 22020-22190, and change line 22010 to:
22010 GOSUB 4900: GOTO 94
4) MAKE A COMMAND ARTIFACT-SPECIFIC: For example, if you only have a single drinkable artifact in your adventure (eg: artifact #47), and it doesn't do anything to the player's health (eg: a river), you can delete lines 22020-22190 and replace them with:
22020 IF A < > 47 THEN 94 22030 PRINT "OKAY.": GOTO 98
Feel free to contact us for more information.
The Parameter option was introduced with the version 6 DDD. The programming for this option was left unchanged when the DDD was upgraded to version 7, so the following article applies to both versions.
The purpose of the Parameters option is to allow the author to add to and change the way the data is stored. This feature allows the author to 1) generate additional artifact types with unique data fields; 2) modify existing data fields; 3) change the default values of the data fields.
First, a few definitions:
ARTIFACT TYPE: type of artifact, such as WEAPON or READABLE. FIELD: one of the 8 pieces of data for an artifact. For example, Artifact Field #1 is VALUE. DEFAULT: the value that a Field will have unless it is changed by the author. FORMAT: the Field labels for a given Type.
Standard Artifact Data: 1: Value 2: Type 3: Weight 4: Room
Format #1 (Weapons) Format #6 (Door/Gate) 5: Weapon Type 5: Room Beyond 6: Odds 6: Key # 7: Dice 7: Strength 8: Sides 8: Hidden?
There are 9 such standard formats. For a complete list, see the DDD manual.
There are 3 rules which MUST be followed, or Terrible Things May Happen: Rule #1: Before entering any data, make all parameter changes. Rule #2: Always save the parameters if changes were made. Rule #3: Whenever resuming data entry or editing, be sure to load the parameters file first.
*** HOW TO ADD A NEW ARTIFACT TYPE
The best way to describe this is to step through an example. Let's add an artifact type for ridable things, such as cars, horses, airplanes, etc. The fields of this new format will be: Field 5: TYPE (0=car, 1=horse, 2=boat, 3=plane) default: 0 Field 6: SPEED (in MPH) default: 45 Field 7: # SEATED default: 4 Field 8: ARMOR default: 10
The steps are as follows:
RUN DUNGEON EDIT 7.0 Select: 6 SPECIAL FUNCTIONS Select: 8 CHANGE DATA ASSIGNMENTS Select: 6 ADD A FORMAT Enter the Fields and defaults described above Note that this is Format 10 that you are entering Select: 5 ARTIFACT TYPES Select: 12 NEW TYPE Enter the new type: RIDABLE Select: 6 SPECIAL FUNCTIONS Select: 8 CHANGE DATA ASSIGNEMENTS Select: 3 CHANGE FORMAT POINTER Enter '12' to select the RIDABLE Type Enter '10' to set the pointer to Format 10 Select: 7 RETURN TO MAIN MENU Select: 6 SPECIAL FUNCTIONS Select: 9 LOAD/SAVE CUSTOMIZED PARAMETERS Select: 2 SAVE PARAMETERS Enter a name for the Parameters file. It is recommended that you use PARAMETERS
That's it. What could be easier?
The next time that you start up DUNGEON EDIT 7.0 to continue your data entry, perform these steps:
Select: 6 SPECIAL FUNCTIONS Select: 9 LOAD/SAVE CUSTOMIZED PARAMETERS Select: 1 LOAD PARAMETERS Enter the name of the parameters file. If you can't remember it, type '?' to get a catalog.
TWO WARNINGS: 1) Every time that you add a new format, it will say that it is to be Format 10, even when it is not. You must keep track of how many formats you have so that you will know its real number. (Yes, this is a bug.)
2) When you reload the parameters file, the new Format Pointers are NOT set up correctly. In the above example, after reloading PARAMETERS, the Format Pointer for Artifact Type 12 will be 0, which points to the GOLD format. You must enter 6 (Special Functions), then 3 (Change Format Pointer), then change the pointer for Type 12 EVERY TIME that you run DUNGEON EDIT 7.0.
*** ADDING EXTRA DATA FIELDS
This option exists for both Artifacts and Monsters.
The Artifact option doesn't work right. DON'T USE IT.
The Monster option works OK, but you will be adding fields that are not supported by the MAIN PGM. Since you will have to make many changes to the MAIN PGM anyway, it is recommended that you add extra Artifact and Monster fields directly to the MAIN PGM, using DATA statements and the Applesoft READ command. It will probably be easier to do and remember, and won't make your data files non-standard.
*** SOME OTHER DATA ASSIGNMENT OPTIONS
1. MONSTER DATA: allows you to change the Monster Field labels.
2. ARTIFACT DATA: allows you to change the labels for Fields 1 - 4.
4. CHANGE A FORMAT: allows you to change the Format's labels and defaults for Fields 5 - 8.
*** SOME OTHER SPECIAL FUNCTIONS
7. CHANGE DEFAULTS: 1. ROOMS: aren't saved in the parameters file 2. MONSTERS: works OK 3. ARTIFACTS: changes Fields 5 - 8 only
*** SOME COMMENTS AND SUGGESTIONS
As you can see, changing the formats can be pretty complicated, and you must still keep track of a lot of things that are not stored in the parameters file. If your new artifact type will only have 2 or 3 artifacts, it may prove to be easier to do simple artifact number checking instead of messing about with adding new formats. For example, let's say that your RIDABLE artifacts are artifact numbers 12, 13, and 27. If you add a new format, every time your MAIN PGM wants to test if an artifact is ridable, you would use this test: 'IF A%(A,2) = 12 THEN...'. It would be much simpler to NOT generate a Ridable artifact type, but just make these artifacts Type 1, and use this test: 'IF A = 12 OR A = 13 OR A = 27 THEN...'. However, if you plan to have a lot of Ridable artifacts, then it might be better to go ahead and generate a special Type and Format for it.
The DUNGEON LIST programs do NOT support parameters.
Another option is to use an existing format in a new way. For example, a couple of Eamons are set in modern times and have a special 'Machine-gun' artifact type. It would have been better if the author had used artifact Type 3 (Magic Weapons) for machine-guns instead. Or you could make all treasures Type 1, and use Type 0 for a Special Artifact Type.
Finally, since you have to keep track of it all anyway, it is easiest of all to just use the USER Fields for your special stuff. For example, if you want to add a Food Artifact, you could use Drinkable Artifacts for both food and drink. Then use the USER 8 Field to distinguish between them, setting it to 0 for drink and to 1 for food, then testing A%(A,8) in the MAIN PGM.
One very important thing that you should also do, no matter which method you use, is to add some 'Author's Notes' to the intro program or as a stand-alone program, to explain what special Fields and Types you have used and how you have used any USER Fields.
As most of you know, John Nelson is up to his ears in IBM-Eamon these days. He is busily adding more features to the Eamon system. He is using QuickBasic, which is compiled, and is not planning to supply the source code with the basic Eamon Designer Disk. Therefore, since the average IBM-Eamon author won't be able to make changes in the basic IBM-Eamon system, John is adding a number of additional features and options which will seldom ever be used, but will be there for the author if he needs them.
John has added several new Artifact categories. We have no plans to implement any of these in Apple-Eamon at this time, but in the interests of standardization, we are describing them here. If you use these categories, it will make the job of porting your Eamon over to the IBM easier, since John's IBM-Eamon system will already recognize them. The categories are:
11: WEARABLE Especially armor. The version 7 Apple-Eamon supports this category to a limited extent; see the manual for details.
12: FOOD This category is easily implemented on the Apple as a subset of the already existing Category 6, Drinkable Artifacts. It is especially easy to do on version 7 by using the USER 8 field to distinguish between food and drink.
13: DRINK John has broken Drinkable Artifacts into two separate categories, reserving Category 6 for healing potions and poisons, and this category for all other drinkables. Note that Apple-Eamon does not make this distinction.
14: DISGUISED MONSTER A familiar example of this category is the good ol' Mimic of the Beginner's Cave. This kind of artifact will have a common name, like 'Treasure Chest'. But when it is acted upon, an Effect is printed that describes the transformation, the artifact disappears, and is replaced by the monster itself. This category has two important fields: 5. Effect number for transformation description 6. Number of Monster that appears
15: TRAP This is somewhat similar to the Disguised Monster described above. It appears to be an ordinary artifact until the player tries to do something with it. Then there is a random chance that the trap will be sprung. The fields for this are: 5. Percent chance that the trap will go off 6. Number of Effect describing the springing of the trap 7. number of dice for damage calculation 8. number of sides on dice.
How many times have you been blind-sided by a no-warning death trap while playing Eamon? How much did you enjoy having to start over again? Eamon authors seem to undergo some kind of strange compulsion to include in their own Eamons the very traps that they hate in others' Eamons. There are three reasons why Eamon authors install death traps:
1) They are practical jokers and think it's funny. RESPONSE: It's NOT funny to have to start over for no good reason and many people will quit if they have to start over too often.
2) They are giving proper responses to stupid player moves. RESPONSE: No one will intentionally kill himself off-if he made a stupid move then the warning clues were very poorly written by the author.
3) They consider it to be an essential part of the plot. RESPONSE: There are alternative methods that can be used that will fit the plot equally well.
ALTERNATIVES TO DEATH
Whenever I complain to an author about a given death trap, a response that I often get is that 'if it were real life, the player WOULD get killed there. I've got to be realistic.' Well, if it were real life, then the player would be really dead, and would never, ever again get to play the adventure. To continue this 'realism', the Eamon disk should erase itself when the player is killed. To carry this 'real life' thing to its ultimate absurdity, the player will have to quit Eamon altogether! The real issue here isn't realism, but sloppy adventure writing.
What this means is that an Eamon that is well-written for realism will be very survivable. Note that I said 'survivable', NOT 'easy'! A rule which all Eamon authors should closely follow is that it should be possible to escape, overcome, or endure anything that the player encounters in the dungeon. If a trap is unavoidable then it should be survivable at least 98% of the time. 'Pass/no pass' puzzles or riddles should send the player away to search for clues, not kill him or force him to battle supernatural opponents.
There are a number of ways that damage can be inflicted on the player when special effects are printed. Any trap will play well if minor to medium damage is inflicted. You can either inflict a standard amount of damage or can make it random. The methods are:
1) I recommend that you use a small set amount. The following will add 3 hit points to the player and then will jump to the melee routine to give a health status report:
DF = 0:D2 = 3: GOSUB 7636
2) A random hit from 0 to 4 can be given with this code:
DF = 0:D2 = INT(RND(1) * 5)): GOSUB 7636
3) If you want to make it truly dangerous with a chance of death, this code will randomly set the amount of damage to something between 0 and the character's total hardiness (M%(0,1)):
DF = 0:D2 = INT(RND(1) * (M%(0,1) + 1)): GOSUB 7636
4) A final alternative is to NEARLY kill the player by giving him hits that NEARLY wipe him out. This code will leave the player one hit point away from death:
DF = 0:D2 = M%(0,1) - M%(0,13) - 1: GOSUB 7636
THE DEATH TRAP
See if you recognize the following scenario: you are walking down a plain hall when you come to an unusual door. You open the door-no result. You pass thru the door, and are told that you walked into an atomic incinerator and have died! This is an example of the worst brand of 'Gotcha' death traps-no warning, no wind-up, and suddenly the game is over. There are four fair ways to have handled this same trap:
1) When the player attempts to open the door, open it, then print an effect that is similar to this: AS THE DOOR SWINGS WIDE, YOU ARE STRUCK BY A BLAST OF WHITE HEAT EMANATING FROM A ROARING INFERNO WITHIN. YOU HAVE FOUND AN ATOMIC INCINERATOR. Then if the player proceeds into the room, kill him.
2) When the player attempts to open the door, DON'T open it, but print an effect that is similar to this: AS THE DOOR SWINGS WIDE, YOU ARE STRUCK BY A BLAST OF WHITE HEAT EMANATING FROM WITHIN! YOU ARE STANDING BEFORE AN ATOMIC DISINTEGRATION CHAMBER! QUICKLY, YOU SLAM THE DOOR SHUT AGAIN!
3) Open the door but print nothing. When the player attempts to enter the room, do NOT actually move him into the room, but instead print an effect similar to this: AS YOU ENTER THE ROOM YOU ARE SEARED BY A BLAST OF HEAT! YOU REALIZE THAT YOU HAVE ENTERED AN ATOMIC INCINERATOR! QUICKLY YOU BACK OUT OF THE ROOM AND FLEE TO THE SAFETY OF THE HALLWAY!
4) Combine option (1) and (3). First give the warning from option (1), then if the player enters the room print the effect from option (3) to show him that he did something stupid. This option or option 2 is recommended; special effects are fun, and the player is not annoyed by needless restarts. It would also be appropriate to inflict some damage as outlined above.
DANGEROUS TRAVEL DIRECTIONS
Many Eamons are set in mountainous country, and it is not uncommon to have cliffs which will kill the player if he foolishly walks off of the edge. Typically, the room description will say something like THERE IS A CLIFF TO THE WEST. Note that it doesn't say how far away the cliff is, or even if it is the top or bottom of the cliff! Subsequently the player decides to go WEST to see if there is anything near the edge, or tries DOWN to see if the cliff can be climbed. Often the results are: YOU HAVE FALLEN OFF THE CLIFF! YOU HAVE DIED!
Now, think about this. In real life, no one is going to mindlessly walk off the edge of a cliff but will stop at its edge, and no one will attempt to climb down a sheer, unclimbable cliff face, either. The author forgets that a real adventurer would KNOW where the cliff edge was and if it was unclimbable. If the player blunders off the edge, then the failure was in the author's descriptions, NOT in the player's decision.
There are 3 valid solutions to this:
1) Simply make the room connection 0, thus using the standard message 'YOU CAN'T GO THAT WAY'. Not very imaginative, but it gets the job done. Remember, if it were real life, the player would KNOW he couldn't go that way because he would be able to see the cliff edge.
2) Make the room connection some random high value negative number, like (-900). Program some code in the 3070-3300 region in this fashion:
3070 IF R2 = - 900 THEN GOSUB 56: PRINT "THE CLIFF EDGE BLOCKS YOUR WAY.": GOTO 300
Notes: 'GOSUB 56' spaces one line and updates the line counter by 2 lines to allow for the text 'GOTO 300' exits the Move routine
3) Use a program line similar to option (2) that prints a special effect that is similar to this: YOU STEP TO THE EDGE OF THE CLIFF. EXAMINING IT, YOU SEE THAT IT IS TOO STEEP AND CRUMBLY TO BE SAFELY CLIMBED. SEEING NOTHING ELSE, YOU STEP BACK TO SAFETY. If the effect number was 15, for example, the programming would look like this:
3070 IF R2 = - 900 THEN GOSUB 51: R = 415: GOSUB 45: GOTO 300
Notes: 'GOSUB 51' spaces one line and increments the line counter by 1 Effects are in the 401-600 range, so effect #15 is record 415 'GOSUB 45' calls the description print routine
Don't make insulting comments like 'THERE'S A CLIFF THERE, STUPID!' If the player tried it, then the descriptions inadequately described the danger and the failure was the author's, not the player's.
An alternative to death by falling off a cliff is death by drowning. Remember the 'real life' rule when doing water hazards. The best way to handle water is with the standard 'YOU CAN'T GO THAT WAY' response, although the alternate 'YOU CAN'T SWIM!' is perfectly acceptable.
I dunno about you, but I NEVER drink or eat anything unless I have first saved the game. In fact, I never eat or drink at all if I can avoid it; the occurrence of 'Gotcha' fatal poisons is all too common. There are two fair ways to handle poisons:
1) Give it non-fatal consequences as outlined above.
2) Give it a readable label. This is more difficult to accomplish because it requires that the poison be two different types of artifact at once (readable and drinkable). But is the best way, because it gives the alert player a chance to avoid being blind-sided. To accomplish this: (a) The bottle's description must mention that there is writing on it. It would be best to avoid mentioning a label, because the player is liable to try to READ LABEL instead of READ BOTTLE. (b) make it a drinkable artifact (type 6) but add a line to the READ routine to recognize this one artifact (for example let's make it artifact # 5 and make the writing effect # 2):
23015 IF A = 5 THEN R = 402: GOSUB 45: GOTO 300
ACTS OF GOD
This category includes random events that were added to spice up the adventure. You are all familiar with the old pre-version 7.0 POWER command's 'the ceiling falls on you' death trap. Other examples that come to mind are snipers in modern settings and falling rocks in caves and mountains. This kind of random thing is great for adding realism and excitement, but is patently unfair if it kills the player off. Any of the above examples would play well using one of the 'damage' options. Imagine this special effect: A RUMBLE COMES FROM ABOVE. SUDDENLY A HUGE BOULDER CRASHES ON THE PATH BESIDE YOU AND BOUNCES ON DOWN THE MOUNTAINSIDE! YOU ARE PELTED WITH LESSER ROCKS; ONE THE SIZE OF TWO FISTS JUST MISSES YOUR HEAD! Exciting, huh? And even though you as the author know that the player won't be killed by any such special effects, HE doesn't know it!
FAIR DEATH TRAPS
Is it possible to have a death trap that is fair? The answer is yes; there are two ways to do so:
1) Automatic Resurrection: it's acceptable to kill off the player if a means of resurrecting him can be worked into the plot. One such means can be found in #114 'Thror's Ring'; the player's companions will pull him back from foolish moves or resurrect him with a spell.
2) Progressive Deadliness: death traps are acceptable if some means is provided for the player to learn how to recognize them. One way is to have a series of similar traps that increase in deadliness but offer similar clues as to their whereabouts. An alternate method of doing this is to describe the trap's characteristics in the introduction or by some other means so that the player will know what to watch for.
The bottom line on the subject of death traps is playability. It is NOT fun to have to start over and replay old, stale ground, especially if the player had no control over his demise. And the more fun that people have with your adventure, the higher they will rate it. And the higher the rating, the more people will obtain and play your hard work.
Being somewhat new to the use of Effects in an Eamon game, I have sat down and written out a mini-manual for beginning Eamon designers. The use of Effects is not explained in great detail in the designer manual, and I sorely needed to understand them. After a letter of help from Tom Zuchowski, and the study of the Eamon games 'Eamon v7.0 Demo Adventure' and 'Assault on Dolni Keep', I understand them a bit better now. I wrote down the uses as I came across them, and a wide variety of uses did I find.
Effects can be used for several things. They can print on the screen the message on a note found in a bottle. They can print something when a sword is picked up. They can be used to 'scare' the player. Etc...
Below follow just a few examples of the uses of Effects. Different people use Effects for different uses. Don't let this be a guideline of how to use them, but rather use it to give you ideas of what to do with them.
For those who don't know (i.e. beginners), Effects are stored in EAMON.DESC, record numbers 401 through 600.
Basically, to print out an Effect, one would have a line like this in the MAIN PGM:
R = 401: GOSUB 45
Where R is the record number of the Effect to be printed. In this example, we are printing Effect #1. Since Effects are stored at 401-600, we must add 400 to the Effect number to get the record number. GOSUB 45 calls the subroutine that reads in and prints EAMON.DESC records.
But the question here is, where would one have an Effect in the program? One such place would be in lines 3070-3390 (MOVE). An example of a use in this area would be like this:
3070 IF R2 = - 300 THEN R = 425: GOSUB 45: GOTO 100
R2 is the room to be moved to. When the player tries to move to a room connection with a negative number, he is not actually moved. This allows extra programming to be added for special stuff. In this example, we are using a room connection of (- 300) to trigger the printing of Effect #25, or record #425. Such an Effect might be something like: THE CAR RACES PAST YOU, ALMOST HITTING YOU. THE DRIVER LEANS OUT THE WINDOW AND SHOUTS SOMETHING ABOUT BEACHES. Another example is: WALKING INTO THE CRUSHER, YOU BARELY JUMP OUT BEFORE IT FLATTENS EVERYTHING INSIDE OF IT!
Another interesting use of Effects would be this: you are climbing a mountain. Every now and then, this happens: SUDDENLY, A LARGE BOULDER COMES CRASHING DOWN, NOT 5 FEET FROM WHERE YOU STOOD A MOMENT AGO! This could be generated this way:
510 IF RO < 24 OR RO > 36 THEN 100
520 IF RND(1) > .7 THEN R = 401: GOSUB 45
RO is the current room number. In this example, the mountains are rooms 24 through 36, and the Effect is #1. 100 is the beginning line number of the YOU SEE code that prints what you see in the room.
Line 520 sets up a random number, which will be greater than 0 but less than 1. In this example, if it is .7 or less, the effect will not be printed. What this does is to set the odds to be 70% that it will not happen and 30% that it will. You can set this number to anything between .01 and .99.
Putting this code in the 500-900 programming area will cause it to print out after any monster attacks take place and before the 'YOU SEE' printout. Another good place to put it is in the 201-209 area, where it will print just before the YOUR COMMAND? prompt. If there isn't enough room in the 201-209 area, you can GOSUB to some free line numbers somewhere else.
Another Effect could be added to our 'mountain effects' like this. Imagine that we have 6 effects that are Effects #1-6:
530 R = INT(RND(1) * 6) + 1: IF R < 6 THEN R = R + 400: GOSUB 45
In this way it produces a random effect. Effect #1 might be the 'huge boulder' line printed previously. Effect #2 might be: YOUR HAND SLIPS! YOU BEGIN TO FALL, BUT CATCH YOURSELF AT THE LAST MOMENT! Effect #3 might be: TINY ROCKS BEGIN TO PELT YOU FROM ABOVE. IT APPEARS THAT SOMEONE OR SOMETHING IS THROWING THEM DOWN ON YOU.
Another kind of Effect would involve picking up a weapon or artifact:
4145 IF A = 8 THEN IF NOT QQ THEN R = 405: GOSUB 45: QQ = 1
4235 IF A = 8 THEN IF NOT QQ THEN R = 405: GOSUB 45: QQ = 1
In this example, the Effect is #5 and it is printed when Artifact #8 is picked up, but only if QQ = 0. If QQ = 1, then the artifact has been picked up before and the Effect is not printed. You could use another variable name besides QQ that is not already being used. Line 4145 covers a regular GET command, and Line 4235 covers the command GET ALL. If you have a LOT of something like this to handle, you could do it like this:
31440 DIM QQ%(NA)
4145 IF A = 8 THEN IF NOT QQ%(8) THEN R = 405: GOSUB 45: QQ%(8) = 1
4235 IF A = 8 THEN IF NOT QQ%(8) THEN R = 405: GOSUV 45: QQ%(8) = 1
This code does the same as above, but instead of a single variable QQ, you use an array QQ%() that has a location for every artifact. This makes keeping track of them easier for you while programming the adventure. You can use any array name, as long as it is not already being used. Consult the Designer's Manual to see which array names are already in use.
Here's another example, using the array technique:
4146 IF A = 9 THEN IF NOT QQ%(9) THEN R = 478: GOSUB 45: DF = 0: D2 = 3:
GOSUB 7636: QQ%(9) = 1
4236 IF A = 9 THEN IF NOT QQ%(9) THEN R = 478: GOSUB 45: DF = 0: D2 = 3: GOSUB 7636: QQ%(9) = 1
In this example, when artifact #9 is picked up for the first time, then Effect #78 is printed, then the player takes 3 points of damage.
For use of Effects when reading a note or label, etc., refer to lines 23000-23210 in the MAIN PGM. The use of Effects here is already added to the MAIN PGM. You use DUNGEON EDIT 7.0 to make the note a 'Readable' artifact type, and put the number of the Effect in the field that is titled '1ST EFFECT'. If it is a long message, you can use sequential effect numbers and then put the total number of Effects to be printed in the '# OF EFFECTS' field. If there is just one effect to be printed, '# OF EFFECTS' must be 1.
I am now through describing some basic uses of Effects. Any further ideas should be used by you. If you have any interesting uses for them, please drop me a line with your idea. I'd love to hear some others. Thanks to Tom Zuchowski for writing to me explaining how to use Effects. Robert Parker, 4025 Sunset Pl., South Bend, IN 46619.
New Eamon authors have been almost eternally plagued by problems: "How do I add a new command?" "How can I make the POWER spell do what I want?" "How do I..." and the list goes on.
In the recently rediscovered 'Eamonomicon', the answers to these and many more questions were found. If you're new to Eamon designing, read on...
First, it must be said that it is VERY important to obtain a printout of the MAIN PGM. Without this, it is difficult to decipher the inner workings of each routine. Use the full 80 columns of your printer or even a compressed 132-column mode if you have it, both to save paper and to minimize the paper shuffling while jumping back and forth from routine to routine. Don't fool yourself into the false economy of saving paper; the ease of working on paper, being able to spread it out before you and make notes on the printout will more than make up for 2 cents worth of paper and ribbon.
Commit the following variables to memory:
RO room player is in M%(x,5) room monster is in A%(x,4) room artifact is in T(1) true if hostile monster is in room M%(0,13) player's wounds (damage or 'hit' points) M%(0,2) player's agility
HOW TO ADD A COMMAND
To add a command to the MAIN PGM, change these lines:
LINE 31910: the number stored in this data statement is the total number of commands. Add 1 to this number for each additional command
LINE 31930: put new commands in a list on this line in the same format as line 31920. All commands must be single words with no spaces in the middle; use a hyphen to join two words together if it is a two-word command.
LINE 290: add the line numbers where the start of each new command is located. These must be in the same sequential order as the commands at 31920-31930
Add special programming for each new command at the new line numbers specified in line 290
The best thing to do is to look and see how any normal command is handled by the lines listed above. Here are a few tips:
End each routine with a GOTO 98. This will print a blank line, update the line counter, and proceed to the code that checks to see if there is a fight in progress. Except in special cases, this should always be the exit point.
If the command requires an object, always GOSUB 4900 to check to see if an object was included in the command. If no object was specified, this routine will ask for one before returning.
Use the search routines. GOSUB 4700 for monsters and GOSUB 480x for artifacts. If either of these routines return with the variable F = 0, then instead of exiting to 98, exit to the appropriate error message at lines 91-96. Note that the routine at 4800 has different entry points for different circumstances; once again it is best to examine the code in the MAIN PGM to see how it is done. For example, if the artifact you are looking for must be carried by the player for the command to work, see lines 5010-5030 of the DROP command for the proper coding. If the artifact must be in the room, see lines 4010-4020 of the GET command. If the artifact can be carried by the player or be in the room, see lines 6010-6020 of the EXAMINE command. For artifacts that must be worn, see 27010 of the REMOVE command.
If the command only works with one particular artifact, DO NOT do a string compare with the artifact's name; instead use this line: IF A < > (# of artifact) THEN 94 If the search routine at 4800 finds a match, it returns with the variable A set to the number of the artifact that it found a match to. By checking the artifact number instead of the string, you are letting the search routine worry about abbreviations so you don't have to, and you also get a very consistent response to different abbreviations.
HOW TO USE THE POWER SPELL
The POWER spell effects are in lines 13015-13080, though 13080 may be easily renumbered to anything as high as 13990 for more code space.
For random effects, such as a chance that a cow may fly past, check to see if the random number RL (generated in line 13010) is smaller than the chance (from 1-100) of it happening. If it involves an artifact or a monster entering the room, set the artifact/monster's location to that room. If it's a monster, be sure to then GOSUB 3600 to check its friendliness.
Be sure to put the checks of RL in sequential order. The smallest chances must be checked first, with greater chances following in order of probability. In the following example, the dragon is monster #1 and the box is artifact #1:
13015 IF RL < 35 AND M%(1,5) < > RO THEN PRINT: PRINT " A DRAGON
MATERIALIZES!": M%(1,5) = RO: GOSUB 3600: GOTO 98
13020 IF RL < 60 AND A%(1,4) = 0 THEN PRINT: PRINT " A BOX APPEARS!": A%(1,4) = RO: GOTO 98
Also, you can have room-specific effects. These are placed before the random ones and check the room number before being executed. In this example, room 13 has a brick wall, artifact #4, that hides a treasure, artifact #5:
13012 IF RO = 13 AND A%(4,4) = RO THEN PRINT: PRINT "THE WALL EXPLODES! SOMETHING WAS BEHIND IT!": A%(5,4) = RO: GOTO 98
HOW TO USE THE 'USE' COMMAND
The USE command is exceptionally easy to use, as all you have to do is check for the artifact you wish to use and then furnish the effects. In the following example, the artifact must be in the player's inventory to be used:
28020 GOSUB 4900: GOSUB 4801: IF NOT F THEN 91
If it can also be in the room, change the above code to read like this:
28020 GOSUB 4900: GOSUB 4804: IF NOT F THEN 94
Here are some examples of code for the USE command (artifact #5 = drugs; #6 = computer; #7 = concrete; #8 = broken wall in room 27; #9 = new wall):
28030 IF A = 5 THEN PRINT: PRINT "WHAT ARE YOU, A FOOL?": GOTO 98
28040 IF A = 6 THEN PRINT: PRINT "THE BLASTED THING EMITS A CURL OF SMOKE, THEN EXPLODES!": A%(6,4) = 0: GOTO 98
28050 IF A = 7 THEN IF RO = 27 THEN PRINT: PRINT "YOU'VE FIXED THE WALL!": A%(7,4) =0: A%(8,4) = 0: A%(9,4) = RO: GOTO 98
You may also have the USE command refer to other commands, if the artifact type is right. This is useful for weapons and healing potions. You must check the artifact type, A%(A,2), to see if its the right type. In this example, the command USE (weapon) will jump to the READY command (artifact type 2 = weapon):
28060 IF A%(A,2) = 2 then 17000
Happy Adventurer slaying!
It is not clearly described anywhere in the manual how to properly design for and use the 40/80 column option of version 7.0. This article will attempt to demonstrate just how this is done.
THE INTRODUCTION PROGRAM: when the intro asks whether 40 or 80 columns is to be used, it POKEs either a 40 or an 80 into an unused memory location, so that this information can easily be passed to the MAIN PGM.
THE MAIN PGM: the MAIN PGM PEEKs this number from memory and sets the variable CP to this value. CP is used by the line-counting routine to decide if a description will take (for example) 6 40-column lines or 3 80-column lines.
That’s it! With the addition of code to turn off 80-columns at the end of the adventure, that is the entire programming for the 40/80 column option.
But it's not quite that simple from the author's point of view! Each and every room, artifact, and monster description and all the effects must be carefully designed to look good in BOTH 40-column and 80-column modes. This isn't difficult to do, but can be tedious, depending on just how good you want your descriptions to look.
DEFINITIONS: the following explanation refers to 'odd-numbered' lines and 'even-numbered' lines. Refer- ring to Figure 1a, the 'odd-numbered' lines begin with THIS, HIGHLIGHTS, and BREEZE, and the 'even-numbered' lines begin with POLISHED, LAMP, and ABOVE.
The standard method of writing 40-column Eamon descriptions is to pad the end of each 40-col. line with spaces so that the text will have good line breaks and be left justified. Figure 1a gives an example of this. However, when this same description is displayed in 80-col. mode, a huge gap appears in the center of the text, as shown in Figure 1b. This looks awful and is very distracting, resulting in less player satisfaction and lower ratings for your adventure.
The answer is to spread the extra spaces out along the entire line so that there is never more than a single space at the end of the line. Figures 2a and 2b give an example of this technique. Here are some guide- lines that will help you design good-looking text:
1) The extra spaces are less noticeable following punctuation and next to large words. First put spaces after punctuation before sticking them elsewhere. You can get away with 3 spaces after a comma or a period and still look good.
2) The ODD-NUMBERED lines must never have more than one space at the end of the line. These lines will be the left half of each 80-col. line.
3) If an ODD-NUMBERED line works out to exactly 40 characters so that there is no room for a space at the end, then the following EVEN-NUMBERED line must BEGIN with a space. When these two lines are combined for 80-col., there must be a space between them or else the two words in the center will be run together.
4) The FIRST line can have paragraph-like indentation at the beginning, as has been done in Figures 2a & 2b. If this indentation runs more than 3 spaces then possibly some of the spaces should be spread through the rest of the line.
5) You can treat the EVEN-NUMBERED lines as if they were 40-column only. These lines make up the right half of each 80-col. line and extra spaces at the end don't matter. However, you may want to spread some of the extra spaces into the text to keep it from looking 'heavy' on the right side of the 80-col. line if there is a lot of padding in the left half of the line. Try to balance the line so that the odd-numbered half and even-numbered half are equally dense looking.
6) Try not to put many spaces near short words. The text can get real sparse looking which is unattractive.
OK, now we have filled the huge gap presented in Figure 1b, but Figure 2b still presents a 'gap-tooth' look because all of the spaces are in a straight row, giving a 'two-column' look that is not esthetic to look at. And when several descriptions are run together, as in a large special effect or the appearance of several new monsters, the two-column look becomes quite pronounced and is distracting to read.
The way to fix it is by designing the text so that at least one but no more than two of these middle-of-the line spaces come at the beginning of an even-numbered line instead of at the end of an odd-numbered line. Figures 3a & 3b demonstrate this technique. Yes, the left margin is ragged using this method, but it's not that noticeable and is a lot less noticeable than a line of spaces down the center of your 80-column screen.
That's all there is to it. It takes a little practice and you may have to re-edit a few times before you get it looking good. A paperback Thesaurus is absolutely essential for finding alternative words when you just CAN'T get that darn description to fit the lines right. Also, a Thesaurus is very valuable in helping you avoid overusing a given word when describing (for example) several successive rooms that are very similar.
80-COLUMNS ON THE APPLE II AND II+: The Apple II+ uses a variety of aftermarket 80-column boards, since Apple did not offer an 80-column option for this machine. The Videx board was by far the most successful, and most all other II+ 80-column boards conform to the Videx 'standard'. For the most part it will work fine when you use VTAB, HTAB, POKE 1403, and PEEK 37. However, it does not properly support the HOME command. For HOME to work on a Videx board, it must be followed by a CHR$(12), the Form-Feed character. The technique that I recommend is to set the variable FF$ = CHR$(12); and when clearing the screen use the double command HOME:PRINT FF$ (This will be invisible on a //e or in 40-col. mode). Try to avoid fancy CALLs that clear to end-of-line or do other things, because they won't affect the Videx screen at all. If you need to do such a thing it can be done by printing a line of spaces.
INVERSE and FLASH also do nothing on a Videx.
80-COLUMN INPUT ON THE II AND II+: Since the II has no shift key, the 80-column board must be able to keep track of the case being used and convert the II's upper-case input into lower-case when required. This is done by sending keyboard input to the 80-column board before it goes to the Apple so that the character can be converted if need be. Also, the Videx uses CTRL-A for shift-key and caps-lock and must be able to intercept this keystroke. All this means is that you MUST use GET and INPUT and can't PEEK the keyboard data directly.
Eamon authors and adventurers all have one thing in common: If you want to play, you must play under the old DOS 3.3 operating system. While there is really nothing wrong with this, what if you would rather play under the ProDOS operating system? You are kinda out of luck, aintcha? Not so, Oh tall one! It is unbelievably simple to convert a DOS 3.3 version of a given scenario to ProDOS - even a niffling such as yourself can do it with ease!
But first, why should you convert? To be truthful, there is no adventure oriented reason. A given scenario in ProDOS will appear identical to one under DOS 3.3. But how many adventurers habitually live in the DOS 3.3 world? The advent (No pun intended) (yeah, right) of the Apple IIGS and various program selectors for the rest of the Apple II series, means adventuring in any Eamon world requires that you re-boot the entire system. That's defeating the whole purpose behind the program selectors. However, if you have a ProDOS version of an Eamon adventure, you can simply select the Master Program from within your program selector and be off!
For instance, I play on an Apple IIGS. If I want to play one of the old DOS 3.3 versions, I have to essentially shut the whole thing down, and re-boot on the EAMON MASTER DISK. But, since I have a ProDOS version of the Master, all I need to do is point my mouse at it and "click". Zip, I'm in the Main Hall. From there, it's essentially the same as in the DOS 3.3 versions. Unfortunately, even though I have a ProDOS Master disk, I still need to convert my old DOS 3.3 scenarios if I want to adventure in them. There are other disadvantages to DOS 3.3, not the least of which is it's speed. ProDOS disk access is usually about eight times faster than DOS 3.3.
A thought for future authors, under ProDOS, you could make use of the CHAIN command, which carries variables with it. In other words, under DOS 3.3 you have to write all your variables to a file, RUN the other program, then READ the variables again. Under ProDOS, all you need to do is CHAIN to the next program. The variables will carry over unchanged. ProDOS also offers SAVE and RESTORE commands, which allow you to STORE all your variables in one file, then RESTORE them to a different program - even if your computer has been shut off. (The chain program does this too, but the file created is temporary, internal to the computer, and wiped out when the power goes away. You'll never see it.)
That's neat, but how can I convert the games I already have? Converting Eamon adventures is very easy. In fact, there are fewer than 30 program lines that HAVE to be changed or added. All you need other than a willingness to type a little - is some way to copy files from your DOS 3.3 disk to a ProDOS disk (I use Copy II+). A program such as Beagle Brothers PROGRAM.WRITER can be handy for this project too, but is hardly necessary.
You start out by formatting a blank floppy for use under ProDOS. I recommend it follow this disk naming convention: EAMON.P.XXX, where XXX is the adventure number. Copy II+ or your System Utilities disk can do this for you. Next, use your copy files utility to copy ALL the files on the DOS 3.3 disk to the ProDOS disk. Once that is done, put your DOS 3.3 disk away, you're done with it.
Now, set your PREFIX to your ProDOS Eamon disk, and do a CATalog. You should note that most of the file names have been changed, and in some cases, truncated. This is because ProDOS won't allow filenames longer than 15 characters, and won't allow spaces in the filename. Even most punctuation is replaced with periods. This is nothing to worry about, since it's what the conversion is really all about. In fact, the hard part is done.
In point of fact, that is the whole reason behind the rest of this column. Under DOS 3.3, Eamon filenames are full of spaces and special characters but since ProDOS won't allow spaces or special characters in a filename, AND limits that filename to 15 characters, several EAMON program lines need to be changed to make the programs run properly. Don't worry, there are surprisingly few, and the conversion is very simple.
The next step is the re-naming of several of the programs, mostly just to make the filenames easier to read. One will Usually be: EAMON.ADVENTURE. This file started life as EAMON ADVENTURE # XXX. I recommend you rename it EAMON.XXX (again, XXX is the adventure number). Another file that usually requires renaming is the description file - For instance: THE MINES OF MORIA will be: THE.MINES.OF.MO. after the file copy process. Needless to say, while that can be understood, it's a bit clumsy. I suggest something like: MINES.OF.MORIA. It's still the same file, but it's a little easier to understand the filename. Of course, there ARE those description files whose names are just too long to make understandable under ProDOS, but, since it's just a name, we must do the best we can and live with it.
Now you need to create a short program. In fact, one line is all you really need:
100 PRINT CHR$(4)"RUN (description file)"
For Mines of Moria, the program would be:
100 PRINT CHR$(4)"RUN MINES.OF.MORIA"
Save this program under the name LEADIN. This is a MUST, since both known ProDOS EAMON MASTER disks look for this file. You can add your own embellishments to this program to make things flow more smoothly. For instance, the LEADIN programs I write check for a SAVED game and make provisions to resume it, so they look like this:
100 ONERR GOTO 300
200 PRINT CHR$(4)"VERIFY GAME.VAR":PRINT CHR$(4)"RUN MAIN.PGM,@29000"
300 POKE 216,0:PRINT CHR$(4)"RUN (intro pgm)
Line 200 checks for the file "GAME.VAR" and if it finds it, runs MAIN.PGM, starting at line 29000 - which is where I generally put the RESUME game routine. If "GAME.VAR" is not found, the description file is run, which in turn passes you to MAIN.PGM - but at the beginning, since you are starting a new adventure.
Now, LOAD the MAIN.PGM and LIST line 130. This line varies greatly from one scenario to the next, but they are all similar. Re-type this line exactly, character for character, except where you see PRINT DK$"READ EAMON.ROOM NAMES,R". At this point, type PRINT DK$"READ EAMON.ROOM.NAME,R". Not much difference is there? But it's enough.
One thing to note: when you list line 130, if you don't see anything resembling EAMON.ROOM NAMES anywhere, take a look at the few lines nearest it in the program. If you still can't find a reference to EAMON.ROOM NAMES, note where any nearby GOSUBs go, and take a look at THOSE line numbers. There have been a few occasions where this part of the line has been stashed as far away as line 37000.
LIST line 1040. Do the same thing, using the filename FRESH.MEAT instead of FRESH MEAT.
LIST line 1060. Notice any similarities to line 130? Right, it looks at EAMON.ROOM NAMES too. Re-type this and change EAMON.ROOM NAMES to EAMON.ROOM.NAME .
LIST line 1050. Does it end with "PRINT DK$"DELETE FRESH.MEAT"? If not, add line 1055:
1055 PRINT DK$"DELETE FRESH.MEAT" At this point it would be a good idea to SAVE your changes. Nothing is quite so frustrating as spending even as little as 5 minutes on something, only to have it blown away by a random loss of power, or the calculating destructiveness of your local housecat.
This much is fine, and will allow us to play the game, with a little extra typing to get things started, but we still need to address what happens when we successfully complete the quest. So:
First, check to make sure the lines between 2500 and 2900 don't do anything but provide an exit back to the Main Hall. (They shouldn't it's usually all that's ever there). Now delete them and type in the following listing:
2500 REM >>> RETURN TO MAIN HALL <<<
2510 ONERR GOTO 2530
2520 PRINT DK$"OPEN EAMON.PREFIX":PRINT DK$"READ EAMON.PREFIX":INPUT PR$:PRINT DK$"CLOSE": GOTO 2570
2530 POKE 216,0:REM >> ERROR TRAP <<
2540 PRINT DK$"CLOSE":PRINT DK$"PREFIX": INPUT CX$
2550 PRINT:PRINT:PRINT CX$:PRINT "IS THE CURRENT PREFIX":PRINT"INSERT YOUR MASTER DISK AND ENTER ITS PREFIX"
2570 PRINT DK$"PREFIX"PX$
2580 PRINT DK$"VERIFY MAIN.HALL":POKE 216,0:IF DIE THEN PRINT DK$"OPEN THE.ADVENTURER": PRINT DK$"CLOSE":PRINT DK$"DELETE THE.ADVENTURER":GOTO 2630
2590 IF REC=-1 THEN 2630
2600 PRINT DK$"OPEN CHARACTERS,L150":PRINT DK$"WRITE CHARACTERS,R"REC:PRINT MN$(0): PRINT MD%(0,1):PRINT MD%(0,2):PRINT CH: FOR A=1 TO4:PRINT SA%(A):NEXT A
2610 FOR A=1 TO 5:PRINT WA%(A):NEXT:PRINT AE:PRINT SEX$:PRINT GOLD:PRINT BANK:PRINT AC:FOR A=1 TO 4:PRINT WN$(A):PRINT WT%(A): PRINTWO%(A):PRINT WD%(A):PRINT WS%(A): NEXT
2620 PRINT DK$"CLOSE":PRINT DK$"OPEN THE.ADVE NTURER":PRINT DK$"WRITE THE.ADVENTURER": PRINTMN$(0):PRINT REC:PRINT DK$"CLOSE"
2630 REM >>> RETURN TO MAIN HALL <<<<
2640 PRINT DK$"RUN MAIN.HALL
Save the program again.
Take a look at the SAVE/RESTART routines - usually kept at line 18000 and 29000 respectively. Make sure they don't make use of the old filenames. If they do, they need to be changed. Use lines 130, 1040, and 1060 as examples if you need to. ( A better set of ProDOS SAVE/RESTORE game routines should be the subject of a future Dungeon Designs column. )
What about the other programs?
Now, take a look at the remaining BASIC programs on the disk. If you are not sure which they are, simply CATalog the disk and check it out. Every BASIC program will have "BAS" immediately to the right of the filename.
LOAD each remaining BASIC program in turn, and look through it for lines where it makes reference to one of the other files on the disk. In most cases it will be something like this:
20 D$=CHR$(4):PRINT D$"OPEN FRESH MEAT":PRINT D$"READ FRESH MEAT":INPUT NAME$:INPUT REC: PRINTD$"CLOSE"
500 PRINT:PRINT"GOOD LUCK, "NAME$".":PRINT D$"RUN MAIN PGM"
I can't tell you which specific line numbers to change in these cases, since there are nearly as many different line numbers as there are scenarios.
What lies behind all these changes? By now you will have noticed that all this typing (well, most of it) has to do only with those lines that OPEN or otherwise make use of the files on the disk. With this knowledge, you should be able to go through the rest of MAIN.PGM and the other BASIC files and make sure that the filenames - as they appear in the program - agree with what shows up when you CATalog the disk.
That, believe it or not, is all there is to converting the scenarios to ProDOS. It looks more difficult than it really is. In fact, if you intend to convert more than one or two, it might behoove you to use a text editor to pre-type the necessary lines as an EXEC text file, since the applicable lines rarely change. You can even have the Exec file load in your programs for you, and save the program when the changes have been made. Once all the changes have been made to all the programs, you're set! Launch your ProDOS MASTER disk, and go slay a few orcs!
Lurch has done a large number of conversions using the method that he outlined in the preceding article. While it should be mentioned that there are no significant differences between my conversion method and Lurch's, his method and mine differ in some minor respects, that I will list here:
1) I don't check for a saved game in the LEADIN pgm, but do this check at Line 20 of the MAIN.PGM, as it is done in the Dos 3.3 version. In my opinion Lurch is 'showing off' ProDOS features with this step <grin>. Also, I name the saved VAR file SAVED.GAME instead of GAME.VAR.
2) I do not add line 1055 to delete the FRESH.MEAT file if it is missing. In fact, I REM out line 1055 whenever I find it! I don't see any good reason for deleting this file, as it makes it impossible to start a game over again without returning to the Master to resurrect your character and then launching the adventure all over again, a totally unnecessary procedure.
3) I rename the intro pgm in the format EAMON.nnn.INTRO. Note that we are using a 3-digit convention here, with leading zeroes in 1 and 2 digit Eamon numbers (eg: EAMON.008.INTRO).
4) I delete the pgm EAMON ADVENTURE #nnn altogether. It serves as the HELLO pgm in Dos 3.3 but serves no purpose in ProDOS.
5) I add a short pgm with the name REV.DDMMMYY (where DD=date; MMM=month; YY=year). This pgm has 2 lines:
10 HOME: VTAB5: PRINT"EAMON ADVENTURE #nnn": PRINT: PRINT "(name of adventure)": PRINT: PRINT "BY (name of author)" 20 VTAB15: LAST UPDATE: MM/DD/YY
6) Lurch & I disagree on the subject of error trapping when returning to the Master disk. Lurch believes in handling the errors that don't require too much code, whereas I believe that if you aren't going to trap them all then it is better to let all the errors crash uniformly. My 'return' code is:
2500 PRINT DK$"OPEN EAMON.PREFIX": PRINT DK$ "READ EAMON.PREFIX": INPUT PX$:
PRINT DK$ "CLOSE"
2510 HOME: VTAB 5: PRINT "(INSERT EAMON MAS TER DISKETTE, THEN": PRINT " HIT THE 'C' KEY) ";: POKE -16368,0
2515 GET A$: IF ASC(A$) = 3 THEN PRINT: END: REM CTRL-C 2517 IF A$ < > "C" THEN 2515
2520 PRINT A$
2525 ONERR GOTO 2510
2530 PRINT DK$"PREFIX "PX$
2540 POKE 216,0: IF DI THEN PRINT DK$;"DELETE THE.ADVENTURER": GOTO 2900
2550 PRINT DK$"OPEN CHARACTERS,L150": PRINT DK$"WRITE CHARACTERS,R";REC: PRINT MN$(0): PRINT MD%(0,1): PRINT MD%(0,2): PRINT CH: FOR A = 1 TO 4: PRINT SA%(A): NEXT
2560 FOR A = 1 TO 5: PRINT WA%(A): NEXT: PRINT AE: PRINT SEX$: PRINT GOLD: PRINT BANK: PRINT AC: FOR A = 1 TO 4: PRINT WN$(A): PRINT WT%(A): PRINT WO%(A): PRINT WD%(A): PRINT WS%(A): NEXT
2570 PRINT DK$"OPEN THE.ADVENTURER": PRINT DK$"WRITE THE.ADVENTURER": PRINT MN$(0): PRINT REC: PRINT DK$"CLOSE"
2900 PRINT DK$"RUN MAIN.HALL"
7) I am taking the INIT lines at 1001-1038 out of the MAIN.PGM and putting them in a small program named MAKE.FAST.START. This pgm loads EAMON.ARTIFACTS and EAMON.MONSTERS, and STOREs then in a VAR file named FAST.START. I put a line in the MAIN.PGM at 1010 to RESTORE FAST.START, resulting in a lot faster startup. I also write a companion pgm to MAKE.FAST.START named MAKE.ARTS.MONS that will generate EAMON.ARTIFACTS and EAMON.MONSTERS from the FAST.START file for editing. This allows you to delete EAMON.ARTIFACTS and EAMON.MONSTERS to save disk space.
8) Both Lurch & I are using STORE and RESTORE to save and resume games. It is very compact and fast. Here is my code:
18000 REM SAVE GAME
18010 PRINT: PRINT "DO YOU WANT TO SAVE THIS GAME? ":INPUT "(Y/N) :";A$: A$ = LEFT$(A$,1)
18020 IF A$ < > "Y" AND A$ < > "N" THEN 18010
18030 IF A$ = "N" THEN 100
18040 PRINT DK$"CLOSE": PRINT DK$"FRE"
18050 PRINT DK$"STORE SAVED.GAME"
18080 PRINT: PRINT "THE GAME IS NOW SAVED. RUN THE PROGRAM NAMED 'MAIN.PGM' TO RESTART THE GAME."
29000 REM RESTORE
29005 POKE 216,0
29010 PRINT: PRINT "DO YOU WANT TO RESUME THE SAVED GAME?": INPUT " Y OR N:";A$: A$ = LEFT$(A$,1)
29020 IF A$ < > "Y" AND A$ < > "N" THEN 29010
29030 IF A$ = "N" THEN PRINT DK$"DELETE SAVED. GAME": RUN
29040 PRINT DK$"RESTORE SAVED.GAME"
29060 PRINT DK$"OPEN EAMON.DESC,L256": PRINT DK$"OPEN EAMON.ROOMS,L64": PRINT DK$"OPEN EAMON.ROOM.NAME,L64"
19070 GOTO 100
It should go without saying that you really need a good program editor to do these conversions. Lurch recommends Program Writer. I have been using a ProDOS version of GPLE and have found that GPLE won't do global searches in line numbers over 9999 on my enhanced //e, so Program Writer is probably the way to go.
Hark! Ready to write an adventure? You're a Basic whiz, know every trick in the book and crush bugs for lunch. You write it and send it to the EAG and LO! Your mighty game gets a 3? What's wrong with those morons? After all, you used flawless algorithms.
Well, let's take a look at your game...."REVENGE OF GWAR". The evil warrior demigod Gwar has taken over a cavern south of town, threatening all life for miles around. You go in, beat up all the cronies, and slay Gwar. What more could you ask for?
A lot. Where's the story here? Who or what is Gwar? Why is he so bad? What's the revenge angle? Where is this town? Why can't they handle Gwar by themselves? This information, known as background, is important to give the adventure some depth and detail. It is also good for helping out with items and events that come along later in the game. For example, if we know that Gwar eats Spam, the adventurer would find lots of Spam cans. Good hints can be placed in the intro, such as recounting a tale of how Gwar once attacked but fled when a turnip cart came near him.
Now we have a background? Is the story ready to go yet? Not unless the bulk of the adventure is interesting and builds up to the finale. What happens in between the intro and the confrontation with Gwar? The player wanders through the caverns looking for Gwar and fighting monsters.
BORING! This is the easiest formula for failure. There are so many random fight-fests out there that they all just get dull. First, if you refuse to have any sort of building plot, at least spice it up. Puzzles and humor work wonders for otherwise sorry adventures. Preferably, build up the plot. In the case of our search for Gwar, what happens in the caves as we search for him?
The key to writing a plot up is, "Would this make for an interesting read if it were a book rather than an adventure?" I was told this by a certain author who knows who he is, and it's helped me five-fold when it comes to writing adventure plots.
This is when you have to get creative; now you need a plot. For space limitations, I'll keep it simple. Remember to keep the background in mind. Nothing annoys like meeting a monster in an impossible and unexplained place.
In our search for Gwar, the character might have to: 1) find the caverns 2) get in 3) get through an orc lair 4) find in the orc treasure how to reach Gwar 5) reach Gwar 6) defeat him.
Each of these steps would have its own substeps. For instance:
3) Get though orc lair a. fight sentries b. open locked door c. find turnip in kitchen (which slays Gwar) d. find Orc King's escort too big to fight e. find secret door to King's room f. slay Orc King; orcs flee
Each of these steps would have their own special programming and such, but obviously the variables and such aren't independent of other steps. You have to make allowances for what can go wrong, or prevent wrong things from happening. Not to mention covering the possibility that the player may try to go about solving a problem a different way than you intended. Putting the plot to play is a long process that includes special programming and text that can only be arrived at through experience gained from trial and error.
Now that you've got that out of the way, what happens once the player beats Gwar? Few things can be as anti-climactic as a dead body and then walking out a side exit, with no more than "You ride off into the sunset" for reward.
Gwar is a mean dude, and he's not of this Earth. Have him go out with a bang. Bodies dissolving in smoke (appropriate only for unnatural beings), disappearing corpses, last words, and gory details always spice up the death scene of an arch-nemesis.
Now that the town is rescued from Gwar, the character is a hero, and heroes do more than ride off into sunsets. A good thing to have is a wrap-up at the end of the adventure consisting of a few effects. These are used to explain the hero's welcome (bumbling moron's welcome?), the town's reaction and reward to the valiant warrior, and anything else that needs to be said. This is one feature that I feel is sorely lacking in most Eamons lately.
The game is complete now. Or is it? What about the text? After all, it's how the player relates to the game. Good grammar can wait. Are the descriptions good? Compare:
YOU SEE GWAR. HE GROWLS AT YOU.
SITTING ON A THRONE IS A GREAT, TOWERING SHAPE WITH RED SHAGGY FUR, SHARP GREEN FANGS AND BEADY EYES. HE SNEERS AND SAYS, 'I AM GWAR! PUNY MORTAL, PREPARE TO BE LUNCH!"
More interesting, isn't it? Do that for everything: monsters, rooms artifacts, and especially effects.
Here comes the equivalent of bug removal for the plot, that is, checking for holes. Pretend you're playing the game, and for some reason can't take a thing for granted. Ask questions about why everything is. Are these things fairly explained or fairly obvious? If not, then you should place something in the game to explain it. For example, if you have 80 jillion orcs in your game, you should have a logical reason. (Author's note: I remember while working on "Ragnarok Revisited" Tom sent me back about a page and a half of questions involving holes in the plot. Working the answers into the game sent the rating up about 3 points.)
Now you game is ready to be mapped, entered, programmed, debugged, and finally released. It's the shortest step, but the most important.
To learn much more about the importance of a good plot, play all the high-rated adventures (8's and up). This is something better learned by example than theory. Take notes. What do you like and what do you dislike about every adventure you play?
"But I don't have any ideas!" you may whine. "I can't think of anything interesting!" Here's a few off the top of my head. If properly used, things like these can really spice up an adventure: unusual magic; an interactive device (like a computer or radio); mysterious things; companions and monsters that "do• things; mysteries about monsters and companions; unusual portals; humor; weapons of uncommon destruction; buying and selling of artifacts; riddles. If you can't come up with much, at least have stuff to read, examine, open, unlock, and find.
While working on one of his adventures, Rob had terrible problems with database corruption in the EAMON.ROOMS file. The problem was traced to the fact that it was to be a 10-direction adventure instead of the normal 6 directions.
Version 7.0 allows for an average of 4 digits for each of the 6 directions from a given room plus the lighting status, for a total of 32 bytes (including CR's after each value). Rob's adventure used lots of special room connections and was averaging very close to 4 digits for ten directions, for a total of about 50 bytes. This meant that the room data was overrunning the disk record space that was allotted for it.
Version 7.0 can accommodate different record lengths, depending on the author-specified length for the room name. It defaults to a room name length of 38 bytes, but a wide latitude of name lengths can be specified when the adventure is initialized, or later with the RESIZE FILES utility.
The allotted record space for room data cannot be so easily modified, but room data shares the same record with the room name. Thus it is quite easy to make more space for extra room data by specifying a longer room name than you really intend to use.
For a 10-direction adventure, you should specify a room name length that is at least 20 characters longer than you really intend to use. For example, if you plan to use the default 38-character name length, you should specify a name length of at least 58. Then you must remember not to let your room name run past the first line even though the editor shows that you have another half-line available.
Yes, this is a kluge fix, but it is very easy to implement. If you don't want to do something mickeymouse like this, you have two other options for 10-direction adventures:
1) Limit your room data to an average of 2 digits per room connection. As long as you don't exceed 20 digits (plus an additional 10 bytes for CR's), the data will fit very well within the standard record space.
2) Rework the DUNGEON INIT, EDIT, & LIST programs to accommodate the extra space. This isn't very difficult to do but then you must somehow make sure that no one ever runs a normal DDD on the adventure.
Rob opted for a modification of option #1. He reworked his room connections to use fewer bytes. But he also deleted the UP and DOWN directions from the database, which gave him an average of 2.75 bytes per direction to play with.
So how does one make a 10-direction adventure? The mods to the MAIN PGM are actually quite simple:
1) Add 4 to the number in the DATA statement at line 31910.
2) Add NE,NW,SE,NW to the command list at line 31920, between DOWN and GET.
3) At Line 290, immediately after the GOTO, add the number 3000 four more times, so that the line has 3000 a total of ten times, consecutively.
Next, you must modify the EAMON.NAME file by running this small pgm: 10 D$ = CHR$(4) 20 PRINT D$"OPEN EAMON.NAME" 30 PRINT D$"READ EAMON.NAME" 40 INPUT AN$: INPUT ND$: INPUT DV$ 50 PRINT D$"WRITE EAMON.NAME" 60 PRINT AN$: PRINT "10": PRINT DV$ 70 PRINT D$"CLOSE"
That's all there is to it!
The DEC'90 article on how to make a 10-direction had a bug in the small program that modifies EAMON.NAME. Here is the correct program:
10 D$ = CHR$(4)
20 PRINT D$"OPEN EAMON.NAME"
30 PRINT D$"READ EAMON.NAME"
40 INPUT AN$: INPUT ND$: INPUT DV$
50 PRINT D$"CLOSE"
60 PRINT D$"OPEN EAMON.NAME"
70 PRINT D$"WRITE EAMON.NAME"
80 PRINT AN$: PRINT "10": PRINT DV$
90 PRINT D$"CLOSE"
There are only two basic types of information in the room data: exits and light. Light has two values: (1) if the room is naturally lit, and (0) if the room is dark.
A normal Eamon adventure has 6 directions of travel: North, South, East, West, Up, and Down. When editing room data, you must supply an exit number for each of these directions: A (0) means that there is no exit in that direction. A (-99) signifies an exit to the Main Hall. Custom programming can be accomplished by using negative numbers; however, you must supply the programming for such special connections.
The last means of exiting a room is through a Door artifact. The exit number in the room data should equal the artifact number of the door plus 500. For example, if the door's artifact number is 21, then the exit number is 521. This tells the programming to consult Artifact #21 for more information about the exit.
And what about the door itself? First, you must decide if it is a normal door or if it is a secret door. If normal, you simply use the Room number for the door's location and answer "0" to the HIDDEN question. If it is a secret door, add 200 to the room's number for the location, and answer "1" to the HIDDEN question. But if it is hidden, then you must remember to mention it somehow in the room description, so the player will have a name to EXAMINE to make it appear in the room.
Be careful with the KEY question in the door menu. It presently defaults to 99, which means that you will need artifact #99 to use as a key to open it. If you have fewer than 99 artifacts, the program will crash. The KEY number should be set to the artifact number of the key that opens the door. If the door is unlocked, set KEY to zero.
Be sure to set the door's weight to 999. The MAIN PGM recognizes 999 as an impossible weight and responds "DON'T BE ABSURD" if the player tries to GET the door. If you don't do this, some bozo with a super-character will pick up the door and carry it off, which does not open the passageway but does ruin the adventure.
Set the door's strength to whatever you want it to be. This number is reduced by the damage hits inflicted when the player ATTACKs the door; when it reaches zero, the door shatters. If it is a flimsy door, set this number to something small, like 10. If it is armored, set the number very high, like 999.
Let's do an example of a door. Let's say that the door is artifact #5 and is a secret north exit from Room 3. The room beyond the door is Room 7. The door armored and locked, and its key is artifact #6, and is found in Room #2. This example underlines all typed input:
ROOM-2 ART.-4 EFF.-0 MONS.-0
YOUR CHOICES ARE-- 1. ADD NEW ROOM, ARTIFACT, EFFECT, OR MONSTER 2. (etc.)
ENTER KEY OF YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) R
ENTER ROOM NAME: END OF A N/S TUNNEL
ROOM DESCRIPTION: YOU HAVE REACHED THE END OF THE TUNNEL. IT IS BLOCKED BY A LARGE FLAT PANEL.
FOR EACH DIRECTION ENTER THE ROOM # THAT THIS ROOM CONNECTS TO: MOVE N ...505 (door - artifact #5) MOVE S ...(etc.)
ROOM-3 ART.-4 EFF.-0 MONS.-0
YOUR CHOICES ARE-- 1. ADD NEW ROOM, ARTIFACT, EFFECT, OR MONSTER 2. (etc.)
ENTER KEY OF YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) A
ENTER ARTIFACT NAME: PANEL
ARTIFACT DESCRIPTION: YOU DISCOVER THAT THE PANEL IS REALLY A STEEL DOOR!
TYPE : 8 (door/gate) VALUE : 50 (doesn't matter) WEIGHT : 999 (immovable object) ROOM : 203 (hidden in Room #3) ROOM BEYOND : 7 (connects to Room #7) KEY# : 6 (Artifact #6) STRENGTH : 999 (can't be broken down) HIDDEN? : 1 (secret door; 0 if not hidden)
ROOM-3 ART.-5 EFF.-0 MONS.-0
YOUR CHOICES ARE-- 1. ADD NEW ROOM, ARTIFACT, EFFECT, OR MONSTER 2. (etc.)
ENTER KEY OF YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) A
ENTER ARTIFACT NAME: STEEL KEY
ARTIFACT DESCRIPTION: YOU HAVE FOUND A SMALL STEEL KEY.
TYPE : 9 (key) VALUE : 1 (not worth much) WEIGHT : 1 (doesn't weigh much) ROOM : 2 (found in Room #2) USER #5 : (doesn't matter) USER #6 : (doesn't matter) USER #7 : (doesn't matter) USER #8 : (doesn't matter)
That's how it's done. Be sure to print out the manual. It has all this information and more in it, and you will find it a valuable reference.
The above example is not a complete printout of everything that you will see on the screen. There are quite a few on-screen menus during data input that list the allowable inputs, so that you don't have to memorize such things as the artifact type of a door. In fact, the menus almost cover such information better than the manual does.
The USER prompts seen with some types of artifact data input, such as the key above, are not used by the standard MAIN PGM programming. They are made available for the purpose of adding extra data for special programming. If you have not added any such extra programming, simply enter zero at each prompt (or hit Escape to retain the default value shown on the screen) and ignore them.
A container is any kind of artifact that can hold other artifacts inside of itself. Most containers are simple boxes or chests, but this artifact class also includes things like desks, lockets, sacks, and so on. In fact, anything can be used as a container if the story requires that it be able to contain or conceal other artifacts.
Containers may be closed or open, locked or unlocked. Their initial state is up to you. Once a container is unlocked or opened, it may not be closed again or relocked using the standard MAIN PGM programming. However, if the player puts an artifact into an open container, the container will "behave" as if it is closed, holding and concealing the artifact until the player again opens it.
Like doors, container key numbers default to artifact #99. You must change this number to the artifact number of the actual key or to zero. If you leave it as 99, then the player must have artifact #99 in his possession to open the container. If the adventure doesn't have 99 artifacts, the MAIN PGM crashes when the player tries to open the container.
Also like doors, containers have a Strength parameter that is in effect the container's "hardiness". If the player has no key, he can attack a locked container and wear down its strength until it reaches zero, at which time the container shatters and can be opened. Try to select a container description that fits the strength number that you choose. If the container is a lightly built wooden box then the strength should be around 10. If it is a massive iron-bound strongbox then the strength can be in the hundreds. Make some effort to have the container's description match its strength.
Let's do an example of a container. Let's say that the container is a small, stoutly built, locked wooden box that contains an emerald. The box is artifact #1, the key artifact #2, and the emerald artifact #3. The box will be found in room 1 and the key in room 7. This example underlines all typed input:
ROOM-0 ART.-0 EFF.-0 MONS.-0
YOUR CHOICES ARE-- 1. ADD NEW ROOM, ARTIFACT, EFFECT, OR MONSTER 2. (etc.)
ENTER KEY OF YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) A
ENTER ARTIFACT NAME: BOX
ARTIFACT DESCRIPTION: YOU SEE A SMALL WOODEN BOX. IT IS ORNATELY FINISHED IN DARK VARNISHES WITH SILVER INLAYS. YOU CAN SEE FROM ITS CONSTRUCTION THAT IT IS STOUTLY BUILT. THERE IS A SMALL KEYHOLE ON ONE SIDE.
VALUE : 5 (not worth much) TYPE : 4 (container) WEIGHT : 5 (not too heavy) ROOM : 1 (found in Room #1) KEY# : 2 (Artifact #2) STRENGTH: 50 (moderately strong) OPEN? : 0 (Open = 1; Closed = 0) USER #8 : 0 (doesn't matter)
ROOM-0 ART.-1 EFF.-0 MONS.-0
YOUR CHOICES ARE-- 1. ADD NEW ROOM, ARTIFACT, EFFECT, OR MONSTER 2. (etc.)
ENTER KEY OF YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) A
ENTER ARTIFACT NAME: STEEL KEY
ARTIFACT DESCRIPTION: YOU HAVE FOUND A SMALL STEEL KEY.
VALUE : 1 (not worth much) TYPE : 9 (key) WEIGHT : 1 (doesn't weigh much) ROOM : 7 (found in Room #7) USER #5 : (doesn't matter) USER #6 : (doesn't matter) USER #7 : (doesn't matter) USER #8 : (doesn't matter)
ROOM-0 ART.-2 EFF.-0 MONS.-0
YOUR CHOICES ARE-- 1. ADD NEW ROOM, ARTIFACT, EFFECT, OR MONSTER 2. (etc.) ENTER KEY OF YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) A
ENTER ARTIFACT NAME: LARGE EMERALD
ARTIFACT DESCRIPTION: YOU SEE A MARVELOUS LARGE EMERALD! IT HAS AN EXQUISITE COLOR AND WONDERFUL CLARITY. IT HAS BEEN CUT INTO AN OVALSHAPE WITH LARGE FACETS.
VALUE : 500 (valuable) TYPE : 1 (treasure) WEIGHT : 1 (doesn't weigh much) ROOM : 501 (inside Artifact #1) USER #5 : 0 (doesn't matter) USER #6 : 0 (doesn't matter) USER #7 : 0 (doesn't matter) USER #8 : 0 (doesn't matter)
That's how it's done. Be sure to print out the manual. It has all this information and more in it, and you will find it a valuable reference.
The above example is not a complete printout of everything that you will see on the screen. There are quite a few on-screen menus during data input that list the allowable inputs, so that you don't have to memorize such things as the artifact type of a key. In fact, the menus almost cover such information better than the manual does.
The USER prompts seen with some types of artifact data input, such as the key above, are not used by the standard MAIN PGM programming. They are made available for the purpose of adding extra data for special programming. If you have not added any such extra programming, simply enter zero at each prompt (or hit Escape to retain the default value shown on the screen) and ignore them.
Jun'91: Back to the Basics: Containers How to program and use; step-by-step examples
Mar'91: Back to the Basics: Rooms and Doors How to program and use; step-by-step examples
Dec'90: Using 10 Directions in Version 7.0 How to modify the MAIN PGM Pitfalls to watch for
Sep'90: Eamon Style and Technique: the Storyteller’s Craft Pointers on how to plot and write an Eamon adventure
Jun'90: Converting Eamon Adventures to ProDOS A step-by-step discussion of the procedure
Mar'90: Designing Descriptions for the 40/80 option How to write descriptions that look good in both 40 and 80-column formats.
Dec'89: Basic Eamon Routines Tips on modifying commands and on using the POWER and USE commands
Sep'89: Using Effect for Eamon Games with 7.0 How to make and use your own special effects
Jun'89: Traps and Obstructions Guidelines for proper design in order to ensure maximum player enjoyment
Mar'89: The Parameters Option Using this option to make special artifact types
Dec'88: Increasing free memory for large adventures Tips on how to make the MAIN PGM smaller
Sep'88: Programming efficiently for space and speed Tricks that make an Applesoft program run faster
Jun'88: Room Descriptions How to properly describe room exits to make the player's mapping effort more enjoyable
Oct'87: Handling monster groups Special routines for handling the friendliness of 'tribes' of monsters (from "Buccaneer!")
Jan'87: Initializing an adventure diskette A tutorial on how to generate a new adventure diskette
Jun'86: A description of the changes that were made going from version 6.0 to 6.2.
Oct'85: Putting Fun Stuff in Eamons 1) Using gates 2) Number conventions for extended 6.0 usage (also example code for DIG & WEAR commands) 3) Save Game feature 4) Some undocumented features (group monsters, poisons, truces)
Aug'85: Adding commands to the MAIN PGM Discusses an example EAT command
May'85: Things We'd Like to See in Eamon Pets, exhaustion, broken armor, SAY command much good discussion on pets
Mar'85: Guidelines for writing adventures Some good suggestions and guidelines, and a discussion of several inherent limitations of the Eamon MAIN PGM
Jan'85: dead bodies and magic A great discussion of magical effects
Oct'84: Doors, gates, and keys Locked doors for version 5.0, which didn't have key artifacts
Aug'84: Local Magic A few ideas for special stuff
May'84: A brief discussion of some Eamon stuff Eamon Master Diskette Basic monster and Artifact fields
Mar'84: Initializing a new adventure diskette
A "monster" in Eamon is defined as any animate denizen of the dungeon. This includes friends, foes, bystanders, people, wild animals, pets, and all other categories of creatures. The monster routines support weapon-carrying monsters, natural weapons such as claws and teeth, and unarmed monsters who can't fight until they are able to find a weapon.
Monsters can be individuals or groups. A group can be a pack of wolves, an orc patrol, a horde of locusts, or whatever. Groups are important; they permit the author to include many more monsters without filling up the database (which quickly uses up memory and disk space and makes the game run slower). Groups can also make the game play better, as it makes the list of monsters in the room much shorter. If you've ever played an Eamon in which there were 12 or 15 monsters in the room, then you know what I am talking about!
In version 7.0, a monster's fighting ability is determined by his Agility (AG) and his armor. The higher the Agility, the better he can fight. The weight of his armor lowers his fighting ability, but it also protects him. Lastly, his Hardiness (HD) defines how many hits he can take before he dies. Be careful not to select numbers that are too high. If the monsters are too strong then the player will keep getting killed out and will give up in disgust before he gets the chance to see all of your adventure. Here's a rule of thumb that isn't too far off: for the most difficult fights, a character with a fairly strong HEAL spell, chain mail and shield, and a 2D6 weapon should get killed no more than 50 percent of the time. Of course, this balance will be affected by whatever companions you have given the player by the time the confrontation takes place.
One item that seems to confuse many new authors is how to define the room location of an artifact that is a monster's weapon. The artifact's "room number" should be the negative of the monster's number, minus 1. For example, a weapon being carried by monster #5 should have a room number of (- 5 - 1) or -6. Also, a monster can carry any artifact, not just weapons, and you can start him out with as many as you please.
Let's do a few examples. First, lets do a generic sword, artifact #8, that our monster will carry. Next, let's do a simple orc, and let's make him monster #4. (NOTE: the following is not a complete printout of everything that you will see on the screen. There are quite a few on-screen menus during data input so that you don't have to memorize such things as the weapon type of a sword.)
ROOM-0 ART.-7 EFF.-0 MONS.-3
YOUR CHOICES ARE-- 1. ADD NEW ROOM,ARTIFACT,EFFECT, OR MONSTER 2. (etc.)
ENTER KEY FOR YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) A
ENTER ARTIFACT NAME: SWORD
ARTIFACT DESCRIPTION: YOU SEE A PLAIN IRON SWORD.
VALUE : 10 (not worth a lot)
TYPE : 2 (weapon)
WEIGHT : 5 (not too heavy)
ROOM : -5 (carried by monster #4)
ODDS : 10 (ordinary weapon)
W.TYPE : 5 (sword)
DICE : 1 (not a real good sword)
SIDES : 4 (not a real good sword)
ROOM-0 ART.-8 EFF.-0 MONS.-3
YOUR CHOICES ARE-- 1. ADD NEW ROOM,ARTIFACT,EFFECT, OR MONSTER 2. (etc.)
ENTER KEY FOR YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) M ENTER NAME: SMALL ORC
ENTER DESC-- YOU HAVE SURPRISED A SMALL ORC! EVEN THOUGH HE'S SMALL, HE'S MAD AS HECK AND HE IS READY TO TAKE YOUR HEAD OFF.
ENTER HD: 8 (he's pretty scrawny)
ENTER AG: 16 (he's pretty quick, though)
ENTER # MEMBERS: 1 (he's not a group monster)
ENTER COUR: 175 (he's fairly determined to kill you. A courage value of less than 100 makes him more likely to run away, and a value of more than 100 makes him more likely to chase you if you FLEE.)
ENTER ROOM: 14 (you'll find him in room 14)
ENTER WEIGHT: 80 (he's a little guy)
ENTER ARMOR: 1 (light armor)
ENTER WEAPON #: 8 (do NOT use neg. number here)
ENTER DICE: 1 (doesn't matter-he doesn't use natural weapons, so his dice and sides will be determined by the weapon he is carrying)
ENTER SIDES: "4• (doesn't matter)
ENTER FRIEND: "1• (an enemy)
OK, now let's do a group monster, a pack of rats. Remember that the data for group monsters is always that of just a single member of the group:
ROOM-0 ART.-8 EFF.-0 MONS.-4
YOUR CHOICES ARE-- 1. ADD NEW ROOM,ARTIFACT,EFFECT, OR MONSTER 2. (etc.)
ENTER KEY FOR YOUR CHOICE (1-7) 1
DO YOU WANT TO ADD A ROOM, ARTIFACT, EFFECT, OR MONSTER (HIT KEY, RAEM) M
ENTER NAME: RAT (always use singular name)
ENTER DESC-- THE ROOM IS CRAWLING WITH RATS!
ENTER HD: 1 (easy to kill with one blow)
ENTER AG: 20 (fast and hard to hit)
ENTER # MEMBERS: 18 (18 rats in the pack)
ENTER COUR: 30 (a bunch of little cowards)
ENTER ROOM: 22 (you'll find them in room 22)
ENTER WEIGHT: 1 (real small)
ENTER ARMOR: 0 (none)
ENTER WEAPON #: 0 (natural weapons--teeth)
ENTER DICE: 1 (these values are used here)
ENTER SIDES: 2 (a single rat bite isn't that dangerous)
ENTER FRIEND: 1 (another enemy)
That pretty much covers basic data entry. If you keep your weapons straight and pick the right numbers for good balance in the fighting, you've got it nailed down. Be sure to print out the manual! You will find it a valuable reference when plotting and populating your dungeon.
Think long and hard before using dead bodies in your adventure. It is not an error that the 7.0 DDD comes with dead bodies disabled with a REM! Only very rarely do dead bodies do anything but take up tons of valuable memory and disk space and slow down the program execution. Dead bodies complicate late data additions while fine-tuning your adventure. And they are very difficult to do that read well with group monsters. Really, the only time that bodies are worth implementing is if you want to use their descriptions to print death scenes when monsters die. But if all you have to say is YOU SEE A DEAD MONSTER, then your adventure will be much better without them.
One feature of modern Eamon adventures is the ability to "embed" artifacts in room descriptions. Such embedded artifacts do not appear in the room until the player examines them, at which time they are converted from "embedded" to "normal".
The biggest drawback of embedded artifacts is that the artifact's name must correspond almost exactly with the name used in the room description. This is often difficult to accomplish in a way that reads well. For example, if there is a secret hidden trapdoor in the floor, the room description can hardly say so! This difficulty could be gotten around in older Eamon versions by making the trapdoor a "hidden" artifact that would appear in the room when the player did a LOOK command, but version 7.0 does not support "hidden" artifacts.
The solution for this problem in version 7.0 was the implementation of the SYNONYMS routine at line 4600. This routine has been designed specifically to identify embedded artifacts that may have names that are drastically different from the one in the room description.
Let's look at an example of a synonym and how it is handled by the routine. We'll use that hidden trapdoor that I mentioned before, and let's say that it is Artifact #17 and is located in Room #21, and its name is SECRET TRAPDOOR.
First, the room description:
THIS ROOM IS LONG AND NARROW, WITH A HIGH CEILING. THE WALLS ARE LINED WITH MOUNTED ANIMAL HEADS. THERE IS AN ORNATE RUG CENTERED ON THE FLOOR. THERE IS A BUMP IN THE RUG NEAR ONE CORNER.
Now, let's generate the lines for the Synonym Checker:
4610 SL = LEN (S$)
4620 IF RO = 21 THEN SY$ = "RUG": SY = 17: GOSUB 4680
4630 IF RO = 21 THEN SY$ = "BUMP": SY = 17: GOSUB 4680
4680 IF LEFT$ (SY$,SL) = S$ OR RIGHT$ (SY$,SL) = S$ THEN S$ = A$(SY): POP
S$ is the "object" that the player is examining SL is the length of the object name that the player typed RO is the Room that the player is in SY$ is a synonym for the object SY is the artifact number tied to the synonym
My example sets up two possible synonyms for the secret trapdoor: RUG and BUMP. Let's examine the routine on a line-by-line basis:
4610 finds the length of the object name the player typed in.
4620 checks to see if the player is in room 21. If he is, it passes the synonym name RUG and the artifact number of the secret door (which is artifact #17) to the compare subroutine at 4680.
4630 is the same as line 4620 but for the synonym BUMP.
4675 exits the synonym routine if no synonym match was found.
4680 compares the synonym SY$ to the object S$. If a match is found, it changes the object name to the name of the synonym and POPs the subroutine stack to avoid returning to the synonym checker.
4690 exits the compare subroutine. If no match was found, it RETURNs to the synonym checker in case there are multiple synonyms in the room. If a match was found, it RETURNs to the routine that called the synonym checker.
In my example, there are two possible synonyms in the room, RUG and BUMP. The command EXAMINE RUG would execute these lines: 4610, 4620, 4680, 4690. The command EXAMINE BUMP would execute these lines: 4610, 4620, 4680, 4690, 4630, 4680, 4690. As you can see, the number of lines executed goes up rapidly with each synonym that is added. This is why the room number RO is checked in 4620 and 4630; if the player is not in room 17 then the lines executed for either command would be: 4610, 4620, 4630, 4675. This avoids wasting time checking for synonyms that aren't even in the room.
Even though my example uses just two synonyms, you can add as many as you want. There is room for 69 synonyms without renumbering the routine, and as many as 94 if you renumber.
The synonym checker is a great tool and I strongly recommend that you take advantage of it.
A Temporary variable and counter
A$ String read in from EAMON.DESC Full command typed by player Name of Art. being PUT or GIVEn
A$(*) Artifact names
A%(x,y) Artifact data; 'x' is Art. number; (see below for values of 'y')
A2 Temporary variable and counter
AC Armor Class of armor brought by player from Main Hall
AE Armor Expertise; affects combat odds
AR Artifact number of ARmor being worn
B FAST.START parm byte; used to compute if FAST.START file is valid.
B$ Name of Monster being GIVEn to Name of Monster being REQUESTed from Name of Artifact being PUT
B% Ampersand Integer array search variable used to pass the last location to be searched to the ampersand routine Temporary variable.
BA Money in BAnk
BV$(*) Attack Verbs used during melees
C Command array number of current command
C% Ampersand search routine Counter
C$(*) Command verb array
CC Line counter for printing valid commands
CH Player's CHarisma
CP Number of Columns of display (40 or 80)
CZ$ Command given in last round of play
D Temporary variable Direction being moved (123456 = NSEWUD) Number of dice for combat resolution
D$ CHR$(4) for DOS
D% Value to be searched for by Ampersand Integer array search routine
D2 Damage points taken by Defender in combat
D3 Counter variable
DF Monster number of DeFender in combat
DI "DIe" flag-set to 1 if player is killed
EA Armor Expertise weighting factor
ED$ String: "EAMON.DESC"
EM "EMbedded" location--see below
ER$ String: "EAMON.ROOMS"
F "Found" flag--see below F(*) Total hits taken in combat:
F(1) = enemies in room F(3) = player and friends in room
F1 Low byte of top of free memory before string is read in from EAMON.DESC
F2 High byte of top of free memory before string is read in from EAMON.DESC
FF$ Form Feed character CHR$(12) required by Videx 80-column cards
FR Temporary variable used to compute FRiendliness of newly met monsters
G Monster number of Guard of bound monster
GO Player's GOld
HA "HAve" (being carried) location--see below
HI "HIt" flag-set to 1 if defender has been hit in combat
HM "HIMEM" variable; used to compute if FAST.START file is valid K Temporary variable used when attacking artifacts and freeing bound monsters
L Line counter for screen pause
LA Length of records in EAMON.ARTIFACTS
LK Temporary flag variable-set to 1 if INVENTORY finds artifacts being carried or if OPEN finds artifacts in a container
LL Number of lines in string read in from EAMON.DESC
LM Length of records in EAMON.MONSTERS
LR Length of records in EAMON.ROOMS
LS Artifact number of artifact being carried that is current Light Source
LT LiT Room flag-set to 1 if room is lit M Temporary counter variable
M$ Monster name being searched by array search routine at 4700
M$(*) Monster names
M%(x,y) Monster data; 'x' is monster number; (Monster '0' is the player)
M%(x,0) 'Seen' flag
M%(x,3) # of members in group
M%(x,5) Room number
M%(x,6) Weight (not currently used)
M%(x,7) Armor thickness
M%(x,8) Weapon number
M%(x,9) Number of dice (natural weapon)
M%(x,10) No. of dice sides (natural weapons)
M%(x,12) Original size of group
M%(x,13) Damage or hits taken
M2 Temporary variable and counter
MC Counter for group Monsters during combat
MR% Number of monsters that flee from combat
NA Number of Artifacts (including those brought by player from the Main Hall)
NC Number of valid Commands
ND Number of valid Directions
NE Number of Effects
NL Flag set to 1 if room is Naturally Lit
NM Number of Monsters
NR Number of Rooms
NX Number of eXits from room NZ Number of artifacts in database (not including those brought by player)
OF Monster number of attacker in combat
Q Temporary variable used in GIVE, PUT Q$ Temporary input string used in GIVE, PUT
R Record number to be read in from EAMON.DESC Temporary random number
R2 Number of room being moved to
R3 Number of room last moved from
RB$(*) Verb that describes non-hit attack result RD%(*) Array containing exits from room
RE REcord number of player character in CHARACTERS file on Main Hall disk.
RL Temporary random number; temporary variable
RN$ Room Name of present room
RO ROom number of present room S Number of dice Sides used to compute damage in combat Array location of Spell data for spell being cast
S$ Subject (object) of command
S2%(*) Current level of Spell abilities
SA%(*) Absolute level of Spell abilities
SE$ SEx of player character
SH Artifact number of SHield being worn SL Temporary variable used for
S$ String Length during array searches.
SM$(*) SMILE response verbs
SP SPEED spell counter until expiration
SU Flag set to 1 if spellcast was SUccessful
SX Temporary variable used when ATTACKing artifacts
SY Artifact number of SYnonym
SY$ Name of SYnonym
T(*) Total hardiness of combat groups:
T(1) = enemies T(3) = friends
TA Flag set to 1 to tell ATTACK code that it is handling a BLAST spellcast
TP Total value of loot sold at end of game
UP Flag to increase weapon ability
V$ Command Verb
V%(*) 'Seen' flag for rooms
W Weapon number of player Counter at end of game for player's Weapons
W2 Complexity of readied Weapon Counter used at initialization to search for duplicate artifact names Number of Weapons carried by player at end of game
W5 Input variable for Weapon number that player is selling at end of game.
WA%(*) Player Weapon type Abilities
WD%(*,*) Weapon Data for weapons taken back to the Main Hall
WH "WHere" location--see below WM Computed odds of achieving a hit during combat
WP$(*) Names of all Weapons being carried by layer at end of game
WP%(*) Artifact number of all Weapons being carried by Player at end of game
WT Combined WeighT of all artifacts being carried by player
X Temporary variable and counter
Z Number of artifact that is being PUT
'Seen' flags These variables tell the YOU SEE routine whether it should print the long description of the room, artifact, or monster. If the 'Seen' flag is zero, the description is printed.
Search Routine Variables The variables EM, HA and WH are used by the various command routines to pass location search parameters to the artifact array search routine at 4800 and the monster array search routine at 4700. The default values for these are:
EM <EMbedded> Room number + 200 HA <HAve it> - 1 (carried by player) WH <WHere> Room number
For example, the EXAMINE command would use these defaults, in order to look for artifacts in the room, both seen and unseen, and carried by the player. But the DROP command will set all three of these to (-1) so that only artifacts being carried by the player will be found by the search routine. The GET routine sets HA = WH so that the player can't GET something that he is already carrying.
When the search routines at 4700 or 4800 have completed their search, they set the variable F = 1 if an artifact or monster is matched to the object specified by the player's command, but set F = 0 if no match was found;
Artifact Arrays The first five array locations of all artifacts are identical: A%(x,0) 'Seen' flag A%(x,1) Value A%(x,2) Type A%(x,3) Weight A%(x,4) Location
There are ten different formats for the next four array locations, depending on what the artifact type is:
Type 0 (Gold), 1 (Treasure): A%(x,5) Not used A%(x,6) Not used A%(x,7) Not
used A%(x,8) Not used
Type 2 (Weapon), 3 (Magic Weapon) A%(x,5) Weapon type A%(x,6) Complexity A%(x,7) Number of dice A%(x,8) Number of dice sides
Type 4 (Container) A%(x,5) Artifact number of key A%(x,6) Strength A%(x,7) Set to 1 if open A%(x,8) Not used
Type 5 (Lightable) A%(x,5) Counter until extinguished A%(x,6) Not used A%(x,7) Not used A%(x,8) Not used
Type 6 (Drinkable) A%(x,5) Healing amount A%(x,6) Number of uses A%(x,7) Set to 1 if open A%(x,8) Not used
Type 7 (Readable) A%(x,5) Record number of 1st Effect A%(x,6) Number of Effects to print A%(x,7) Set to 1 if open A%(x,8) Not used
Type 8 (Door/Gate) A%(x,5) Number of room beyond A%(x,6) Artifact number of key A%(x,7) Strength A%(x,8) Set to 1 if hidden
Type 9 (Key) A%(x,5) Not used A%(x,6) Not used A%(x,7) Not used A%(x,8) Not used
Type 10 (Bound Monster) A%(x,5) Monster number when freed A%(x,6) Artifact number of key A%(x,7) Monster number of Guard A%(x,8) Not used
Type 11 (Wearable) A%(x,5) Armor class (not implemented) A%(x,6) Type (not implemented) A%(x,7) Not used A%(x,8) Not used
That pretty much covers all of the variables. See the DDD manual for more information.
ProDOS NOTE: Most of the DOS 3.3 MAIN PGM Init code at 31000 and 33000 is broken out into a separate program named MAKE.FAST.START. The MAIN.PGM uses the FAST.START VAR file generated by this program to save memory and for much faster startups. Once you have entered your data, run MAKE.FAST.START before testing the adventure.
Also note that ProDOS adventures as distributed by the EAG do not usually contain the data files EAMON.ARTIFACTS nor EAMON.MONSTERS. This data is contained in the FAST.START file. If you want to edit or list the adventure data, first run the program MAKE.ARTS.MONS to generate the two missing data files. If you make a change to the artifact or monster data, be sure to rerun MAKE.FAST.START when done to update the FAST.START file.
I get a fair number of calls and letters from people who are having problems with an Eamon. Often, the fix is something very simple that anyone can do, if they know what to look for.
Problem: The adventure is doing something that doesn't make sense, or is
Fix: Check the revision date in the adventure's catalog. Compare the date on your disk with the revision date listed in this newsletter (a DOS 3.3 list was in the last issue, and a ProDOS list is in this issue). If the date does not agree, check the EAG back issues from around the time of the revision date and look for a bug fix that has the same problem you are seeing.
If you don't see anything that will help, proceed with the various procedures outlined in the rest of this article.
Problem: WRITE PROTECTED error
Files are written to on both the Master and the adventure disks. You must not cover the write enable notch with a write-protect tab.
If the adventure is written to the back side of a disk, it may be that the write protect notch was improperly punched.
Fix: If the write-protect notch is covered, remove the Write-protect tape from the edge of the disk. If the adventure is on the back side of a disk, repunch the notch or else copy the adventure to the front side of another disk.
Problem: DISK FULL error This error usually occurs when trying to SAVE a DOS
3.3 version of the game. Many of the better Eamon adventures do not have DOS 3.3
on the disk, because they require every possible bit of disk space. You will get
this error on these big Eamons if you make a copy of the disk by using the DOS
INIT command and copy the adventure over to the new disk file-by-file. INIT
automatically installs a copy of DOS 3.3 on the disk.
Fix: Make Eamon adventure copies with Copy II+, using the "disk" option, or else use COPYA from the DOS 3.3 Master.
NOTE: If you get a DISK FULL error while saving a game, immediately delete the files GAME.STR, GAME.SVAR, & GAME.PTRS (DOS 3.3) or SAVED.GAME (ProDOS). There is a danger that the disk catalog will be corrupted if you don't do so.
Problem: I/O ERROR This error can not be caused by a bug in the adventure. Your disk is bad.
Problem: PROGRAM TOO LARGE This error can not be caused by a bug in the adventure. It can only occur if the adventure's MAIN PGM has become corrupted. Note that your disk might be good, but was copied from a bad disk that contained the original error.
You might also get this error in very large Eamons if you have any extra stuff resident in memory such as Program Writer.
SYNTAX ERROR IN XXXX
NEXT WITHOUT FOR ERROR IN XXXX
RETURN WITHOUT GOSUB ERROR IN XXXX
ILLEGAL QUANTITY ERROR IN XXXX
UNDEF'D STATEMENT ERROR IN XXXX
BAD SUBSCRIPT ERROR IN XXXX
DIVISION BY ZERO ERROR IN XXXX
TYPE MISMATCH ERROR IN XXXX
These are genuine program bugs. Please follow these steps immediately after the crash, before typing anything else and before contacting the EAG with a bug report:
1) Write down the line number (XXXX)
2) Type LIST XXXX (XXXX = the line number)
3) The offending program line will be printed to the screen. It will contain a number of variable names, such as RO, M, AD%(A,4), etc.
4) Type PRINT statements for each of the variables in the bad line. PRINT RO PRINT M PRINT AD%(A,4) (Note that this includes the variable A which must also be printed) PRINT A (etc.)
5) Each time you type in a PRINT statement, the value of that program variable will be printed to the screen. Write down all this info. It is virtually impossible to fix obscure bugs without full knowledge of what the bad program line was doing.
6) It will be very helpful if you write down a detailed description of where you were in the dungeon and what you were doing at the time the error occurred. Please include the revision date of the disk and where you got it. It is possible that your supplier's disk became bad somehow and must be replaced; I will send them a replacement if I make this determination.
Problem: When trying to "go on an adventure", the Main Hall program goes
crazy, printing out all kinds of stuff without waiting for you to type anything.
Fix: The FRESH MEAT file on the adventure disk is locked. Unlock the file with the command
(DOS 3.3): UNLOCK FRESH MEAT
(PRODOS): UNLOCK FRESH.MEAT
Problem: FILE LOCKED error when trying to save the game.
Fix: The Saved Game files on the disk are locked. These files are written to when the game is saved and must be unlocked. Type:
Problem: REDIM'D ARRAY ERROR IN XXXX
This is really a totally different bug that is being masked by sloppy programming. It happens when the adventure doesn't bother to disable the ONERR GOTO jump after checking for a saved game (this was a bug in the original version 5 SAVE routine and is common).
Check and modify the saved game verification code in the program named MAIN PGM. It will be at lines 10-50 on most Eamons. The line numbers may be different in some Eamons; the first line will contain an ONERR GOTO statement.
If there is no POKE 216,0 in Line 20, add one just before the GOTO statement. There are several variations on this line; here's one example of the original line:
20 DK$ = CHR$ (4): PRINT DK$"VERIFY GAME.PTRS": GOTO 29000 Change it to:
20 DK$ = CHR$ (4): PRINT DK$"VERIFY GAME.PTRS": POKE 216,0: GOTO 29000
There are many variations of this line in different Eamons. In the above example, I didn't change anything except to add the POKE statement. That's what you should do.
If there's no POKE 216,0 in line 50, you should add one to the front of the line:
Change: 50 GOTO 1000
to: 50 POKE 216,0: GOTO 1000
NOTE: As stated above, this error message is not the real problem. Once you add the POKE 216,0 statement, the adventure will still crash at the same point. But after the POKE has been added, you will get the correct error message.
Problem: When restarting a saved game, it immediately tries to again do a
Fix: The DOS 3.3 Eamon SAVE routine does not want you to hit the <Return> key when answering the question "DO YOU WANT TO RESTART THIS GAME?" If you answer this question with "Y <Return>", the "Y" is taken and the <Return> is left in the keyboard buffer to be taken as the first command. And since the last valid command was the SAVE command that saved off the game, it tries to save the game again.
When playing DOS 3.3 Eamons, do "not• hit the <Return> key when answering "Y" to the "RESTART THIS GAME" question. If you forget and do it by mistake, simply answer "N" when asked "DO YOU WANT TO SAVE THIS GAME?"
ProDOS note: this "feature" causes so much trouble for new Eamon players that all ProDOS versions "do• require that you hit the <Return> key when answering Save/Restart game questions.
Warning: Any time you modify the MAIN PGM, a DOS 3.3 saved game will be dangerously unplayable. If you try to restart it, you will see bad room names and other weird stuff, and it will soon crash with a corrupted program in memory. Never, ever save the MAIN PGM to disk after seeing such a weird crash. This is one way that the corrupted MAIN PGMs mentioned in one of the above problems come about.
ProDOS note: unlike DOS 3.3, it is OK to restart ProDOS saved games after modifying the MAIN.PGM.
Problem: OUT OF MEMORY
Fix: This error does not mean that you have run out of free memory. This error is also printed when something called a "stack overflow" occurs. Some Eamon adventures occasionally experience stack overflows because they were written using very poor programming practices.
Normally you can immediately restart the adventure by typing this line at the keyboard:
Sometimes it will crash a second time. Just type it in again. ________________________
If you do find a genuine problem, please follow the steps outlined for SYNTAX ERROR above. I get an astonishing number of letters that say, "I bought your Eamon game, (name), and it crashes. What are you going to do about it?" Obviously, I can't do anything with that except write them back with some suggestions about bug reporting.
While the version 7.0 MAIN PGM has a fairly complete basic command set, sometimes you need to add extra commands to get the play that you desire.
Let's set up a simple example and then step through the procedure. Let's say that part of the quest requires that the player be able to TALK to a certain denizen of the dungeon. This scenario needs to have the command TALK added to the command list. For the sake of simplicity in this example, let's say that only one monster actually has something to say, and that this is monster #12. Let's make this monster's comments Effect #6. The required syntax for this command will be TALK (MONSTER).
First, let's write the code for the new command:
35000 REM TALK
35010 GOSUB 4900: GOSUB 4700: IF NOT F THEN 96
35020 IF M = 12 THEN R = 406: GOSUB 45: GOTO 98
35030 PRINT: PRINT "YOU EXCHANGE ";
35040 IF M%(M,11) = 1 THEN PRINT "INSULTS."
35050 IF M%(M,11) > 1 THEN PRINT "PLEASANTRIES."
35060 GOTO 98
Let's examine this, statement by statement:
35010: GOSUB 4900 (Check to make sure that a specific object has been named in the command.) GOSUB 4700 (Find out if the Monster named is in the room, and what his number is in the monster database.) IF NOT F THEN 96 (If the routine at 4700 cannot find a match between the object and the name of any monster present in the room, it returns with F = 0. If no match was found, jump to line 96, which prints NOBODY HERE BY THAT NAME!)
35020: IF M = 12 THEN R = 406 (If the routine at 4700 finds a match, it returns with M = the monster number. In our example, the only monster that has anything to say is monster #12. Effects are stored in EAMON.DESC at records 401-600. Effect #6 is record #406.) GOSUB 45 (This is the routine that gets text from EAMON.DESC and prints it.) GOTO 98 (Exit the routine. This exit prints a blank line and updates the screen pause line counter.)
35030: PRINT: PRINT "YOU EXCHANGE "; (Print this text when M does not equal 12 so that the player gets a response to his command.)
35040: IF M%(M,11) = 1 THEN PRINT "INSULTS." (If the monster is an enemy.)
35050: IF M%(M,11) > 1 THEN PRINT "PLEASANTRIES." (If the monster is not an enemy.) ˙
35060: GOTO 98 (Exit the routine. This exit prints a blank line and updates the screen pause line counter.)
OK, that is our new command. Now we have to integrate it into the command list. The number of basic commands (32) is stored at line 31910, and the commands are listed at line 31920. To add TALK, we must increase the number at 31910 by one and add the command at line 31930:
31910 DATA 33
31930 DATA TALK
TALK will now be listed as the very last command in the command list and will be recognized by the command parsing routine at line 200. The only thing left to do is to add the line number of the routine to line 290 so that the command parser will know where it is:
290 ON C GOTO 3000,3000,3000,3000,3000,3000, 4000,5000,6500,6000,7000,8000,9000,10000, 11000,12000,13000,14000,15000,16000,23000, 17000,18000,19000,20000,21000,22000,24000, 25000,26000,27000,28000,35000
Note that the numbers in line 290 must be in exactly the same order as the commands in lines 31920-31930!
That's it! We now have a working TALK command!
OK, that covers new commands involving monsters. The code for commands involving artifacts is much the same, except that the artifact search routine is at 4800 instead of 4700, and the routine at 4800 has several entry points. Let's look at the differences from the above code. It's identical except for the GOSUB 4700. The artifact search routine compares to three "locations": HA, WH, and EM. The defaults are:
HA = - 1 (held by player) WH = RO (visible in room) EM = RO + 200 (embedded in room)
GOSUB 4801 if the player must be holding the artifact for the command to work. (eg: DROP).
GOSUB 4804 if the command works whether the artifact is being held, is in the room, or is still embedded in the room (eg: EXAMINE).
HA = RO: GOSUB 4805 if the artifact must be in the room or embedded in the room but not held by the player (eg: GET).
HA = - 999: EM = HA: WH = HA: GOSUB 4810 You can also define your own special "locations" to be checked. The example above is from the REMOVE command, which requires that the artifact to be acted on be worn by the player (- 999). This can be any number that you choose to use. _____
There are several optional exits from your routine. The two main ones are:
GOTO 98 prints a line, increments the line counter by three, and proceeds to the monster melee code at 300.
GOTO 99 is the same as GOTO 98 except that it proceeds to the YOU SEE code at 100 instead of the monster melee code.
If the routines at 4700 and 4800 do not find a match to the object and return with F = 0, you have several optional exits:
GOTO 91 "YOU AREN'T CARRYING IT."
GOTO 92 "YOU MUST FIRST OPEN IT."
GOTO 94 "YOU CAN'T (player's command) (eg: YOU CAN'T WEAR TABLE)
GOTO 96 "NOBODY HERE BY THAT NAME!"
If none of these four error messages quite fit your new command, you can use your own error message and exit through a GOTO 98 or GOTO 99.
Let's recap by looking at some examples from the regular commands:
5010 GOSUB 4900: IF S$ = "ALL" THEN 5100
5030 GOSUB 4801: IF NOT F THEN 91
6010 GOSUB 4900: GOSUB 4804: IF NOT F THEN 6040
6040 GOSUB 4700: IF NOT F THEN PRINT "YOU SEE NOTHING SPECIAL": GOTO 98
4010 GOSUB 4900: IF S$ = "ALL THEN 4200
4020 HA = RO: GOSUB 4805: IF NOT F THEN 94
26010 GOSUB 4900: HA = -1: WH = RO: EM = - 999: GOSUB 4810: IF NOT F THEN 94
7020 GOSUB 4900: GOSUB 4700: IF F THEN 7300
7030 HA = RO: GOSUB 4805: IF NOT F THEN 94
In the past year, there has been some difficulty and bad feelings caused by misunderstandings between myself and one or two new Eamon authors. The problems could have been completely averted if we had each done a better job of communicating our opinions and plans. So it seems well past time for me to discuss the subject of new adventure evaluation:
1) Sometimes a new author will write me and ask for help in setting up this or that special event that he wants to use in the adventure he is working on. Usually, the description of the proposed special event is very vague and doesn't begin to give me enough details or even an overview of the play behind the special event.
I can't properly help you unless you give me a detailed description of what you want to do and why. More often than not, the author's original idea is either extremely difficult to implement or will never be seen by anyone because it requires obscure actions by the player. But if I have enough details, I can almost always come up with modifications that are reasonably easy to program and will be seen by the player.
For example, I once received an adventure that had an enormous amount of special programming that only kicked in if the player character had a certain name. I'm sure that you can see that the author hadn't thought this aspect out very rigorously. It was a rather mundane adventure as originally submitted, but once modified to work for all players it became an excellent play.
Bottom line: be very specific in your requests for help. Always include a disk copy of your incomplete adventure. I am more than happy to help you work out special programming ideas, if you do all you can to enable me to see what you want.
2) The steps that I follow when working with new adventures are these:
a. A new adventure is submitted for assistance and/or evaluation
b. I look it over and playtest it. I return an overview of my opinion of how it plays and a critique that lists plusses and minuses of the adventure, and any problems that I see.
Generally the list of minuses is much longer and more detailed than the list of plusses. Don't get shook by this; it doesn't mean that I think that the adventure stinks. It's because the plusses are already OK, but the minuses need additional work to improve the adventure.
I will answer questions about special programming if I can figure out what the author wants to do. If I can't figure out what he wants to do, I'll ask for clarification. If he wants to do something that is very difficult to program, I'll explain the problems and recommend modifications to the idea, or may even recommend that the idea be scrapped. If a disk was included, I will sometimes go ahead and make the program mods myself and return the disk.
c. After the critique is returned to the author, I sit back and wait for him to respond with comments or a modified disk. I DON'T DO ANYTHING MORE UNTIL THE AUTHOR RESPONDS.
d. When I get a letter or new disk, I go back to step (b.) above. If I see more problems or if more modifications are requested/required, I will again wait for a response.
e. Once the author is satisfied with the state of the finished adventure, it is assigned an adventure number and released to the public domain outlets.
Comment: The bad feelings mentioned at the beginning came about because of mistaken notions about my methods. I returned a critique listing problems, and never heard from these people ever again. Meanwhile, they were waiting for me to go ahead and release their adventures. A year went by. When I got around to noticing that I had never heard from them, the responses that I got were very hot. One author assumed that I was ordering him around and refusing to release his adventures unless he rewrote them to my specifications. NOT SO!
Let's set some ground rules here. If someone sends me a buggy adventure that has loads of bad room connections and database errors that cause fatal crashes, I am not going to spend a lot of time working on the adventure, since the author obviously didn't. Usually about the fifth time it crashes or sends me to the wrong room, I quit and send a list of the problems that I saw to that point. But you must understand that I can't in good conscience release an Eamon that crashes every 50 moves.
There's no question that debugging an Eamon adventure gets old real quick. But if the author is too lazy to fix common database errors, I am not going to spend a dozen hours doing it for him. If you really and truly don't know what you're doing wrong, write and ask for help. I'll be very happy to teach you how to recognize and fix the database errors.
Any time I get an adventure that has lots of badly-written text, full of line-break, grammar and spelling errors, I always point out that such errors seriously detract from the adventure and tend to downrate it by two or three points. You don't have to fix them if you don't want to, but I won't do it, either. I am willing to release it in this condition if you want me to. If you are happy with a (4) rating when you might have gotten a (7), who am I to argue?
IT'S OK TO DISAGREE WITH ME. If you disagree with any of my criticisms, don't hesitate to tell me that I'm all wet. This is your adventure, and we will do it your way. I only offer suggestions, not orders from On High.
Sam Ruby and I strongly disagree on several aspects of Eamon gaming. The correspondence that we have exchanged over the years while calling each other idiots probably makes a stack two or three inches high. But Sam learned from this, and has evolved his style to accommodate differing tastes in adventuring without compromising his vision of how his adventures should work. I think that we all agree that Sam writes the best Eamons we will probably ever see.
Some people think that I have no right to criticize their adventures. If they feel that way, all they have to do is tell me to butt out and release it "as-is". I'll do it. But I have been directly involved in the development of 60 or 70 Eamons. I've played all 224 Eamons plus another half-dozen that were never released. People send me Eamon ratings and often describe what they like and don't like. I've been involved in numerous arguments about how an Eamon adventure should work and have developed an appreciation for differing tastes.
It used to be that I had a stable of knowledgeable playtesters and we got multiple assessments of new Eamons. But one by one they dropped out, and presently no one is testing Eamons but me. If you think that my critiques are rough, then you've never seen one from Pat Hurst! It's a very humbling experience to send a "finished" Eamon to Pat and get back a list of 130 problems, like Pat did with one of my own Eamons. Pat took no prisoners, but he was always right. I give him a great deal of credit for the quality of many of the high-rated Eamons, and for much improvement in myself, Sam, and Nate Segerlind, among others.
Bottom Line: It comes down to this. We will offer criticism and suggestions, but we will do things your way. All you have to do is tell us! We are willing to release Eamon adventures with screwed-up text and plot problems, if you want us to do so. We will not release Eamons that crash because of serious database and programming errors. Likewise, I'm not likely to release a 10-room, 2-monster Eamon (yes, I have received such).
I have modified Main Halls coming out of my ears. There's no market for new Main Halls, but it seems like everybody does one because it is a lot easier than writing a real Eamon adventure. (NOTE: if you are interested in collecting modified Main Halls, please let me know! I have a reason for asking.)
It's my experience that the quality of an Eamon adventure is very closely related to the amount of time that the author is willing to put into it, polishing and spiffing until it is right.
This ability comes slow at first but improves with practice. My first adventure is also my highest-rated one, but I spent hundreds of hours over a period of months getting it to that state. The MAIN PGM went through over 140 significant revisions before release, with each revision encompassing dozens of modifications and a complete play-through. I certainly don't expect you to do that. But it's a truism that the quality of an Eamon is directly related to the amount of playtesting that was done. Think about it.
Here is a grab-bag of thoughts and techniques that I have used in writing my own Eamons.
Before you begin data entry for your new Eamon adventure, plan as much of the map as you can. Actually draw a free-hand map on paper. Once the map is drawn, mark it into individual "Eamon rooms". Plot where puzzle clues, puzzle solutions, special effects, plot development, secret doors, etc. will go. Assign as many monsters and artifacts as you can. Make copious notes on how each part of your adventure should work. Nothing clears your head like writing it down! The more you get straight at this point, the easier your adventure will be to construct.
Reason out now how your special events will work. Decide how the event will be triggered. What the player will see. How it will affect everything that may be in the room. Work out as many details as possible, or else you may discover later that your all-important special event is impossible to implement.
For example, suppose that you envision a sentry who will sound the alarm if he happens to spot you. You may decide that the only way the alarm can be safely avoided is for the player to shoot him with an arrow before he enters the room occupied by the sentry.
Well, we have a few problems here. The player won't know that the sentry is there until after he enters the sentry's room, when it will be too late. If he is somehow informed that there is a sentry in the next room, he won't be aware that the sentry can be killed from a distance. Informing him that this can be done, and how it can be done, has the potential of making this a very klunky and unsatisfactory special event.
I solved this exact special event in "Assault on Dolni Keep" by making it a certain companion's decision and job to shoot the sentry without any intervention on the player's part. I executed this with Effects that were triggered by entry into the adjacent room. And when the sentry's room is entered, his arrow-shot body is found on the ground at the player's feet. If I do say so myself, this particular event reads and plays well enough. But if I hadn't planned this in advance, I might have been forced to delete the sentry from the scenario, which would have made it much less believable.
I find that the adventure is less difficult to build and execute if you separate the map and plot into several sections that can be entered and largely debugged section-by-section. Any problem is easier when it can be broken into smaller pieces which can be solved individually. adventure writing is no exception to this rule.
I tend to enter the data for each section, and playtest and debug just that section before entering the next one. Then once the entire adventure has been entered and each section debugged, I can concentrate on debugging any problems that appear when playing the entire adventure at once.
Once you have completed data entry, use DUNGEON LIST 7.0 to print out your entire database. Print rooms, monsters, artifacts, and effects. Use these printouts to cross-check for errors. Believe me, you will find many things to fix! Skimping on a bit of printer paper at this point will make it just that much harder to straighten out the inevitable errors. Once you have fixed all of the errors discovered through cross-checking, print it out again! You will find this printout to be an extremely valuable reference while playtesting.
My method for playtesting an adventure is to play it as far as it will go, taking notes about problems that I see as I progress. Make an effort to try something new every time you go through a room or solve a puzzle. You'll be amazed at the holes in your plan that you've overlooked. If you're careful and thorough, you may find that a single playthrough has given you an entire page of problems to correct.
Fine. At the end of the playthrough, fix all the problems in the database and in your special programming. Then play it through again. If you make that effort to try different approaches to your puzzles and obstacles, you may continue to find problems for several playthroughs. The more complex the adventure is, the more problems you will probably have to fix.
Timed events (such as the sudden appearance of a certain monster or the printing of a special effect at a particular point in the play) are a bit trickier to get completely debugged. I'm talking about the kind of event that only happens when a predetermined set of other events have occurred. Unless your map is very narrowly and rigidly drawn so that nothing can occur out of sequence, this type of event needs special attention during playtesting. Be sure to try as many ways to get around the special event as you can think of. Every time you play, try to think of some new action to try that will cause the event to not take place as planned. It's likely that you will find a good many holes to plug!
Needless to say, replaying your adventure over and over again does get real old, real quick. This is where building it in sections helps. Once you have debugged one section, it is very simple to add a temporary line to the MAIN PGM to skip over the part already completed.
For example, let's say that you have completed and debugged rooms 1-40, and you wish to skip ahead to room 41 for advanced playtesting. Your scenario says that a successful adventure at this point requires that you be carrying artifact #7 and that you be accompanied by monster #1 and #3. Your special programming requires that variable Z1 and Z5 be set to 1. Adding this line will enable you to "jump ahead" to room 41 for playtesting purposes:
31500 R2 = 41: A%(7,4) = R2: M%(1,5) = R2: M%(3,5) = R2: Z1 = 1: Z5 = 1: GOTO 3500
I typically will make several of these lines for different places in the adventure, and will add them all to the MAIN PGM with REM's so that they are ignored. Then when I need to use one, I merely remove the REM from the front of the line to activate it.
Don't forget to delete this line when you are through playtesting!
Don't make your character specially super-strong or immortal for the purposes of playtesting. Playing with such "cheater" characters will give you a very warped idea about what it will be like for others to play your adventure. Just when you think that you have got it perfect, play with a "normal" character may reveal that it is impossible to survive!
Well, okay, it's all right to use an immortal character during the early phases of testing the individual sections. But if you do this, be sure to play the entire adventure through about six times with a "normal" character to be sure that you have pegged the difficulty right.
Some may differ, but I would define a "normal" character in this range: HD, CH, AG = 20; all weapon abilities = 50; armor ability = 20; all spell abilities = 70; gold = 10,000; two swords with 10% complexity and 2D8 damage ability; plate armor and shield. If your adventure requires a stronger character or abilities, it is up to you to make the extra power available in the actual adventure.
You can make special potions and weapons available to pump up the character, or you can provide powerful companions to take up any slack. I used the "powerful companions" option in both "Thror's Ring" and "Dolni Keep", and pumped up the character in "Walled City of Darkness". Either method works well. If you pump up the character to really high levels, it's a good idea to shrink him most of the way back down before returning him to the Main Hall.
If your adventure has puzzles to be solved for special events, be sure to plan for the super-characters, too. A significant percentage of Eamon players like to use super-strong characters with nuclear-weapon-level weapons to crash through everything in sight. If you have a vault door with a strength of 900, these guys will simply beat it down instead of figuring out how to open it. This kind of thing is fairly easy to defeat with special programming, but you must plan ahead. For an example, in "Walled City", I had a number of supernatural foes who could only be destroyed by a special weapon that the player had to obtain in the adventure; and use of the player's strong magical weapons were rigged to do more harm than good!
One of the really friendly things about an interpreted language like Applesoft is that you can stop the program, examine and change the program variables, then resume the program anywhere you want to. This enables the knowledgeable Eamonaut to look into the workings of the adventure and regain the upper hand in an Eamon adventure that is beating him badly.
<RETURN> the key labeled "Return" <Ctrl-C> hold down the key labeled "Control" ("CTRL" on a II+) and then press the "C" key. The "Control" key works just like the "Shift" key. <Ctrl-C> is a special code that halts a running Applesoft program. (v7) the version 7.x Eamon MAIN PGM (v4-6) earlier versions of the MAIN PGM
***** To Halt a Running Program
To stop a running Eamon adventure, type <Ctrl-C> then <RETURN> at the YOUR COMMAND? prompt. Don't do it at any other time, or you may damage the flow of play.
***** To Resume Play
To resume play of an Eamon program at the YOUR COMMAND? prompt, type:
POKE 51,0:GOTO 100
The POKE is necessary to tell DOS that a program is running. If you don't add the POKE, the program will eventually crash with a NOT DIRECT COMMAND error.
Here are some useful variables for you to know:
Rooms NR...total number of rooms
V%(x) "seen" flag for rooms eg: if V%(22) = 1 then you have already been in Room 22. If V%(22) = 0 then you have not been in that room yet.
RO...room number of the room you are in
R3...room number of the last room you were in
R2...room number of the room you are moving into
Artifacts NA........total number of artifacts
A$(x).....name of an artifact (v7)
AN$(x)....name of an artifact (v4-6)
A%(x,4)...location of an artifact (v7)
AD%(x,4)..location of an artifact (v4-6)
Artifact Locations (v7)
1 to 200.......in room 1-200 eg: 71 means Room 71
201 to 400.....hidden in room 1-200 eg: 271 means hidden in Room 71 ˙
501 to 700.....inside container artifact 1-200 eg: 524 means inside Artifact 24
-1.............carried by the player
-2 to -201.....carried by monster 1-200 eg: -62 means carried by Monster 61
Artifact Locations (v4-6)
1 to 100.......in room 1-100 eg: 71 means Room 71
101 to 200.....inside container artifact 1-100 eg: 124 means inside Artifact 24
201 to 300.....hidden in room 1-100 eg: 271 means hidden in Room 71
-1.............carried by the player
-2 to -101.....carried by monster 1-100 eg: -62 means carried by Monster 61
NM........total number of monsters
M$(x).....name of a monster (v7)
MN$(x)....name of a monster (v4-6)
M%(x,5)...location of a monster (v7) eg: M%(13,5) = 37 means that Monster 13 is in Room 37
MD%(x,5)..location of a monster (v4-6)
M%(x,1)...a monster's hardiness (v7)
M%(x,13)..a monster's hit damage (v7)
Note that the above variables for (v4-6) are the standard ones. There are several (v4-6) Eamons that use a variable set that is similar to the (v7) one; examples can be found among my own and Sam Ruby's Eamons, and there are others as well. If you get a BAD SUBSCRIPT error while trying any of the techniques listed below, try listing the code at lines 100-200 to see what variable names are used in the program.
***** Peeking into a Running Program
All of these examples are meant to be typed after halting the game with <Ctrl-C> then <RETURN>. Once you have done the desired operation, resume play as stated above. All examples are for (v7).
* To see which rooms you haven't visited:
FOR I = 1 TO NR: PRINT V%(I): NEXT
* To list the numbers & names of all artifacts:
FOR I = 1 TO NA: PRINT I,A$(I): NEXT
* To list the locations of all artifacts:
FOR I = 1 TO NA: PRINT I,A%(I,4): NEXT ˙
* To list the numbers and names of all monsters:
FOR I = 1 TO NM: PRINT I,M$(I): NEXT
* To list the locations of all monsters:
FOR I = 1 TO NM: PRINT I,M%(I,5): NEXT
***** An Example
Suppose you are on a Quest for a Magic Sceptre of some sort. You have been everywhere and LOOKed everywhere, and you haven't found it. You are at your wit's end, and are ready to cheat! OK, after halting, take these steps: (This example is for v4-6.)
1) First, find the artifact's number:
FOR I = 1 TO NA: PRINT I,MN$(I): NEXT
(As the artifact list scrolls by, watch for the Sceptre's name in the list. Use <Ctrl-S> to stop and start the list as it scrolls by.) Let's say that the Sceptre is Artifact #13.
2) Find the Sceptre's location:
Let's say that the Sceptre is in Room 144. We know that locations in the 101-200 range are containers. Thus, the Sceptre is contained in Artifact #44.
3) Find out the container's name:
Let's say that it is named SMALL DOOR.
4) Find the container's location:
Let's say that it's in Room 259. Ah ha! We know that locations in the 201-400 range have descriptions that are "embedded" in the room's description, and don't appear until they are acted upon. The door is in Room 59.
5) Have we been in Room 59?
***** "Teleporting" to Other Rooms
This is a very simple thing to do. The entry point for this is line 3500 in the MAIN PGM. This routine will move you and your companions to whatever room is defined by the variable R2. This works just like an ordinary move; your enemies may chase you, also!
Let's say that we want to jump to Room 59 where that Sceptre is hidden:
R2 = 59: POKE 51,0: GOTO 3500
If V%(x) shows that you have not been in the room yet, then you shouldn't "teleport" there, because you may be jumping past important plot elements and may make the adventure impossible to complete. If you haven't been there yet, list all of the rooms' flags and "teleport" to the nearest room number that you have been in. Once there, look for the entry to the room you want. This doesn't always work, because rooms are seldom numbered in exact sequence, but it often works out quite well.
***** Resurrecting Yourself (DOS 3.3)
When you see that YOU HAVE DIED! Type <Ctrl-C> then <RETURN> at the PRESS ANY KEY TO CONTINUE prompt. What you type next depends on why you died:
If you fell in combat, or were killed by POWER or a deathtrap:
DI = 0: M%(0,13) = 0: POKE 51,0: GOTO 29060
If you walked into a deathtrap room that you should better have avoided entering:
DI = 0: M%(0,13) = 0: R2 = R3: POKE 51,0: GOTO 3500
***** Resurrecting Yourself (ProDOS)
When you see that YOU HAVE DIED! Type <Ctrl-C> then <RETURN> at the INSERT EAMON MASTER DISKETTE THEN HIT THE 'C' KEY prompt. What you type next depends on why you died:
If you fell in combat, or were killed by POWER or a deathtrap:
DI = 0: M%(0,13) = 0: POKE 51,0: GOTO 29060
If you walked into a deathtrap room that you should better have avoided entering:
DI = 0: M%(0,13) = 0: R2 = R3: POKE 51,0: GOTO 3500
The program will immediately crash. Type:
POKE 51,0: GOTO 29060
***** Getting Out of No-Exit Traps
After halting at YOUR COMMAND?, type:
R2 = R3: POKE 51,0: GOTO 3500
***** Healing Yourself
If you are getting beat up badly in combat, you can halt at YOUR COMMAND? and type:
M%(0,13) = 0: POKE 51,0: GOTO 100
If you want to beef up the HEAL command after it's pooped out on you:
S2%(2) = 2000: POKE 51,0: GOTO 100
***** Cutting the Bad Guys Down to Size
If the bad guys in the adventure are impossibly difficult to kill, you can make them one hit away from death with this line:
(V4-6) FOR M = 1 TO NM: MD%(M,13) = MD%(M,1) * (MD%(M,14) = 1): NEXT: GOSUB 3600: GOTO 100 (V7) FOR M = 1 TO NM: M%(M,13) = M%(M,1) * (M%(M,3) = 1): NEXT: GOSUB 3600: GOTO 100
This will only affect monsters that you have actually met up with that are your enemies.
SPECIAL NOTICE I'm facing a problem with this column: I am having a bit of difficulty coming up with stuff to write about that hasn't already been covered in past issues. If there's something that you would like to see discussed or explained, please let me know about it!
Monster Weapons: Few things detract from the feel of combat like silly and inappropriate weapon assignments. Pay attention to the monsters' weapon numbers! If the monster is supposed to be carrying a weapon, be sure to actually assign him a "real" weapon that is included in the artifact database. If the monster is fighting with natural weapons (teeth, karate, whatever) be sure to give him natural weapons by assigning a Weapon Number of zero.
Note that you can set up individual monsters as "unarmed" by giving them a negative weapon number. A good example of when this is appropriate would be a freed prisoner who has no weapon but will fight if given one.
The game's play can really get screwy when a multiple-monster is carrying a real artifact-weapon and drops or breaks it during combat. (I don't mean that the program breaks, just that this event reads very poorly.) Avoid this by not assigning a real weapon to multiple monsters unless there is some overriding reason for such a weapon to exist. When possible, give all multiple-monsters "natural" weapons, even if they should be carrying real ones. Minimize the confusion by making little or no reference to the monsters' weapons. If there are just two or three members of the group, it might be better to make them individual monsters and assign real weapons to them.
Artifact USER Fields: The artifact database fields named USER are not used by the MAIN PGM. It doesn't matter what is put in these locations, since this information isn't used for anything. The DUNGEON EDIT program makes them available so that authors can easily use these locations for special programming data of their own.
Synonyms: Be sure to use the synonym checking routine for your embedded artifacts. See the June '92 EAG newsletter for a step-by-step tutorial of this powerful feature.
Special Checking: When you add special programming that checks for specific artifacts, never make the check by comparing the artifact's name to S$! Always use the variable "A" and compare "A" to the artifact number you are looking for.
What difference does it make? It uses the standard player interface, which permits the player to expect certain responses from certain inputs by utilizing the standard checking code. One of the worst mistakes that new Eamon authors make is to bypass the standard interface routines.
Let's do an example. Let's say that something special will happen when the player picks up an artifact named MAGIC WAND. Let's say that this wand is Artifact #12.
4060 IF LEFT$ ("MAGIC WAND",LEN(S$)) = S$ THEN (special programming)
Problem: This line won't detect right-end abbreviations; the command GET WAND won't see it.
4060 IF S$ = "MAGIC WAND" THEN (special programming)
Problem: This line won't detect any abbreviations; the command GET WAND won't see it, and neither will GET MAGIC.
4060 IF A = 12 THEN (special programming)
Benefits: Improves execution speed by making use of already-executed existing code; utilizes standard interface that detects truncated words. The player expects to be able to use commands as short as G M, and this line will do it.
How does the "right way" work? If you look at the GET routine at 4000-4020, you will see that it calls the subroutine at 4800 to see if the artifact named by S$ is available. If the artifact is available, the routine at 4800 sets the variable A to the number of the artifact. So, you see, all of the checking has been done for you already by the time you get to your special programming at line 4060.
Closed Artifacts: Containers, readable artifacts, and drinkable artifacts all have the option of being open or closed. Unless there is a strong reason to have it closed, you should be sure to leave readable and drinkable artifacts already open in the database. For example, it's irritating to the player to have to OPEN an ordinary book before reading it, as the READ command implies opening the book as well.
Unfortunately, the editor defaults drinkable and readable artifacts to the closed state. Be sure to enter the open state for anything that isn't locked or tied to special effects upon opening.
Containers are a special case; it doesn't matter which state they are in, as the OPEN command functions to empty them out onto the ground. However, you will of course want to have "locked• containers closed!
NOTE: most of these programs only work with Eamon version 4-6, as noted.
A nifty little program with two user-specified options: FREESPACE modifies DOS 3.3 so that the CATALOG command lists free space at the top. FILEDUMP prints any text file directly to the screen. Compatibility notes: FREESPACE prints a blank for free sectors on my enhanced IIe but works OK on my II+ and ROM1 GS. FILEDUMP works on my II+ and IIe but crashes into the Monitor on the GS.
CHANGE EAMON NAME (v6)
A painless way to change an Adventure name or the Adventure number. Caution: make sure that the EAMON ADVENTURE #XXX program, the intro program, and EAMON.NAME are unlocked before running.
LAST UPDATE INSTALL (all)
Back before the EAG took over Eamon library maintenance, Eamon adventures had a blank line in the catalog where the LAST UPDATE line is now. This program renames this "blank name" file to LAST UPDATE. This program will crash on Eamons that have the LAST UPDATE file.
EAMON DOS REMOVER (all)
This program frees up an additional 32 sectors of disk space by deleting DOS from the disk. It also adds an alert message that prints to the screen when the disk is booted.
LCASE KILLER (all)
BRUNning this program from a running Applesoft program will convert all of the text in the program's PRINT statements to upper case.
LC/UC CONV (all)
This program will convert any string to all upper case text, as noted in the DDD 7.0 Utilities Manual. To make it available, simply BLOAD it. To convert the string A$, use this command: CALL 768A$
VERSION ANALYSIS (v1-6)
Can identify Eamon versions 1 through 6. Doesn't recognize non-standard formats or 7.x. See UNIVERSAL CHECK FILES.
ROOMS CONVERT (v4-5)
This program can change the record size of the EAMON.ROOMS data file. It reads in EAMON.ROOMS and writes a new file named NEW.ROOMS at the specified record length. You must then delete the original EAMON.ROOMS and rename NEW.ROOMS to EAMON.ROOMS to complete the change. The new record length is specified in Line 20 of the program, which you must modify to the length that you desire.
ROOM NAMES CONVERT (v4-6) ARTIFACTS CONVERT (v4-5)
These two programs work just like ROOMS CONVERT above and are used to convert EAMON.ROOM NAMES and EAMON.ARTIFACTS, respectively.
ARTIFACT MAINTENANCE (v4-6)
Normally, using dead bodies greatly complicates modification of the Artifact database, as the dead bodies must all be together and should be at the end of the file. This program gives you a quick and easy way to insert extra "DUMMY" artifacts into any point in the artifact list. It will also remove excess artifacts that you want to get rid of to free up disk and memory space.
REMOVE DUMMY ARTIFACTS (v4-6)
A common way to develop Eamon adventures is to stick a bunch of extra "DUMMY" artifacts in between the "real" artifacts and the dead bodies. Thus you can use the "dummies" to add more artifacts without having to monkey with the dead bodies. This program can be used to help you get rid of excess dummies once you are through with development.
DESC EDIT (v4-6)
A very handy program for doing quick fixes of errors in the descriptions.
UNIVERSAL CHECK FILES (v4-7)
Reports the version and structure of Eamon adventures. Recognizes all known non-standard formats. Verifies the integrity of the database files and reports any errors.
ADD LIGHT TO ROOMS (v4-6)
Adds the "light" data to the room data (if it's not already there) and sets all rooms to "lit".
Lists the number and names and selected data fields for rooms, artifacts, or monsters. Can list to printer.
LIST EAMON R.A.M. (v4-6)
Prints out the numbers and names of rooms, artifacts, and monsters. Can list to printer.
ROOM ANALYSIS (v4-6)
Lists room numbers and names plus all artifacts and monsters in each room. Doesn't recognize hidden or embedded artifacts. Can list to printer.
QUICKY ROOM PRINT (v4-6)
Lists room numbers and names plus room exits. Does not print light. Can list to printer.
FLEX DUNGEON LIST 2.1 (v4-6)
Prints out database in 40-col. format. Does not print light.
DUNGEON LIST Z (v4-6)
This program combines features from several old Eamon utilities not found on this disk:
Lists Rooms, Artifacts, Effects, and Monsters; makes cleaner printouts than DUNGEON LIST does.
Room Analysis: same as described above.
Walk-Through: enables you to go from room to room; does not recognize doors or non-standard room connections.
The strength of this program is that it only loads what it needs to do the task you select, and retains that data in memory. Thus you can save a lot of time waiting on disk accesses, making it very useful for messing about in the database.
DUNGEON LIST 6.0G (v4-6)
Basically the same as the DUNGEON LIST program on the 6.2 DDD, but with a couple of minor extras. Makes much cleaner printouts than DUNGEON LIST does!
TEST BENCH (all)
Allows you to quickly start an adventure without using the Main Hall. You can define your test character's basic stats, and play with a basic set of weaponry. Note: don't use the "default" setting, which gives you a nearly helpless character.
ADVANCED BENCH (all)
Similar to TEST BENCH, but permits you to specify more of the character's stats. Gives you two mundane weapons and one 2D8 sword.
EAMON CHARACTERS FILE MAINT (all)
A comprehensive CHARACTERS file maintenance program that enables you to change any aspect of the CHARACTERS database. You can also resurrect the dead, make copies, generate new characters, list the contents, and more.
CHAR REBIRTH (all)
A simple program that will resurrect a "dead" character in the CHARACTERS file. Handy when you've been killed out of an adventure.
START ADVENTURE (all)
This program is similar to the test benches above, but gets the data from that stored in the CHARACTERS file. Handy for quick startups because it is faster than using the Main Hall and doesn't mark the character as "dead".
FRESH SAM (all)
Another program that starts Eamon adventures without having to use the Main Hall. This one uses a preset character ("Sam"), whose stats represent an advanced character who has earned reasonably high stats and decent weapons. I personally use this program for all of my Eamon playing.
(Ed. note: I was so impressed by the text parser in Frank's Eamon, "Adventure in Interzone", that I asked him to write it up for us.)
The following is a quick and efficient way to print text without wrap-around in any column width. It can be easily integrated into the basic 7.1 MAIN PGM.
The text must be contained in the string variable A$ and the column width must be specified in the variable CP before use (this is normally automatically set at program startup). When you want to print your text, simply use the statement "GOSUB 11".
11 GOSUB 28 : GOTO 16
14 IF LEFT$ (A$,1) = " " THEN A$ = MID$ (A$,2) : GOTO 14
16 IF LEN (A$) < = CP -1 THEN PRINT A$ : GOSUB 52 : GOTO 29
17 FOR K = CP - 1 TO 1 STEP - 1 : IF MID$ (A$,K,1) = " " THEN PRINT LEFT$ (A$,K - 1) : A$ = RIGHT$ (A$,LEN(A$) - K) : GOSUB 52 : GOTO 14
18 NEXT : PRINT "STRING TOO LONG ERROR" : STOP
28 F1 = PEEK (111) + PEEK (112) * 256 : RETURN
29 IF PEEK (111) + PEEK (112) * 256 < F1 THEN POKE 111,F1 - INT (F1 / 256) * 256 : POKE 112, INT (F1 / 256)
45 GOSUB 28 : F2 = F1 : PRINT D$"READ"ED$",R"R : INPUT A$ : PRINT D$ : GOSUB 51 : GOSUB 11 : F1 = F2 : GOSUB 29
(Delete the old Line 50.)
Line 14 stops any problems which would be caused by double spacing between
Line 16 checks to see if A$ is equal to or less than the column width set. If so, it prints it, increments the line counter, and exits.
Line 17 starts a search for a space at CP - 1 characters and works backwards until it finds one.
Line 18 - If no space is found, then an error message is printed and the program halts. This can only occur if there is a word longer than the column width.
Lines 28-29 circumvent string "garbage collection" by discarding A$ after use.
Line 45 reads in A$ from disk and calls the rest of this routine to parse and print it.
If you want to do something special to A$ such as convert it to all caps, put it in Line 11 after "GOSUB 28".
If you have any questions or need help integrating this routine into your program, write me with an exact description of what you're trying to do:
A description of the workings of the MAIN PGM.
45-50 string print subroutine 45 note the top of free memory and read in A$ from disk 50 perform screen pause calculation for A$ length; print A$; then recover the memory that A$ occupied 51-59 screen pause routine 51 print blank line, increment line counter by one 52 increment line counter by one 54 print blank line, increment line counter by 3 56 print blank line, increment line counter by 2 58 check for full screen; if full then 59 pause screen and zero line counter 91-96 command error messages 98 normal return point for most commands 99 return point for Inventory, failed commands
100-200 YOU SEE routine 110-117 check status of Artifact light source 120 check status of SPEED spell 122-123 recovery of expended spell ability S2 is present level, SA is full ability; if S2 is less than SA, then increase by 10% 125 check room light; skip YOU SEE if dark 130 print room name 135 print room desc. if "seen" flag is zero 140 check for monsters in room 145 print monster desc. if "seen" flag is zero 150 print single-monster name 154 print multiple-monster name 155 print blank line if desc. was printed 160 check for artifacts in room 165 print artifact desc. if "seen" flag is zero 170 print artifact name 190 print personal-weapon name if in room
200-290 Command parser 210 ask for "YOUR COMMAND?" 220 strip any leading spaces 230 use last command if <RETURN> was input 240 find end of first word of command 250 assign command verb (V$) and object (S$) 260 strip leading spaces off object 270 check for verb match to direction command (N,S,E,W,U,D) 272 if not direction command, check for match to rest of command list 275 if no match to any command, print command list and go back to 210 290 if match was found, jump to command routine
300-495 PICK FOE routine 305 print blank line 310 foes present? if not, exit routine 320 find monsters present in room 330 if monster is neutral, look for another 333 if single-monster, check courage level, determine if monster flees room 334 if monster did not flee, proceed to combat 335 check multiple-monster courage level, determine if monster(s) flee room 336 multiple-monster member(s) flee room 340 if multiple-monster has more than 8 members, limit combat rounds to 8 (on theory that a max of 8 monsters could get in a hit in one round) (BAD LINE???) 350 assign monster as attacker (OF); determine if attacker is friend; if so, go to 400 360 determine if attacker is only enemy in room 370-380 find friendly defender (DF) for attack; go to 480 400-430 find enemy defender for attack 480 proceed to DO BATTLE routine
500-900 for every-round special programming
3000-3390 MOVE routine 3010 abort move if enemy present 3020 assign direction (D) 3030 get exit data; if door then proceed to GATE/DOOR routine 3040 if valid room connection then proceed to GO routine 3060 check for exit to Main Hall 3390 abort move if invalid exit
3400-3430 GATE/DOOR routine 3410 find room on other side of door; if door is not locked nor hidden then get room connection and return to MOVE routine 3420 if door still hidden then abort move 3430 if door locked then abort move
3500-3590 GO routine 3530 move to next room, check monster status 3540 get new room desc. and exits 3550 find number of exits from room 3560 get room natural light status and determine if room is dark 3590 exit to YOU SEE routine
3600-3670 ENEMY? subroutine 3610 initialize group monster strengths and hits 3620 check each monster... 3630 determine if monsters from last room follow and bring them in new room 3640 if monster did not follow then next monster 3650 determine monster friendliness 3660 add monster strength and hits into group totals and exit to calling routine
4000-4240 GET routine 4010 check for object of command S$; if "ALL" then go to ALL routine 4020 check to see if S$ is in room; if not, go to error message at 94 4030 if object weight is greater than 900 then abort with DON'T BE ABSURD message 4040 if object weight plus inventory would exceed ten times player's strength then abort with TOO HEAVY message 4050 if object is "prisoner" artifact than abort with TIED DOWN message 4140 get object; increase weight carried by player (WT); if player has no ready weapon and object is a weapon, proceed to READY routine 4150 exit to PICK FOE routine
4200-4240 GET ALL routine 4200 find all artifacts in room 4210 print name of artifact; if prisoner, skip 4215 if weight is over 900 then skip 4220 if weight would add too much to player's carried WT then skip 4230 get artifact and print TAKEN 4240 increment line counter and check for screen pause
4600-4780 SYNONYMS subroutine 4610 find length of object name 4620-4674 space for synonym data 4675 exit to calling routine 4680 compare synonym name to object name; if match, assign object name to artifact defined by synonym data
4700-4780 MONSTER SEARCH subroutine 4705 assign search locations to room and player inventory 4710 check for match between object name and monster names 4715 if no name match then return with F = 0 4720 if name match found then check to see if monster is in room or in player inventory 4750 increment F; if first match found then assign monster number (M) to match 4760 if name is an exact match then assign (M) and exit to calling routine 4770 check for additional matches 4780 exit to calling routine
4800-4870 ARTIFACT SEARCH subroutine 4801 assign all search locations to player inventory only; proceed to search (DROP) 4804 assign search locations to player inventory, room, and artifacts "embedded" in room (EXAMINE) 4805 assign search locations to room, artifacts "embedded" in room, and third location defined by calling routine (GET, REMOVE) 4810 check for synonyms; perform search for match to object name; abort if no match 4820-4830 determine if any artifact that is in one of defined locations matches name; if perfect match, assign artifact number (A) to match and exit subroutine 4850 search for additional matches; if found, ask WHICH DO YOU WANT? and exit to YOU SEE 4870 exit to calling routine
4900-4920 GET S$ subroutine 4905 if room is dark then abort to YOU SEE 4910 if no object defined by S$ then as for one 4920 exit to calling routine
5000-5150 DROP routine 5010 check for object of command S$; if "ALL" then go to DROP ALL routine 5030 check to see if player is carrying object; if not, go to print error at 91 5040 deduct object's weight from weight carried (WT); print "DROPPED" message and check for screen pause 5042 if dropped object was current carried light source, extinguish light and switch to room's natural light 5050 if dropping object increases weight carried beyond player's carrying capacity (eg: dropped object was something like a cart or wheelbarrow) then proceed to DROP ALL and dump entire inventory on ground 5060 if dropped object was ready weapon then change Ready Weapon status to unarmed 5070 exit to PICK FOE routine
5100-5150 DROP ALL routine 5100 search artifacts for those carried by player 5110 drop each to ground as it is found; print DROPPED and check for screen pause 5150 set weight carried to zero, mark player as unarmed
6000-6060 EXAMINE command 6010 check for object of command S$; find out if named object is an artifact present in the room or being carried; if not found then proceed to search for monster 6020 if object is an "embedded" artifact then change location to room to make visible 6032 if object is one of player's personal weapon then name it 6033 if object is hidden door then make door visible 6034 if object is drinkable then print number of swallows left; check for screen pause 6035 print artifact description; set "seen" flag to "seen"; exit to PICK FOE routine 6040 search monsters for match to object; if no match then named object is not an artifact nor a monster, so print YOU SEE NOTHING SPECIAL and exit 6050 print monster description; if group monster and uninjured then print THEY ARE IN PERFECT HEALTH; exit to PICK FOE routine 6060 print monster's health status; exit to PICK FOE routine
6500-6510 LOOK routine 6510 set room "seen" flag to zero (this will cause room desc. to be printed at next pass through YOU SEE routine); exit to PICK FOE routine
7000-7370 ATTACK routine 7010 check for Ready Weapon, abort if none 7020 check to see if object of attack is named; search for match to monster; if match proceed to line 7300 7030 check to see if object of attack is an artifact in the room; if no match then abort to print error message at 94 7040-7080 perform attack on artifact 7040 if object is not door or container then abort attack; exit routine 7050 set "dice" and "sides" to weapon stats; if attacking through BLAST spell then set "dice" to 2 and "sides" to 5 7060 set up database variables for door; if object is container then set variables for container 7070 perform attack on object; if object strength is reduced to zero then print SHATTERS message and open it 7075 if object is hidden door then unhide it 7080 print WHAM!!! message
7300-7370 perform attack on monster 7300 define attacker (OF) and defender (DF); proceed to DO BATTLE routine 7310 if successful hit then check to see if weapon ability should be increased; increase weapon ability 7360 if defender was enemy or self then exit to PICK FOE routine 7370 if defender was friend or neutral then calculate whether alignment changes and update group totals; exit to PICK FOE
7400-7450 MONSTER PICKS UP WEAPON subroutine 7410 find artifact number of weapon that monster had dropped; if available then go to 7440 7420 search room for available weapons; identify best weapon found 7440 if weapon found then pick up and assign as monster's ready weapon 7450 exit to calling routine by way of screen pause check
7500-7900 DO BATTLE routine 7505 reset "Hit" flag; set W to Artifact number of attacker's weapon; if no weapon then go to PICKS UP WEAPON routine 7507 compute percent odds of scoring hit (WM) 7510 select correct attack verb. Print attack 7511 check line count; generate random number RL in 1-100 range; if RL is less than 5 or the computed odds WM and also less than 97 (3% chance of fumble) then set Hit flag and proceed to damage computation 7515 if defender is carrying a real weapon then set A2 to weapon type, or set to 0 if natural weapon 7520 if RL < 97 or the attacker is using natural weapons, then print a "Miss" verb and exit through screen pause routine (97% chance) 7525 print "A FUMBLE" (3% chance) and generate random number R; if R < 41 (40% chance) then print FUMBLE RECOVERED and exit through screen pause routine 7530 if R < 81 (40% chance) then drop attacker's weapon; adjust Weight Carried; put weapon in Room; set attacker's weapon to None; exit through screen pause routine 7532 if attacker's weapon is magical then print SPARKS FLY message and exit through screen pause routine 7535 if R > 95 then proceed to WEAPON HITS USER (5% chance) 7537 if R < 91 (90% chance) then print WEAPON DAMAGED and lower weapon sides by 1; if sides is greater than zero then exit through screen pause routine 7540 if sides equals zero then print WEAPON BROKEN; lower Weight Carried by weapon weight; set weapon location to zero; set weapon carried to None; generate random number; if more than .5 then exit through screen pause routine (50% chance) 7545 print WEAPON HITS USER; check screen pause; set DF to attacker for damage computation; proceed to damage computation unless R = 100 then proceed to WELL STRUCK computation
7600 if player is attacker then compute possible increase in weapon and armor expertise 7605 set Dice and Sides to monster's stats; if carrying weapon then use weapon stats 7607 set Defender's armor factor to 1; Print "** A HIT" if defender is player or "++ A HIT" if monster; if RL > 5 then proceed to damage computation (95% chance)
7610 print WELL STRUCK! (5% chance); check screen pause; generate random number R2; if R2 < 51 then set Defender's armor factor to zero (50% chance); proceed to damage computation 7615 set RL to 1.5 (35% chance); if R2 > 85 then set RL to 2 (10% chance) 7620 if R2 > 95 then set RL to 3 (4% chance) 7625 if R2 = 100 then set RL to Defender's Hardiness (a sure Death Blow; 1% chance) 7630 multiply Sides by RL to increase damage
7633 check for screen pause; compute hit damage D2; reduce D2 by defender's armor multiplied by armor factor set in 7607-7610; if D2 is not positive number then no damage; if defender not wearing armor then print BLOW TURNED and exit through screen pause routine 7635 if D2 is not positive then print BLOW BOUNCES OFF ARMOR; exit through screen pause routine 7636 print blank line 7637 check for screen pause; if defender is multiple-monster then print ONE 7638 print monster's name and IS 7640 compute hit damage to defender and defender's room-group total; if hits equal or exceed defender hardiness then proceed to MONSTER DIES routine
7650 proceed to appropriate damage report 7652-7675 damage reports; exit through screen pause routine
7700 MONSTER DIES routine 7710 print DEAD!; remove dead monster from room group total; if multiple-monster then reduce monster count by one and set hits to zero for next member of multiple-monster and exit through screen pause routine 7720 remove dead monster from room; if multiple-monster then reset total to original value; place all artifacts carried by dead monster in room 7730 set dead monster's weapon to None 7735 inactive line that is used for optional dead bodies; if activated, places dead monster's body artifact in room 7740 if Defender is player then set DIe flag; remove DO BATTLE subroutine from stack with POP; proceed to DONE routine 7750 if room group hits equals or exceeds room group hardiness then all foes have been killed; reset group hardiness to zero to indicate there are no hostiles in room 7900 exit through screen pause routine
8000 FLEE routine 8010 if no hostiles in room then print NOTHING TO FLEE FROM and exit to YOU SEE routine 8020 if no exits then print NO PLACE TO GO and exit to YOU SEE routine 8030 if no direction specified to flee to then proceed to flee in random direction 8040 find direction specified 8050 proceed to MOVE routine 8500 find random direction to flee 8510 proceed to GO routine
9000-9900 GIVE routine 9010 run object through PARSE routine to see if it parses into full command (GIVE XX TO YY) 9040 if not full command then ask GIVE WHAT? 9050 if artifact given has no numeric value, then it's not gold; check to see if is carried by player; if not, then exit through error message at 91 9060 if not full command, then ask TO WHOM? 9070 check to see if named monster is in room; if not, exit through error message at 96 9080 print OKAY; if gold is being given then proceed to GOLD routine 9090 if artifact is player's weapon then mark player as unarmed 9095 if artifact is drinkable and monster is wounded and artifact has swallows left and is open then proceed to MONSTER HEAL routine 9100 reduce weight carried by weight of artifact given; mark artifact as carried by monster it was given to 9110 if monster was unarmed and artifact is weapon then mark artifact as monster's ready weapon 9115 if monster not Friendly then redefine monster's original potential Friendliness in terms of artifact's value 9120 reassess monster's Friendliness; jump into DROP routine to check for effects on player of losing artifact
9300-9320 GIVE POTION/HEAL MONSTER routine 9300 print that monster drinks and returns artifact to player; check for screen pause; if not Friendly then redefine monster's potential friendliness; reduce "swallows left" by one 9320 heal/poison monster; print health report; return to GIVE routine
9500-9550 GIVE GOLD routine 9500 find amount of gold to be given; if more than player carries then exit through error message at 91 9540 reduce player's gold; redefine monster's potential Friendliness in terms of amount of gold given 9550 return to GIVE routine
9800-9820 PARSE routine 9810 try to break command object into artifact and monster names (eg: GIVE XX TO YY will break into artifact XX and monster YY) 9820 return to calling routine
10000-10150 INVENTORY routine 10010 if no object named then inventory self 10020 if no light then abort to YOU SEE routine 10030 search for match to monster name; if no match then abort to error message 10040 If named monster is not Friend then exit through SMILE routine to give response 10050 set X to location of named monster's stuff and jump to do inventory 10060 search for worn artifacts; if none found then bypass "worn" code 10070 print "IS WEARING" line and check for screen pause 10080 print worn artifact name 10090 check for more; set X to location of player's stuff 10100 print "IS CARRYING" line and check for screen pause 10110 search for carried artifacts; if none found then skip to "(NOTHING)" line 10120 print artifact name; if ready weapon then print "(READY WEAPON)" 10130 check for screen pause; check for more; if no artifacts were found then print "(NOTHING)"; check for screen pause 10140 if player being inventoried then print gold; check for screen pause; print player's health condition 10150 exit to PICK FOE routine
11000-11050 BLAST routine 11010 set S to BLAST; go execute spellcast; check if spell object is named; search for match to monster name; if no match then proceed to ATTACK routine to try for artifact match 11050 print DIRECT HIT message; increment line counter; set "sides" to 5 and "dice" to 2; use code in DO BATTLE routine to compute and print hit damage; exit to PICK FOE routine
11500-11540 SPELLCAST subroutine 11500 if player has ability for cast spell, use random number RL to determine result 11505 if RL = 100 (1% chance) then print SPELL BACKLASH! message; diminish current spell ability by 90%; exit through screen pause check to PICK FOE routine
11510 if spellcast unsuccessful, then print NOTHING HAPPENED message and exit through screen pause to PICK FOE routine 11520 use random number to determine if permanent spell ability is increased by 2 11530 diminish current spell ability by 20% 11540 exit to calling spell routine
12000-12060 HEAL routine 12010 set S to HEAL; go execute spellcast; if monster is named then search for match to name 12040 check for screen pause; if object of HEAL is injured then print HEALTH IMPROVES message 12050 reduce hit damage by 3 to 12; if damage is reduced below zero then set to zero 12060 use code in DO BATTLE routine to compute and print hit damage; exit to PICK FOE routine
13000-13080 POWER routine 13010 set S to POWER; go execute spellcast; generate random number RL; if RL < 11 (10% chance) and player has hit damage then restore to perfect health; exit through screen pause check to PICK FOE 13050 if Rl < 91 (80% chance) then print SONIC BOOM message; perform screen pause check; exit to PICK FOE routine 13070 restore all monsters in room to perfect health (10% chance) 13080 check monster status; exit to PICK FOE
14000-14040 SPEED routine 14010 set S to SPEED; execute spellcast 14020 if SPEED spell is already active then print NOTHING HAPPENED message; exit through screen pause check to PICK FOE 14040 double player Agility; set spell counter to 10-32; print QUICKEN message; exit through screen pause check to PICK FOE
15000-15100 SMILE routine 15005 if no light then abort to YOU SEE 15010 print blank line; check for monster in room; if none then exit to PICK FOE 15030 increment line counter; print monster name; if multiple-monster then add "S" for plural 15040 print response appropriate for monster alignment; if not multiple-monster then add "S" to response 15050 print "AT YOU." 15100 check for more monsters in room; update line count; exit to PICK FOE routine
16000-16900 SAY routine 16010 check for object S$ 16900 if S$ present then "say" it.
17000-17100 READY routine 17010 check for object S$; check to see if named object is being carried; if not carried then exit through error message at 91 17030 if named object not weapon then print NOT a WEAPON and exit through line count to YOU SEE routine 17100 set player's Dice and Sides to that of named weapon; set W2 to weapon type; print READIED message
18000-18100 SAVE routine 18010 ask if player is sure they want to save game 18020 get player response; if not "Y" or "N" then try again for proper response 18030 print response; if "N" then exit to YOU SEE routine 18040 close open files; clean up string space by executing FRE command; BSAVE variable pointers 18060 BSAVE nonstring variables 18070 BSAVE string variables 18080 print GAME SAVED message 18090 ask if player wishes to resume play; if not "N" then exit to RESUME routine to reopen files 18100 END program execution
19000-19050 LIGHT routine 19010 check for object S$; check to see if player is carrying named object; if not then exit through error message at 91 19040 set light flag LT to natural light of room; if named object is not lightable then print IT WON'T LIGHT 19050 set LT to "light"; set light source LS to number of lighted object; print LIGHTED message; exit to PICK FOE through line count routine
20000-20340 OPEN routine 20010 check for object S$; check to see if object is available; if not then exit to DOOR check at 20060 20020 if object is hidden then make visible 20030 update line count; proceed to OPENABLE routine if object is container, drinkable, or readable 20050 proceed to DOOR routine if object is door 20060 if no true artifact is named but object is DOOR or GATE then print TRY GOING message 20070 if we get here it is not openable; print IT WON'T OPEN
20100-20130 OPENABLE routine 20110 if readable or drinkable and open flag is set then print ALREADY OPEN message 20120 if container then mark unhidden (feature not used); if a key exists but is not held by player then print LOCKED message; exit to YOU SEE through line counting routine 20130 mark as open; print OPENED; if drinkable or readable then exit to PICK FOE through line count
20200-20230 CONTAINER routine 20220 update line counter; check artifact array for artifacts in container; if any found then put found artifacts in room; set LK flag to 1 20230 print FOUND NOTHING or SOMETHING INSIDE depending on state of LK flag; exit to PICK FOE through line counter routine
20300-20340 DOOR routine 20310 if a key exists but is not held by player then print LOCKED message; exit to YOU SEE through line counting routine 20330 unhide door; unlock door; put door in room; print OPENED message; find room connection of door 20340 exit to PICK FOE through line counter
21000-21150 PUT routine 21010 if object is named then run object through PARSE routine to see if it parses into full command (PUT XX IN YY) 21040 if not recognized as full command then ask for name of object and container 21100 check for object; if not present then exit to PICK FOE through line counting routine 21110 check for container; if not present or same as object then exit to PICK FOE through line counting routine 21120 if container is not a "container" object then proceed to error message 21130 if container not open then exit to MUST FIRST OPEN IT error message 21140 change object's location to inside container; print OKAY; exit to PICK FOE through line counting routine 21150 print YOU CAN'T DO THAT; exit to PICK FOE through line counting routine
22000-22190 DRINK routine 22010 check for object S$; check if object is available; if not found then exit through error message at 94 (YOU CAN'T...) 22020 if object not drinkable then exit through error message at 94 (YOU CAN'T...) 22030 if not open then exit through error message at 92 (YOU MUST FIRST OPEN IT) 22110 if #uses less than one then print NONE LEFT; exit to PICK FOE through line counting routine 22130 decrement #uses; reduce/increase hits by Heal Amt; print FEEL BETTER or WORSE message; if hits reduced below zero then set to zero 22140 update line counter; proceed to DO BATTLE subroutine to print state of health 22190 exit to PICK FOE routine
23000-23210 READ routine 23010 check for object S$; check to see if object is available; if not then exit through error message at 94 (YOU CAN'T...) 23020 if not drinkable then exit through error message at 94 (YOU CAN'T...) 23030 if not open then exit through error at 92 23040 print IT SAYS:; update line count 23210 print Effects defined by artifact data; exit to PICK FOE routine
24000-24150 FREE routine 24010 check for object S$; check to see if object is available; if not then exit through error message at 94 (YOU CAN'T...) 24020 if not Bound Monster then exit through error message at 94 (YOU CAN'T...) 24030 set some temporary variables 24120 if guard is present then print WON'T LET YOU DO THAT message; exit to PICK FOE through line counting routine 24130 if key exists and not available then print DON'T HAVE KEY message; exit to YOU SEE 24150 print FREED message; put freed monster in room, remove bound monster; update monster alignments and group totals; exit to PICK FOE through line counting routine
25000-25090 REQUEST routine 25010 if object is named then run object through PARSE routine to see if it parses into full command (REQUEST XX FROM YY) 25040 if not full command then get object requested S$ and monster name B$ 25050 check for monster named; if not present then exit through error message at 96 25060 if monster is enemy then exit through SMILE routine 25070 check to see if monster has it; if not print DOESN"T HAVE IT message; exit to PICK FOE through line counting routine 25080 print OKAY; update line count; transfer object from monster to player; increase weight carried WT by object's weight; if object was monster's ready weapon then mark him as unarmed 25090 exit through DROP routine to check for effects of object acquisition
26000-26100 WEAR routine 26010 check for object S$; check to see if object is available; if not then exit through error message at 94 (YOU CAN'T...) 26015 if object already worn then proceed to error message at 26100 26020 if not wearable then exit through error message at 94 (YOU CAN'T...) 26030 if armor then proceed to 26080 26040 if armor and already carrying shield then proceed to error message at 26100 26050 if armor then update player data to show that shield is carried if armor class is odd number (eg: PLATE AND SHIELD) 26060 if already armored then proceed to error message at 26100 26070 set player's armor data to this artifact 26080 mark object as worn; print WORN; exit to PICK FOE through line count 26100 print ALREADY WEARING message; exit to PICK FOE through line counting routine
27000-27040 REMOVE routine 27010 check for object S$; check to see if object is available; if not then print AREN'T WEARING IT message; exit to YOU SEE through line counting routine 27020 if object is player's shield then remove shield from player data 27030 if object if player's armor then remove armor from player 27040 mark object as carried by player; print REMOVED message; exit to PICK FOE through line counting routine
28000-28900 USE routine 28900 print TRY ANOTHER COMMAND message; exit to PICK FOE through line counting routine
29000-29070 RESUME GAME routine 29005 turn off ONERR 29010 ask RESUME GAME? 29020 get answer 29030 if "N" then delete saved game and restart program 29040 BLOAD saved game variables and pointers 29050 set screen to 40-col.; if saved game was 80-col. then set screen to 80-col. 29060 OPEN data files used during play 29070 preset command variables to no command; exit to YOU SEE routine
31000-31950 INIT routine 31005 set string variables to file names 31010 turn off ONERR; open EAMON.DESC; input database parameters; close file 31015 set # of Artifacts NA to number in database plus six for player's stuff; dimension all arrays 31020 input artifact data 31030 input monster data 31035 set up multiple monster numbers and group weight 31039 temporarily go to FAST.START code to save FAST.START info 31040 input player data from FRESH.MEAT file 31050 input player weapons into artifact array 31052 check for player weapons (name not "NONE"); increase # of artifacts variable NA for each one found; set weapon artifact type to "magic" if dice times sides exceeds 25; set weapon weight to 2; add weight to WT carried 31054 close open files 31055 delete FRESH.MEAT (disabled by REM) 31060 open EAMON.DESC and EAMON.ROOMS; set player Ready Weapon; set player dice and sides to that of Ready Weapon 31080 check player weapons for duplicate names 31090 if artifact name matches name of player's weapons then add "#" to front of artifact name; if rename is required then make second pass to ensure that no fresh name matches were generated 31100 check player's armor class AC and generate armor artifact to match; make wearable; set armor weight based on class of armor; mark as "worn"; add to weight carried; set armor class of artifact 31110 check player's armor class for shield and generate shield artifact if present; make it wearable; set weight to 10; mark as "worn"; add to weight carried; set armor class of artifact 31111 set player's armor to that of armor worn; mark player as "friendly" 31120 calculate effect of Armor Expertise and Armor Class 31130 read number of commands NC from data; dim command list array; read commands from data; calculate line breaks for listing commands; set next room R2 to 1 31140 set room to 1; set number of exit directions to 6; assign FF$ to the linefeed character (used by II+ 80-col. video cards to clear screen for HOME command) 31410 read SMILE responses into array 31420 read attack verbs into array; read attack result verbs into array 31430 set line counter to 50 to force HIT ANY KEY TO CONTINUE pause when game is ready to begin; set line length variable CP (used by line counter routine) to number held in memory location 768; if not 80 then set CP to 40 (note: the intro program pokes 80 into location 768 if 80-col. display was chosen) 31440 determine weapon type of Ready Weapon 31900 proceed to GO routine to set up Room 1 and begin game 31910 DATA: number of commands 31920 DATA: commands 31930 space for additional commands 31940 SMILE responses 31945 attack verbs 31950 attack result verbs
32000-32900 DONE routine 32010 clear keyboard strobe so no keypress is pending; execute screen pause 32020 close open files; reset SPEED spell 32030 if dead then exit game 32040 compile list of weapons carried 32050 if fewer than 5 weapons carried then proceed to sell stuff 32060 print "TOO MANY WEAPONS" message 32070 list weapons carried; get number of weapon to sell 32080 put cursor on "sell" input line; get player input; if invalid weapon number than repeat this line 32090 remove "sold" weapon from list; if still more than 4 weapons then relist weapons
32300 assemble retained-weapon data in preparation for return to Main Hall 32310 print SELL GOODS message 32315 remove shield and armor from artifact data 32320 compute value of artifacts carried 32350 print computed value 32360 add value to gold carried; if value is less than zero then set to zero 32370 execute screen pause
32500 set up ONERR vector to recover if Master disk is not inserted as prompted 32505 turn off II+ (Videx) 80-col. mode 32506 turn off IIe 80-col. mode 32510 print INSERT EAMON MASTER message; clear keyboard strobe 32520 get keypress; if not "C" then again 32530 print keypress to screen 32540 if player is dead then delete THE ADVENTURER from Master disk to tell the Main Hall that no one is returning from an adventure 32550 open CHARACTERS and write player data 32555 write more player data to file 32560 write player weapons to file 32570 write player name and record number in THE ADVENTURER 32900 run MAIN HALL to exit program
33000-33540 FAST.START routine 33005 lower the top of free memory to make a protected place for the search routine code; BLOAD the search routine 33010 set ONERR vector to recover if no saved game is found 33015 check for presence of saved game 33020 set ONERR vector to recover if no FAST.START file is found 33025 check for presence of FAST.START PARMS; input memory freespace parms 33030 if current memory free space matches parms then BLOAD FAST.START info; reset ONERR flag; proceed to INIT routine at 31040 to set up and start game 33035 (this line will be run only if present memory setup does not match FAST.START parms) delete FAST.START parms info; proceed to start of INIT routine to load artifact and monster info
33500 generate current memory free space info and save as FAST.START parms info; close all files 33510 BSAVE FAST.START variable pointers 33520 BSAVE FAST.START variables 33530 BSAVE FAST.START strings 33540 proceed to INIT routine at 31040 to set up and begin game
(Editor's Note: the following is somewhat exotic and rather advanced and stretches the way that an Eamon is meant to work. If you are up to them, these are some interesting tips. - TomZ)
In the June '94 EAG, Phil Moore asked, "Can two monsters in the same adventure carry the same weapon?" The answer was no, they couldn't. Actually, they can. Well, sort of... Two monsters can't be "carrying• the same weapon, but they can be made to appear to fight with it if you simply add two lines of code to the MAIN PGM (v7).
First, when you create your monster, leave the Weapon field at zero. Also leave the Room field of the weapon at zero. Now let's say that you want Monster 25 and Monster 29 to both use Artifact 60. Add this line:
7506 IF OF = 25 OR OF = 29 THEN W = 60
Also change the end of Line 7525 to:
...IF R < 41 OR W = 60 THEN PRINT " FUMBLE RECOVERED.": GOTO 56
That's all it takes. Line 7506 assigns weapon Artifact 60 (for attacking purposes only) to Monster 25 or 29 whenever they attack somebody. The changed Line 7525 keeps the weapon from being dropped or broken in combat.
Another good question is, "Can a group monster have varied weapons?" This is also possible. Let's say for example that we want Monster 24 to use either Natural Weapons (claws), Artifact 59, or Artifact 60. The following line will do it:
7506 IF OF = 24 THEN RL = INT (RND (1) * 11): W = (RL > 4) * 59 + (RL > 7)
Whenever Applesoft has a logical statement like "(RL > 4)", it will return either a 1 (meaning True) or a zero (False). The above Line 7506 first rolls a random number from 0 to 10. Then a check is made to see if the roll was greater than 4. If so, then the weapon artifact value becomes 59; if not, it stays at zero (natural weapons). Finally a check is made to see if the roll was greater than 7. If so, then the weapon becomes Artifact 60.
You'll also need to update Line 7525 as in the first example so that artifacts 59 and 60 can't be dropped or broken in a fumble.
Phil also asked about how Control-M can be added to REM statements and was told that you need an Applesoft editor. You can also do them with a disk sector editor if you know what you're doing. Let me know if you want instructions on the sector editor method.
Jun'95 MAIN PGM Tour, Part IV An English-language description of every statement in the MAIN PGM.
Mar'95 MAIN PGM Tour, Part III Also: Trick Programming for Monster Weapons: how to "share" one weapon artifact among multiple monsters; how to vary the weapons held by a group monster
Dec'94 MAIN PGM Tour, Part II Also: A Correction to the 10-Direction Tutorial from Dec'90 EAG issue
Sep'94 MAIN PGM Tour, Part I Also: On-the-fly Text Formatting: Frank Kunze's clever Applesoft code that automatically figures and makes line breaks in DESC text without any special line padding required.
Jun'94 A description of all of the programs included on the EAG Utilities Disk
Mar'94 Tips on effective Artifact usage: Monster Weapons; the USER Fields; Synonyms; Special Checks; Closed Artifacts
Dec'93 How to Cheat while Playing Eamon: a cookbook tutorial on how to get out of or around tough spots while playing an Eamon adventure
Sep'93 Designing and Testing your Eamon Adventure: The Design; Data Entry; Playtesting; Suggestions
Jun'93 The EAG Procedure for Submitting and Testing New Eamons for Release
Mar'93 Adding a New Command: a step-by-step cookbook tutorial
Dec'92 Bug Fixes You Can Do: what various error messages mean; how to recognize and perform easy fixes; how to do bug reports
Sep'92 A Complete Listing and Description of All Variables Used in the MAIN PGM
Jun'92 The Synonym Checker: A step-by-step cookbook tutorial
Mar'92 Back to the Basics: Monsters A step-by-step cookbook tutorial
Dec'91 Announcement and Program Listing of the UNIVERSAL CHECK FILES program
Sep'91 An Index of past designer articles; includes NEUC issues back to Mar'84
Jun'91 Back to the Basics: Containers How to program and use; step-by-step examples
Mar'91 Back to the Basics: Rooms and Doors A step-by-step cookbook tutorial
Dec'90 Using 10 Directions in Version 7.0 How to modify the MAIN PGM; pitfalls to watch for
Sep'90 Eamon Style and Technique: the Storyteller's Craft How to plot & write an Eamon adventure
Jun'90 Converting Eamon Adventures to ProDOS A step-by-step discussion of the procedure
Mar'90 Designing Descriptions for 40/80 Option How to write descriptions that look good in both 40-column and 80-column formats
Dec'89 Basic Eamon Routines Modifying Commands; POWER and USE commands
Sep'89 Using Effects for Eamon Games How to make & use your own special effects
Jun'89 Traps and Obstructions Guidelines for proper design to ensure maximum player enjoyment
Mar'89 The Parameters Option Making special Artifact types
Dec'88 Increasing free memory space
Sep'88 Efficient Applesoft programming
Jun'88 How to Properly Show Room Exits
The old pre-7.0 versions of the Eamon MAIN PGM used programming techniques that made clean and proper code, but caused the program to run very slowly, especially in large Eamons. A set of modifications evolved that came to be known as the "speed-up mods". Many Eamons have received these mods, as was indicated in the September issue's Eamon Listing.
If you have GPLE or Program Writer, the speed-up mods are very easy to make, and can be done in just a few minutes. If you don't have an editor and must make the mods by hand, they are still fairly easy to accomplish if you are familiar with the method of using the IJKL or arrow keys to recopy program listed lines. In most cases, the mods will result in a quite noticeable improvement in execution speed, vastly reducing those annoying delays.
Since the MAIN PGM was constantly evolving over the years, we can't simply give you a set of the mods to make. There are three cases where the mod cannot be made as illustrated:
1) the mod is already made 2) the code resides at different line numbers 3) the code is so different that the mod cannot or should not be made.
Instead, we must teach you how to recognize the old, slow code and how to change it by showing you both the original code and the modified code. In this way you can see for yourself what was changed and why.
YOU SEE original code:
130 IF ( INT (V%(ROOM) / 2) < > (V%(ROOM /2) THEN...
140 IF ( INT (V%(ROOM) / 2) = (V%(ROOM /2) THEN...
150 FOR M = 1 TO NM: IF MD%(M,5) = ROOM AND MD%(M,15) THEN PRINT MN$(M);" IS HERE.": PRINT
160 IF MD%(M,5) = ROOM AND NOT MD%(M,15) THEN PRINT DK$;"READ EAMON.DESC,R";M + 300: INPUT A$: PRINT DK$: PRINT A$: MD%(M,15) = 1: PRINT
170 NEXT M: FOR A = 1 TO NZ: IF AD%(A,4) = ROOM AND AD%(A,9) THEN PRINT "YOU SEE ";AN$(A)
180 IF AD%(A,4) = ROOM AND NOT AD%(A,9) THEN PRINT DK$;"READ EAMON.DESC,R";A + 100: INPUT A$: PRINT DK$: PRINT A$: AD%(A,9) = 1: PRINT
190 NEXT A: FOR A = A TO NA: IF AD%(A,4) = ROOM THEN PRINT "YOUR ";AN$(A) + " IS HERE."
YOU SEE modified code:
130 VZ = ( INT (V%(ROOM) / 2) = (V%(ROOM /2): IF NOT VZ THEN...
140 IF VZ THEN...
150 FOR M = 1 TO NM: IF MD%(M,5) < > RO THEN NEXT: GOTO 170
155 IF MD%(M,15) THEN PRINT MN$(M);" IS HERE.": PRINT
160 IF NOT MD%(M,15) THEN PRINT DK$;"READ EAMON.DESC,R";M + 300: INPUT A$: PRINT DK$: PRINT A$: MD%(M,15) = 1: PRINT
170 FOR A = 1 TO NZ: IF AD%(A,4) < > RO THEN NEXT: GOTO 190
175 IF AD%(A,9) THEN PRINT "YOU SEE ";AN$(A)
180 IF NOT AD%(A,9) THEN PRINT DK$;"READ EAMON.DESC,R";A + 100: INPUT A$: PRINT DK$: PRINT A$: AD%(A,9) = 1: PRINT
190 FOR A = A TO NA: IF AD%(A,4) = ROOM THEN PRINT "YOUR ";AN$(A) + " IS HERE."
PICK FOE original code:
320 FOR M = 1 TO NM: IF MD%(M,5) < > RO OR MD%(M,15) = 2 THEN 490
370 FOR M2 = 1 TO NM: IF MD%(M2,5) = ROOM AND...
400 FOR M2 = 1 TO NM: IF MD%(M2,5) = ROOM AND...
490 NBTL = (FD%(1) < TD%(1)): IF NBTL THEN NEXT M
PICK FOE modified code:
320 FOR M = 1 TO NM: IF MD%(M,5) < > RO THEN NEXT: NBTL = (FD%(1) < TD%(1)):
IF NOT NBTL THEN M = NM: NEXT: GOTO 500
325 IF MD%(M,15) = 2 THEN 495
370 FOR M2 = 1 TO NM: IF MD%(M2,5) = RO THEN IF...
400 FOR M2 = 1 TO NM: IF MD%(M2,5) = RO THEN IF...
490 NBTL = (FD%(1) < TD%(1)): IF NOT NBTL THEN M = NM
MONSTER PICK UP WEAPON original code:
7420 FOR A = 1 TO NA: IF AD%(A,4) < > ROOM OR AD%(A,2) < 2 OR AD%(A,2) > 3 THEN NEXT: RETURN
MONSTER PICK UP WEAPON modified code:
7420 FOR A = 1 TO NA: IF AD%(A,4) < > RO THEN NEXT: RETURN
7425 IF AD%(A,2) < 2 OR AD%(A,2) > 3 THEN NEXT: RETURN
It's also worth adding a line to the "RESTART" code. This code can usually be found at 19000, 29000, or 30000. Add this line (29000 example):
29005 POKE 216,0
Typically, I will add a few other minor fixes if they are merited. The most common one is that the DROP code may not check to see if the object is actually being carried.
Also, I will often scan for special-programming lines that check for room numbers. Usually, these lines will use AND in this manner:
510 IF ROOM = 10 AND AD%(12,4) = ROOM THEN...
Changing AND to THEN IF can radically reduce the number of comparisons made per turn:
510 IF RO = 10 THEN IF AD%(12,4) = RO THEN...
Note that the above change can ONLY be made in those cases where nothing happens if the first comparison fails. If you are not confident that you can determine this, then you should not attempt this particular mod.
A programming compromise was made with the way that the PUT command handles the weight of the artifact, to wit, it doesn't bother to do so. In other words, when the player PUTs an artifact into a container, he is not relieved of that artifact's weight.
This was judged to be an acceptable trade-off in relation to the amount of programming that would have been required to handle every possible case of opening containers and putting things into them. In actual practice, most artifacts are of low weight, plot development almost never cares about weight carried, and the impact is minimal.
However, if your Eamon requires the player to PUT some heavy artifacts, things can quickly reach the point where he can't pick up anything at all because his WT allocation is still loaded with the weight of things he's put elsewhere. This can be fixed during play by doing a DROP ALL, but that is hardly an elegant solution.
There are no easy fixes for this that don't involve either a lot of programming or some trade-offs somewhere along the line. Probably the easiest way to fix it would be to forbid putting the heavy objects in any carryable container (or have no carryable containers at all), and to add this line to the MAIN PGM:
21135 IF A%(A,4) < > - 1 THEN WT = WT - A%(Z,3)
This line will reduce the weight carried if the player is not carrying the container.
If you think about it a minute, I'm sure you will see that weight handling of carryable containers is a real can of worms that is best avoided in the design phase whenever possible.
There is a potential problem with the way the Eamon Master stores the character records in the CHARACTERS file. This problem derives from the fact that each record of the CHARACTERS file is only 150 bytes long. That is normally enough, but if your character has a long name and picks up several long-named weapons, there is a fair chance that the total data length will exceed the 150-byte limit. When this happens, the tail end of this overlong record overwrites the front end of the next character record when it is written back into the CHARACTERS file. This trashes that next record, crashes the Character Maintenance program, and can possibly crash the Main Hall program.
John Nelson printed a fix for this in the Aug'85 issue of the NEUC "Adventurer's Log", but it was a very complex fix that modified every program on the Master, added several new programs, and broke all of the existing character editors and listers. I have never seen the modified version, and I am afraid that I am responsible for eliminating it from the public domain because I did not ever make the mods to the Master in the EAG library.
Here's how to tell if you have the crash-proof modified version: among others it will have files named VILLAGE and CHARACTERS.EXT on it.
There is really no simple way to fix this. If you are serious about wanting a bullet-proof Master, you'll have to do the three pages of mods listed in the Aug'85 and Oct'85 issues, and will also have to modify all of your character utilities as well.
The existing CHARACTERS records have enough room to accommodate a very powerful character as long as his name plus the weapon names don't add up to more than about 45 letters. The actual allowable length will depend on the size of the numbers in the character's and weapons' stats. I recommend for a rule of thumb that you adopt a really short character name like SAM or BOZO and try to keep the total number of letters in your weapons' names to about 40 letters. This is a very conservative rule and should comfortably keep you out of trouble unless you have cheater-superman stats. Another place to scrounge extra space is by keeping the two gold numbers down to three or four digits.
Here are some more suggestions:
1) Use the FRESH SAM program to play Eamon and don't use the Main Hall at all. That's what I have done for 10 years and is probably why I have never seen the problem.
2) Once you get a pretty fair set of weapons that falls within the name-size guidelines, quit trading up every chance you get. Likewise, once you get a decent stash built up, quit grabbing treasure that will enlarge the gold numbers.
3) Just put one character in the CHARACTERS file. Then it will never matter how large that record gets. However, be advised that names larger than about 15 letters will crash the Character File Maintenance program.
If for some reason you want to have more than one character, put each one on his own personal copy of the Master disk. 5.25 disks are CHEAP.
Alternatively, you could keep multiple single-character CHARACTERS files on the same disk by giving them difference filenames and renaming the one in current use to CHARACTERS.
4) Keep a backup copy of your CHARACTERS file! Making an occasional backup of the Master would take care of that for you. Or you could put an extra copy on the Master under a different file name. I personally do both. See item 6 below.
5) Don't use a cheater-superman character. Keep everything but the spell abilities in two digits at most and the spell abilities in three digits. Even these limits will permit an absurdly strong cheater character.
6) If the Eamon you are playing changes your character's name from FRED to something like SIR BOSSMAN or QUEEN OF THE PURPLE FLOWERS, and you know that you are probably pushing the record length limit already, then don't return to the Main Hall. When you reach the end of the game, halt the program without returning, and then reboot the Master and resurrect your character.
If you don't find out that this happened until you've already returned, then do a letter count of the names, and if it's iffy use the Character Maintenance program to make sure that the CHARACTER file is still OK. If there is any question in your mind, then delete the CHARACTER file and replace it with a copy of your backup.
For those who would like to design their own Eamon adventures, but need help getting started, the following summary of the process may help.
The first thing to do is be sure you have everything you need.:
1. Dungeon Designer Diskette preferably version 5.0 or above
2. A scratch diskette (blank)
3. The DDD Manual provided on the DD Diskette
4. A map of how the dungeon is to look
5. A list of all the monsters and Artifacts
6. A theme for the adventure what the adventurer is suppose to accomplish.
The first thing you have to do is boot the DDD. Be sure the DDD is write protected by putting the little tape dealie over the notch (technical Jargon!)
You will be presented with a menu. Select the ‘Initialize a New adventure’ function. The program will start and you’ll see a flashing message to replace the DDD with a blank diskette now. Better do what it says, lest thou be forever sorry.
The program then prompts for the name of the adventure, your (the author) name, and the adventure number. You should be clear on all of these but the adventure number. Use 99 for the number, since this will he assigned by the library when you submit the adventure after finishing it.
The program will also prompt for the number of directions. Until some kindly soul perfects the ten direction functions, we will use the six direction. This is simply the number of directions YOU may move. (North, South, East, West, Up and Down = six)
The program will then initialize the diskette and create some programs on that diskette. You now have the beginning of the adventure to end all beginning adventures. If you will do a catalog, you will notice a text file called SAVE BASR PROGRAM HERE or SAVE LEADIN PROGRAM HERE. Whichever it is, delete it.
Then load the LEADIN FROGRAM from the DDD. If you don’t find a program called LEADIN PROGRAM, you have an old version of the DDD. (Send in a check.) Until you have a new version, you’ll have to wing it. Write your own program to print out a description of the adventure and when that is done, have it run MAIN PGM. If you do have LEADIN PROGRAM, all you have to do is type in print statements to print the description of the mission. The LEADIN PROGRAM takes care of headings, wishing the party luck and other such pleasantries.
Once you have the LEADIN PROGRAM ready, save it to your diskette under the name of your adventure. Example if you entered Plato Playground for the adventure’s name, then type SAVE PLATO’S PLAYGROUND. It should save this as the second name in the catalog.
Now load the Main program from the DDD into memory. This program will be under the name BASE DUNGEON PROGRAM or BASE PROGRAM 2.0 or MAIN PGM depending on the version of the DDD you have. Save this program on your diskette under the name MAIN PGM. You will probably need to make program modifications to this program later, but for now, just save it as it is.
You are now ready to start entering data. This is done by running DUNGEON EDIT from the DDD. The things you will need to enter are Rooms, Artifacts, and Monsters. The DDD manual will explain these things in detail so I don’t have to here.
Once these files have been created, you will be ready to make your program modifications. All Eamon adventures have them, simply because they would be too plain without any changes at all. In order to make the necessary program changes, YOU will have to have a fairly decent knowledge of Applesoft Basic
Use the information provided in the Dungeon Designers Manual to provide the details on how to create an adventure, but the above steps; will provide a good skeleton procedure.
When you want to test your adventure, you will need a FRESH MEAT file on your adventure diskette. This can be done using TEST BENCH from the Eamon Utilities for designers or by using the Master diskette.
When you are satisfied with your adventure, have a friend test your adventure it. When you are completed, send us a copy of it. We will review it and distribute it if you like.
Since this is only our second newsletter and the first one covered a summary of the design process, we thought it would be appropriate to begin at the beginning in this column and work our way into the more advanced designing tips in subsequent issues. Those who are very experienced in designing their own adventures may think we are being too simple, but please bear with us - we will try to build a solid foundation of knowledge and then get into the more advanced techniques.
The Eamon system consists of a master diskette containing multiple programs and individual adventure diskettes that are completely independent of each other. The master diskette passes control -from one program to another by writing any needed in-formation into a text file and running the next program. The main programs that are run on the Master diskette are:
The Wonderful World of Eamon - gets the name of the player and looks it up on the file. If found, it runs Main Hall. If it doesn’t find the name, it runs a program called New Characters.
New Characters asks you if you are male or female and builds your character. When it has finished creating your character it opens a temporary text file called THE ADVENTURER and passes the character’s name and record number to Main Hall which it runs next
Main Hall - This is the central hub of the system. The character buys and sells weapons and learns spells here in order to prepare himself for an exciting life of adventuring. When the character is ready, they select GO ON AN ADVENTURE. The program then deletes the character record and requests an adventure diskette. When the player presses a key the program assumes the diskette has been changed and writes the character’s attributes into a file called FRESH MEAT. The program then opens a file called EAMON.NAME to read the name of the adventure. The final step is then to run the program by that name.
On the adventure diskette there are usually two programs. The first has the name that matches the name found in EAMON.NAME. This program prints the description of the adventure and the runs a program that is usually called MAIN PGM. The second program (MAIN PGM) is the main adventure program. It is the program you will modify to have your own special effects. The remainder of this article will concern this program.
The most important thing to know about this program is the variable names and the tables that are used for monsters and artifacts. The monster table has a variable name of MD% and the artifact table has a variable name of AD%. Both of these tables are two-dimensional tables. That is, they require two subscripts or pointers. The first pointer identifies which item is being referred to and the second pointer is used to access the monster or artifact attributes.
Let’s look at these tables in more depth. The monster table contains all the data for a monster. The first subscript is the monster numbers the values contained in the second subscript determine the attribute being accessed. They are:
1 = Hardiness
2 = Agility
3 = Friendliness
4 = Courage
5 = Room
6 = Weight
7 = Defensive Odds
8 = Armor
9 = Weapon Number
10 = Odds to Hit
11 = Dice
12 = Sides
13 = Damage
14 = Reaction
15 = met flag
The artifact table has a similar arrangement:
1 = Value
2 = Type
3 = Weight
4 = Room
5 = Complexity - only if weapon
6 = Weapon Type - only if a weapon
7 = Dice - only if a weapon
8 = Sides - only if a weapon
The designer can do amusing things by manipulating these fields and printing messages to the player. For example to make a scroll disappear all the designer has to do is change its room number to zero (or some other value that will never be a valid room number). He does this with a statement like AD%(8,4) = 0.
He could make the adventurer stronger or weaker by modifying his hardiness (field 1). He could scare a monster by setting the monsters courage to zero or make him braver by setting it higher. You could even change a treasure into a weapon by changing the type to a 2 or 3 and setting the other fields (5-8) with appropriate values for a weapon.
Knowing these facts is a vital part of being able to design an adventure and make interesting programming changes. Next issue we will cover some local magic and secret passages.
I was asked to provide a set of standards for a typical EAMON adventure. What follows is, of course, personal opinion and not gospel. But PLEASE consider these points when next you create a dungeon.
I. BE CONSISTANT! Your adventure is set in a world of fixed technology, laws, and environment. Nothing gripes me more than striding dawn a castle corridor - in full plate armor - and being mowed down by a Nazi with a machine gun! If you’re in a medieval scenario, then by all means fill it with wizards and warriors, ogres and princesses, etc. A .357 Magnum or a flashlight simply do not belong. Conversely, who wants to run around in chain mail when everybody else has blasters?
2. WHAT’S THE POINT? An adventurer should have a goal. If the adventure is just an excuse far violence, save your time and bucks and go watch a football game on T.V. On the other hand, you’re not out to rebuild Atlantis, either. Use your judgment: a rescue, an assassination, a magic sword keep it simple, but stick to it.
3. AT THE ZOO. ‘There we were, fighting two dozen orcs when in walks this blue dragon ..." In a pig’s eye. Unless they kept the big lizard as a pet, they’d probably avoid it like the plague. This borders on #1 above, but it deserves separate mention: contrary to popular belief, every little hole in the ground does NOT have a life-form lurking in it. And where there are life-forms, the ratio of predators to prey 5 like 1:15. Again, use your judgment: orcs and dragons are both predators, and the competition will be pretty rough. Personally, I’d like to see more prey in dungeons, castles, etc. They’d make for great comic relief, and when you did run into the local predator, it would make for a far nastier surprise.
4. THE OBSTACLE COURSE. A complaint I heard recently was about an adventure where practically every door gave the adventurer an electric shock. It eventually killed him six doors into game. While not really an advocate of fair play, some early warning - or an available defense - sure couldn’t have hurt here. Any series of obstacles (no matter how many or how difficult) should not be insurmountable; using a Power Spell to break out of a room is unfair, stumbling blindly in a dark cave is NOT unfair. Consider the odds when designing a trap, a riddle, or a confrontation with a monster.
5. BE ORIGINAL! My wife (John’s wife, too) collects Harlequin Romances by the box-full. I’ve looked at a few of them, and they’re all the same - only the names and locations have been changed to keep the reader awake! Variety is the spice a + life, and the best adventures have a totally different slant to them. Try to avoid the Thirty-room-six-monsters-and-a-wizard syndrome. BE CREATIVE!!
This issue we will cover more of what we covered last issue, but in more detail: LOCAL PIA6IC. If you read the Eamon Player’s manual, it describes universal and local magic. Universal magic is the magic you can buy at the Main Hall and it works roughly the same everywhere you go. Local Magic is magic that is unique or special to a particular adventure.
Local magic is that created by the de5igner when he designs and programs the adventure. It consists of printing neat little messages to the player and modifying some information in the computer to simulate some action taking place.
Let us say, for example that you wanted to make the adventurer grow old if he drinks a certain potion. This could be simulated by printing a message such as YOU ARE GROWING OLDER BY THE SECOND. YOUR HAIR HAS TURNED WHITE, YOUR SKIN IS BECOMING EXTREMELY WRINKLED, AND YOU ARE GROWING WEAKER’’. You must then modify values to simulate the age increase. There is no age kept for an Eamon character, so you don’t have any variable here to contend with, but you may lower the character’s agility which is contained in he variable MD%(0,2) lower his defensive odds (which normally contain zero, so you could make them negative and lower his strength (contained in variable MD%(0,1).
Using the different fields, you can do almost anything. I will cover the most commonly wanted tricks and let you, as the adventure designer decides what you want to do with it.
One common thing is secret passages. Although this is not really a magical type of effect, it is a common feature and I promised to cover it last issue. Secret passages are handled automatically in DOD version 6.0, but in version 5.0 and before, it required the designer to program these. To program a secret passage, you may do it one of two ways. The first and easier method can also be more dramatic. That is to teleport the adventurer into the new room as soon as they discover the passage. A message can be printed to be as dramatic or as different as you wish. Ta effect the change in rooms, all you have to do is change the variable ROOM to the desired room number with a statement such as ROOM nn. You then have to branch to 3500 of the main program. The second method is a bit more sophisticated and the adventurer will not be forced to use the secret passage immediately. This is done by having a switch (or variable) to indicate whether or not the adventurer has discovered the passage yet. In the move routine, you would check this switch and if the passage had been discovered, allow the move in that direction. Far example, in the look routine, I would code IF ROOM = 54 THEN L1 = 1: PRINT "YOU FOUND A SECRET PASSAGE TO THE WEST!". Then in the Move routine I would code IF R2 = -55 AND L1 THEN R2 = 55: GOTO 3500
Another common adventure feature is to love artifacts or monsters into or out of the room. The variable for an artifact’s location is AD%(A,4) where A is the artifact number in question. The variable for a monster’s location MD%(M,5) where M is the monster’s number. The variable ROOM contains the current room number that the adventurer is in. Therefore, to move an object - be it monster or artifact - into the room you change the corresponding room number variable. For example, to move an artifact into the room, the code might be something like: PRINT ‘THERE IS A BRIGHT FLASH AND A MAGIC SWORD APPEARS!’: AD%(1,4} ROOM. To remove an object from the room, the item’s location is changed to zero. For example, to take the sword away from the adventurer or out o the room it is currently in, the code might be: PRINT ‘THE SWORD VANISHES!’: AD%(1,4) = 0. Monsters are a bit more complicated to teleport around, however. When a monster is caved around, you have to compensate for whether he is friendly, or unfriendly, and how he will react to these changes. This is done by setting the variable R3 to ROOM and performing the subroutine at line 3600 after changing the monster’s room number. This extra step insures that the monster knows he has been teleported.
That’s about all the space we have for this issue, so I’ll wrap it up for now. Next issue I’ll cover locked doors, gates and how to operate and program them.
To make a gate block a passage, you can do it one of several ways. Version 6.0 of the Dungeon Designer Diskette supplies the designer with a method that requires no programming, so we will not discuss this version here. If you have version 6.0, simply use the method provided.
For version 5.0 and prior the following may help make the design easier for the author. Many different ways can be found by looking at how others have done it in various adventures. If you would like to look at how others have done it, the following adventures are along those that contain gates where you have to have the key or some kind of a passcard to get through. The list is by no means complete, but it will demonstrate a wide variety of methods.
Lair of the Minotaur - Iron Gate
Devil’s Tomb - Steel Door
Abductor’s Quarters - brick wall
Quest for Trezore - Brass Door
Hogarth Castle - cell door
The Black Death - Iron Door, safe, desk, file cabinet
Nuclear Nightmare - gate, bubble, vault
Assault on the Mole Man - gates
Revenge of the Mole Man - gates
Here we will go through one of the easier methods and I think one of the better ways to handle locked doors.
The method you use will depend on how you want to activate the opening of the gate. Some adventures will have a special UNLOCK command, some will simply check to see if you are carrying the key and if so, let you pass. Others will have you use an OPEN command and if you are carrying the key, let you go and if not, print a message that the gate or door is locked.
The easiest way is to simply check to see if the person is carrying the key, and having two artifacts for the gate or door. One artifact would be the gate or door when it is open and the other would be the gate or door when it is closed. To operate the door the program would have a fixed number for the door that it would check for.
For example, if the key were artifact #6, and the closed/locked door were artifact #7 and the open/unlocked door were artifact 18, the program could work like this:
1. In the move routine:
3035 IF AD%(7,4) = ROOM AND D=3 THEN PRINT ‘THE DOOR IS LOCKED. YOU’LL NEED A KEY’:GOTO 100
The variable AD%(7,4) is the room number of the locked door. The D = 3 check means the door will block passage only to the east. (East is the 3rd direction in NSEWUD in the command table and D is always the direction of movement). It is compared to the Room number to see if the door is locked. (If it is in the room, the door is automatically locked, because the OPEN routine will do this:)
2. An OPEN command will be needed to get the locked door (artifact #7) out of the room and the open door (artifact #8) into the room:
20000 REM /// OPEN COMMAND
First, check to see if they typed OPEN DOOR or OPEN (name of door) instead of OPEN LUNCH BOX or some such silliness:
20010 IF (S$ = AN$(7) OR S$ = "DOOR" ) THEN GOTO 20100
If they did say something crazy, print an error message:
20020 PRINT "I DON’T UNDERSTAND.":GOTO 100
Now, for the routine that will verify everything is o.k. First, we have to make sure the door is really in the room, and if not, print an error message:
20100 IF AD%(7,4) <> ROOM THEN PRINT ‘THERE’S NO DOOR HERE’’: GOTO 100
Now check to see if they have the key. If the room number of the key (artifact #6) is = -1, then the person does have the key. If this is the case, you open the door by removing the locked one (changing its room number to 0) and bringing the open one (artifact 18) into the room by setting its room number equal to ROOM:
20110 IF AD%(6,4) = -1 THEN PRINT "YOU’VE OPENED THE DOOR!!": AD%(7,4)=0: AD%(8,4)=ROOM: GOTO 300
If the person doesn’t have the key, we have to print a message:
20120 PRINT "IT’S LOCKED. YOU DON’T HAVE A KEY THAT FITS.":GOTO 100
The door or gate has now been installed and should work with no problems. The adventurer will come to the door or gate, try to proceed in that direction and get the message YOU CAN’T G0 THAT WAY! The description of the gate or door should explain that the east exit (or whichever exit it is) is sealed off by the gate or door. The adventurer may then try the open command. If he has the key, the gate will open.
An alternative would be to have a USE command for using the key. This would mean the adventurer would have to know which key to use or would have to experiment. This could be done to make it more challenging for the player.
The USE command may look something like this:
22000 REM /// USE COMMAND
First we have to be sure the player provided a subject to be used. (i.e. KEY or whatever the name of the item he is trying to use.)
22010 GOSUB 4900 : IF S$ = "KEY" OR S$ = AN$ (n) THEN 22100
If there is anything else in the adventure that can be used, the coding to check for this would go between 22010 and 22099.
Now we need to print a message in case they try to use something the program doesn’t recognize:
22099 PRINT "I DON’T KNOW HOW TO USE THAT.":GOTO 100
The actual use key portion of the routine:
22100 REM /// USE KEY
See if the adventurer is really carrying the key:
22110 IF AD%(6,4) <> -1 THEN PRINT ‘YOU DON’T HAVE ANY KEY’’: GOTO 100
Check to see if the locked door is in this room:
22120 IF AD%(7,4) = ROOM THEN PRINT ‘THE DOOR UNLOCKS AND SWINGS OPEN!:AD%(7,4) = 0: AD% = ROOM: GOTO 300
22130 PRINT ‘THE KEY DOESN’T FIT ANYTHING IN THIS ROOM.’:GOTO 100
An added complication could be inserted by making the adventurer use both a USE (or UNLOCK) command and an OPEN command. This would probably require the use of a switch. A variable (for example UL for UnLock) would be set to 1 when the door has been unlocked. Then, in the OPEN command, this switch would be checked and if it is not set, it would say the door is locked. If the switch were set the open artifact (#6 in the above example) would be put into the room by setting AD%(8,4) = ROOM and the closed/locked artifact (#7 in the above example) would be moved into the twilight zone (room 0).
Another alternative - one that does not require the use of two artifacts (one open and the other closed) for the door - would be to set switches to indicate when the door is locked or unlocked. You could set up this kind of door without any kind of artifact at all. If you did it this way, instead of changing the room numbers of the open and closed artifacts, you would set the switch. Zero would be locked, 1 would be unlocked. When the adventurer comes to the locked door, the direction of movement code would be something like -1 for the direction blocked by the door. The program would then have statements such as that below in the move routine:
3070 IF R2 -1 AND UL THEN R2=nn
The nn in the above statement would be the number of the room to move into.
There are probably millions of ways to handle locked doors and gates in Eamon, this has been just a sampling. It should help out if you get stuck or do not wish to re-invent the wheel.
by Bob Davis
‘Okay, now I’ve got the key and I’ll unlock the safe and ...‘ - BOOP’ SYNTAX ERROR LINE 21140. Cruddy Bumpkins! Now I’ll have to change the line and start the testing all over - go through 43 rooms, find all the artifacts needed, kill the troll …"
How many hours are wasted testing and retesting, and how many bugs are not detected because of this tedious method will never be known, but we can guess - many. If only there were easier and faster ways to test newly written adventures…
Well, here they are! The following routines can be temporarily added to MAIN P6fl (versions 5.0 and 6.0) to facilitate testing. After testing is complete and the code is removed, one final test should be given.
FRESH MEAT - Remark the line that deletes FRESH MEAT. This will allow you to
RUN MAIN PGM anytime without having to come from the Master Diskette (after you do it the first time.) Type in the following (or insert REM if you have a line editor.)
1055 REM ?D$ "DELETE FRESH MEAT’
CAN’T KILL ME - When testing a monster’s toughness and/or death traps, this little routine will revive you whenever you die, setting your damage to zero. A change is needed in the ATTACK routine so the program doesn’t bring in the artifact that it thinks is the adventurer’s dead body (lines 7640 and 7690).
2005 IF DIE THEN DIE=0:?: ?‘YOU’RE NOT REALLY DEAD.’: MD%(0,13)=0: ?‘YOU’RE FEELING MUCH BETTER NOW. ‘: GOTO 210
Change 7640 to be;
7640 MD%(DF,13) = MD%(DF,13)+D2: IF MD%(DF,13)>=MD%(DF,1) THEN 7690
7640 MD% (DF,13) = MD% (DF,13 )+D2: IF MD%(DF,13) >= MD%(DF,1) THEN 7700
7690 IF NOT DF THEN ?:?"YOU ARE DEAD!" : GOTO 740
AUTO KILL - This will kill any monster in the Tool that you deem unfit to live. To activate, SAY KILL. This will set an indicator (which can be shut off by typing SAY KILL again) and then simply ATTACK monster name. For example, if you knew a tough dragon was in the next room and you needed to kill him to get past and test the next part of the dungeon you would type SAY KILL, move into the next room and type ATTACK DRAGON.
7295 IF TEST THEN OF=0: DF=M: D=90: S=5:GOSUB 7635:GOTO 300
16800 IF LEFT$ (S$,4) = "KILL" THEN TEST = NOT TEST GOTO 100
TELEPORT - This routine will teleport you, your friends and possibly your enemies to the room of your choice. All you need to do is type SAY ROOM room number.
16820 IF LEFT$(S$,4) = "ROOM" THEN R2=VAL (MID$ (S$,5)) : GOTO 3500
GIMME IT - This routine will give you any artifact by the artifact number without adding its weight to your carried weight. Just SAY GIMME artifact number.
16840 IF LEFT$(S$,5) = "GIMME" THEN AD% (VAL (MID$ (S$,6)),4)=-1: GOTO 100
To remove these changes when testing is complete, delete the following line numbers:
2005, 7295, 7690, 16800, 16820, 16840, and lines 1055 and 7640 should be changed to:
1055 ?D$"DELETE FRESH MEAT"
7640 MD% (DF,13)=MD%(DF,13)+D2: IF MD%( DF,13) >= MD%(DF,1) THEN 7700
With these test routines, testing should be faster, less tedious and (hopefully) more accurate.
by Bob Davis
(John and I decided to swap a few columns this time around just for a change of pace.)
Hello, Adventure Designers. Hel-lo, Bob.) Today we are going to briefly discuss dead bodies (ech!) and then move on to Eamon magic and special effects.
The dead bodies of monsters are set up as artifacts on the artifacts file. They must be the last artifacts and in the same order as the monsters on the monster file. Therefore, if 40 artifacts exist on the file (some of which may be dummy entries for last minute additions) and 20 monsters exist within this dungeon, the dead bodies would be placed on the artifacts file beginning with #41 through #60 with artifact #41 being monster #1’s dead body, #42 is monster #2’s dead body, and so on.
When MAIN PGN recognizes that a monster has been killed, to find the dead body it uses this formula in line 7700:
A2 = DF + NZ – NM
Where A2 will equal the artifact number of the monster’s dead body,
DF = Defender (number of the monster that died),
NZ = Total number of artifacts in the dungeon not counting adventurer’, artifacts brought in), and
NM = Total number of monsters in the dungeon.
If monster number 2 were to die, the formula would calculate artifact #42 using the values in the previous example. 42 2 + 60 – 20
After this number is derived, the monster is taken out of the room; its ready weapon (if any) is placed in the room along with the dead body. (All of this takes place in line 7700.) When the main loop (lines 100 - 900) is given control again, it realizes you have not seen the dead body or the weapon and will print the long description of each. This is most useful for putting in a description of the monster dying and indicate with the name of the artifact that a dead body is present.
LONG DESCRIPTION: The pirate staggers and falls. With his last breath he utters a foul curse at you having to do with decomposing in a hot place.
ARTIFACT NAME: Pirate Rick’s lifeless body.
There is one drawback to this; the long description will print that the pirate is dying again if an EXAMINE is done on the dead body. Far myself, I can live with it.
The Magic of Eamon
Original magic and special effects tend to spice up an adventure, giving it an extra flavor arid personality of its own and, surprisingly enough, it is not very hard to do. Imagine having this effect in your adventure: If a character grabs a hornet nest, many small winged creatures pour out of the nest and systematically penetrate the adventurer’s body and will keep attacking to the point of death, unless ... the adventurer does a POWER spell to bring a hard rain that knocks the insects to the ground and drowns them in the puddles. Sound like a lot of work Fear not; a few simple program statements and two descriptions on the effects file and you are ready. Here’s how…
The very first thing your MAIN PGM will need is a sub-routine that will read the effects file. A variable (EF) for the number of the record to be read will be used. I like to put this routine at 25000.
25000 REM /// READ EFFECT ///
25020 PRINT DK$’READ EAMON.DESC,R’;EF+200
25040 INPUT A$:PRINT DK$:PRINT A$:PRINT
Notice on line 25020 the record number is EF+200. The EAMON.DESC file really is four files in one (room, artifact, effect, and monster descriptions) and the effects descriptions start at record 201. This is all handled automatically when you add effects to the file using any Dungeon Designer diskette. The variable EF will be set up in the magic routines before doing a GOSUB 25000.
Let’s say, for simplicity, that the effect descriptions have already been placed in the effects file as follows:
EFFECT #1 - Hornets stream out of the nest in a buzzing torrent of winged barbs, their stings like hot daggers. You wave your arms futilely and fall to the ground, rolling frantically.
EFFECT #2 - The sky quickly darkens and a loud thunderous clap is heard followed immediately by sheets of rain. The hornets are knocked to the ground and drowned in newly formed puddles.
Along with the effects! Let’s assume the hornet nest is also already on the artifacts tile as artifact #10 and it is in room #20 (in a tree at course). The swarm of hornets will be monster #4 and must be placed in room #0; this is so they will not show up anywhere in the dungeon until the adventurer picks up the nest. Make the courage equal 200 so the adventurer cannot flee from them and the total damage (dice times sides) should be high enough to hurt the adventurer no matter what armor he has. The hornets’ dead bodies will be artifact $44 see first part of this article.)
Now, some of you are saying "This is easy?". When a special effect is set up, the most realistic ones will have all described items in the special effect defined as monsters, artifacts, and/or effects. Here is a short comprehensive list of each item in this example the way they were set up above.
EFFECT: #1 Adventurer picks up nest.
#2 Adventurer says POWER after hornets appear
ARTIFACT: #10 Hornet nest.
#44 Dead hornets
ROOM: #20 Meadow with tree.
MONSTER: #4 Hornets.
Obviously you must keep track of each item. An easy way to do this is by obtaining a list of room, artifact, and monster names using the EAMON LIST R.A.M. on the Utilities II diskette (which is the designer utilities diskette). A list of effects can be obtained from either the DUNGEON LIST or DUNGEON EDIT programs (version 5.0 or above).
Once all the items (hornets, hornet nest, dead hornets, etc.) are defined, all is ready for the special programming code that goes into MAIN PGM to make the magic happen. When the adventurer enters the meadow with the tree (room #20), he will see the hornet nest because its room number is 20. If this item looks interesting enough or the adventurer doesn’t know any better, he will pick it up. When this happens, the GET routine is executed (lines 4000 - 4299). The line to make the hornets appear goes after 4200, which should already have a REMark on it like INSERT HERE SPECIAL EFFECTS OF PICKING SOMETHING UP.
4210 IF A = 10 THEN EF = 1 :GOSUB 25000: MD%(4,5) = ROOM: R3=ROOM: GOSUB 3600
Where: A number of artifact adventurer picked up (already set up for you),
EF = the number of the effect to print,
GOSUB 25000 will read the effect and print it
MD%(4,5) is the room number (field 5) of monster #4,
ROOM = room number adventurer is in (also set up),
R3 = ROOM:GOSUB 3600 must be executed when a monster is brought into or leaves the room to determine reactions and set up necessary variables for the battle routines.
In summary, the above line will determine if the adventurer picked up the hornet nest (artifact #10) and if so, will print effect #1, place the hornets in the room and check the hornet’s reaction (obviously you would want to set the hornets up with a friendliness of zero).
Unless the adventurer does a POWER spell, the hornets should unceasingly attack. If a POWER spell is invoked, the rains will come and drown the bugs. A line should be added at the beginning of the POWER routine (lines 13000 - 13999) before any other magic to make sure the hornets attacking gets checked first.
13005 If MD%(4,5) = ROOM THEN EF = 2: GOSUB 25000: MD% (4,5) = 0 :AD%(44,4) = ROOM:R3= ROOM: GOSUB 3600:GOTO 300
Where: MD%(4,5) = room number (field 5) of the hornets (monster #4),
ROOM current room of adventurer (do not check for room 20 in case adventurer fled to another room),
EF = 2: GOSUB 250000 to print effect #2,
AD%(44,4) = room number (field 4) of hornets’ dead bodies (artifact #44),
R3 ROOM: GOSUB 3600 to reset battle variables,
GOTO 300 to return to the main loop.
In summary, this line will check if the hornets are in the room; if so, effect #2 will print, the hornets are taken out of the room, the dead hornets are brought in the room and the battle variables are reset so the program doesn’t think a fight is still in progress after the hornets drown.
The effect descriptions are very useful in the magic and special effects of Eamon. Up to 250 characters can be used to describe the event plus, more than one effect can be read if desired.
The special code itself is very short and simple. The trick is to know where to put the code (each command routine has a remark to start it) and the variables to check and/or change. To help you in that area, below are listed the more common effects performed in Eamon with the variables needed and the proper routines to perform. the routine the code is added to sakes the difference if a GOTO 300 (return to main loop) is needed or not.
1. Assess damage to the adventurer.
DF=0 : defender is adventurer
D2=n : amount of damage to assess
GOSUB 7640 will assess the damage
Assessing random damage.
A= MD%(0,8) : set up adventurer’s armor (set to zero to bypass armor)
S : maximum sides of dice
D : maximum number of dice
(D x S = maximum damage)
DF = 0 : defender is adventurer
GOSUB 7635 : computes random damage and assess it to the adventurer.
2. Healing the adventurer.
MD%(0,13) = MD%(0,13) : heal amount
GOSUB 7650 : Displays injury status (ROGAN IS HURTING).
3. Changing adventurer’s spell abilities.
SA%(S) where S = 1 to 4
1 = Blast ability
2 = Heal ability
3 = Speed ability
4 = Power ability
These are the permanent spell abilities kept in the character record. The current abilities are stored in S2. In the spell routine is a line:
11530 S2%(S) = S2%(S) /2
This reduces the ability to successfully cast a spell in this adventure by half each time the spell is attempted. If you would like the adventurer to be able to cast many POWER spells, change this line to be:
11530 IF S < 4 THEN S2%(S) = S2%(S) /2
Or the line could be deleted all-together.
4. Some common adventurer’s attributes that can be changed without executing special routines:
MN$(0) - name
MD%(0,1) - hardiness
MD%(0,2) - agility
SEX$- M or F
AE- armor expertise
GOLD- carried gold
Teleporting the adventurer, monsters and/or artifacts into/out of rooms was covered in the August 84 issue of the newsletter.
by John Nelson
This issue I would like to covet three different areas. First, some guidelines you should have in mind if you are intending to distribute your adventure through the club. Second, some limitations of the Eamon system in general, and finally, normal limits and recommended levels for the various data fields required to define an Eamon artifact or monster.
The following points cover some guidelines
1. We do not like to accept and may reject adventures that have artifacts, monsters, or scenes of extremely questionable taste. Some of these adventures have gotten into the library that we did not filter out, but in the future, we may filter such adventures from the regular list of Eamon adventures or place warnings in the adventure list. We believe Adventures should have some redeeming value.
2. Adventures should have a description of the intended goal or mission or at least how the adventurer came to find himself in his current situation. Some adventures have been received that contained absolutely no description of what was supposed to be done. If there is a reason for this lack of explanation, we understand this and accept it. If not, it isn’t fair to the players.
3. Adventures should be somewhat exciting and unique. Special programming is almost a necessity for a good adventure. While we will not reject an adventure based on a lack of special programming, it may not receive as high a rating as those adventures that do contain special programming. For example, an adventure that has only 18 rooms, 10 monsters, 30 artifacts, no effects, no special programming whatsoever, and boring descriptions such as ‘YOU SEE A SWORD for every artifact, etc. may receive a rating of 0 or 1. These adventures would be available to anyone wishing to waste their time in them, but would not be recommended.
4. When an adventure is completed, please send a copy on standard 3.3 DOS apple diskette. Tell us whether the adventure is being submitted for review or for distribution. If you do not specify, we will assume that it is being sent for distribution. We will test it and if you have submitted it for review, we will return our comments for suggested improvements, bugs, (if any) and give an honest opinion of how we liked it. If you wish it to be distributed, we will put it into production status.
These guidelines are necessary to maintain the high standards and corals of Eamon. If we do not fallow them, the quality of the average Eamon adventure will suffer and Eamon will lose much of its charm. We could have hundreds of adventures, but we’d rather go more for quality than quantity.
And now onto the Eamon system limitations...
The Eamon system, for all its magnificence, has the same shortcomings that any computerized adventure system has. It is limited by the number of characters that can be put into memory, the size of the diskette, the intelligence of the programs and the author’s creativeness.
The designer and the player both have to recognize the limitations of the system and not be too nit-picky. For example, if the designer describes a room as having a table and chairs in it, in version 5.0 and before, the artifacts could be real (player able to pick the. up, eat the., destroy them, examine them, etc.) or they could just be there for effect. (i.e. to make the room mare interesting.) In version 6.0, the artifact5 could have the added advantage of being in the room, but being set up as ‘embedded’. That is, they are in the room, can be acted on as an artifact, but are not listed by the main loop as separate artifacts until they are examined. The player has to recognize that if he picks up the table and chair, carries them to the elevator shaft, drops them and walks back into the room and looks around that the room description will say there is a table and chair here. Please don’t send us a letter and say this is a bug. It is not a bug. It is a ‘feature’.
Another example: A player walks into the room and there is a broom sitting in the corner. The designer sets up the description of the broom as ‘YOU SEE A BROOM SITTING IN A CORNER OF THE ROOM.’ The player picks up the broom, goes up into the attic, and tries to clean with it. He then examines the broom and it says it is sitting in a corner of the room. What?!! Can this be? Quick! Do an inventory! How did that tricky little devil get away from me? BZZZZ - NOT A BUG! Poor design, maybe, but not a real bug.
Let’s take a look at how to avoid these things. Maybe we should set up a set of guidelines.
1. Don’t describe artifacts surroundings in the description of an artifact. Describe the artifact itself. For example, on the broom above, you could have just said ‘YOU SEE A BEAT UP OLD BROOM SITTING HERE.’
2. In a room description, try to avoid describing artifacts in the room, unless they are rather permanent or are ‘embedded’ artifacts and it is necessary to describe them so that the adventurer knows they are there.
3. While monster names with descriptions like ‘THE BLACKSMITH HEARS YOU COME UP BEHIND HIM AND HE SPINS AROUND, BRANDISHING A HOT ‘IRON THAT HE QUICKLY PLUCKS FROM THE COALS.’ might sound interesting and exciting, you might want to consider that some new player may LOOK at the Blacksmith and when he gets the sale description again, he may be confused. The player should realize that this is a program feature or limitation and not be confused by it. The designer may decide that it isn’t worth worrying about and go ahead with the good, active descriptions.
The next item I would like to cover is setting up monsters and artifacts. Since this is a broad topic, I will narrow the scope to normal ranges of the various data fields making up the items.
Artifacts consist of the following pieces of data:
Description of artifact.
In addition, weapons and all version 6.0 artifacts contain 4 more fields that are used for different purposes, depending upon the type of artifact.
Weapons contain the following additional fields:
Complexity or Odds
For the purpose of keeping this a little simpler, we will discuss only the standard fields listed above and cover the various 6.0 artifact types in a future issue.
Artifact name - The name of an artifact should be concise and try to avoid duplicating names of artifacts within a single adventure. This can cause the program difficulty when trying to figure out what the player is doing. The name of the artifact should not contain any commas, colons, or quotation marks.
Description - This will describe the artifact to the player either the first time he comes upon it, or whenever he examines it. Try to keep in mind that this description will appear whenever and wherever the item is examined, so do not describe its surroundings within the artifact description.
Value - This will be the price (or roughly) that will be paid the adventurer upon returning to the main ball with this artifact. It should not be negative and for gold (type 0) should not exceed 32767. If it is a treasure (type 1) or any other type, it will bomb the program if it is over 13652. This value will vary depending on the charisma of the adventurer. Anyway, this shouldn’t be a problem, since the practical limits are much smaller. I do not think the total value of an adventure should go over 10,000 for all treasures. (Unless it is an extremely dangerous or difficult one.)
Type - This is the type of artifact. It should be 0 through 3 for most versions. Version 6.0 has artifact types up to type 10.
Weight - All artifacts should have weight. Some magical artifacts may have negative weights, which makes it easier to carry other items.
Room - This is the room number that the artifact is to start in. If it sits in one room waiting to be found upon entering that room, then it will simply be the room number. If it must be found by doing something special, like saying geshundheit when a holy man sneezes for example, then it should be 5et to room 0 initially and altered to another room using special programming. 14 it is a version 6.0 adventure, you could hide it in a room (say, room 54) by coding it as 354. Also for version 6.0 it can be not mentioned by coding it as 254 or inside another artifact (say, artifact 27 - tool box) by coding 127.
For weapons the fields are:
Complexity - The normal limits on standard weapons is +1- 10%. Magic weapons can go up to +1- 35%, although normally they do not exceed +1- 25%. Anything with a higher complexity than +35% is going to be considered illegal. If you design an adventure and someone walks in with a weapon of higher complexity, feel free to chastise them in a manner of your choice.
Dice - This is normally not greater than 2, but depending on the sides, may be almost any number up to 5. Remember that the normal character going through a dungeon has a maximum hardiness of 24. A weapon that generates more than this in total hit points is rather unfair.
Sides - This is normally not greater than about 10; but again, this will depend on the dice. Total damage should not exceed 24. (Total damage is dice x sides), Magic weapons such as Excalibur etc. generate something like 2 D B (Total of 16). A super-powerful magic weapon like Mjolner (Thor’s hammer) generates something like 4 D 8 or 32 maximum points of damage, but this is exceedingly powerful, and should not become a norm.
The important thing to remember about setting up Eamon weapons is try to be consistent with the rest of the series. If in one place magic swords are 2 D 8 and in another a pea-shooter is 100 D 20 (maximum of 2000 points damage; minimum of 100), then you are not being fair, realistic or consistent. When adventures are created like this it promotes cheating by the players. That’s one thing we would like to limit - not promote.
--- Monster Fields ---
And now for the monsters...
Monsters have the following data fields and their associated normal limits:
Monster Name - try to make it somewhat spellable. Also, RAT1 RAT2 RAT3 ... is not interesting. BROWN RAT, TAN RAT, 6REY RAT, CAVE RAT, ICE RAT are much better. Avoid punctuation in the name.
Monster description - Do not use quotation marks in the description. The program will bomb. Try to make the descriptions interesting.
Hardiness - Hardiness is how many hits a monster can take. Monster hardiness should be no higher than an adventurer’s hardiness if the monster is human. A hardiness of 54 for a small boy is ridiculous. Below are some guidelines. For consistency’s sake, let’s try to stay within reason.
Rat, Cat, Small Dog 1 - 5
Medium Size Dog 6 - 10
Child 5 - 10
Large Dog 10 - 15
Fighter – Average 16 - 18
Fighter – strong 18 - 22
Fighter - v. strong 22 - 24
Abnormal Human 25 - 35
Demon, Devil 35 - 95
Giant 10 - 16 ft. 30 - 60
Dragon – small 45 - 80
Dragon – medium 75 - 150
Dragon – Large 130 - 225
Agility - Believe it or not, the agility field is not used in Eamon for monsters. You may set this to anything you wish and it will make no difference.
Friendliness - 0 - 100 is normal
Courage - 0 to 200 is the normal range. Monsters with a courage of 100 will not (or should not) run from a battle. Monsters with a courage of 200 not only won’t run from battle, but will chase you forever if you do.
Room - The root number that the monster is in.
Weight - This is not used for anything in Eamon currently.
Defensive Odds - Mortally defensive odds are zero. If a monster is exceptionally fast or able to avoid attack, it lay be 10 – 30%. Anything higher than this and the battle becomes a little boring. If a monster is very slow and lumbering, you may wish to set this lower than 0.
Armor - This is the number of points of protection that the monsters armor affords him. It should be from 0 to 7 for humans. You have to try to remember the adventurer will be swinging weapons that will generate maximum of 8 points of damage. (For a standard sword). Therefore if you set the armor to 7, he would have to get a maximum roll just to do any damage at all. It is therefore recommended to try to stay around 3-4 for humans. Leave the 7 armor classes to the extremely tough fighters, dragons or some such creature. If you go above 7, you should provide a weapon that can penetrate such defenses. Otherwise the standard characters will not have a chance.
Weapon number - This must point to a weapon artifact, a zero for natural weapons, or a -1 for unarmed.
Offensive Odds - This is the total chance the monster has to hit. Most of the time you don’t want to go above 75%. A monster with 80% is very difficult in battle, while a monster with 0% will be very boring.
Dice and Sides - see the artifact dice and sides description above. The same recommended values apply to monster dice and sides.
That wraps up this issue of designer’s den. Next issue I will get into version 6.0 artifacts.
by John Nelson
With Bob gone and wanting to get some fresh points of view, I’ve asked Jeff Harris (at sword point!) to give us a new perspective on some things he’d like to see in an adventure. When you’re designing these things, sometimes the designer gets into a rut of the same-old-stuff with very few new and creative twists. Jeff has come up with same wild ideas, which I’ll let him express, then (when I finish laughing) I’ll lake a few suggestions on how some of these ideas could be transferred into an Eamon adventure, programming-wise.
Something completely different - by Jeff Harris
Well, it’s Springtime; John’s been rattling the bars on my cage again, so another winter’s hibernation is over. He’s stuck me with the title of Official Eamon Gadfly, so I might as well earn it:
PETS; Ever see the John Wayne movie ‘Big Jake’? Remember Dawg, Duke’s four-legged companion? I’d like to meet an occasional character (preferably a friend) wandering about with his/her trusty animal sidekick. Now, no ‘real’ adventurer would take a Pekingese along; puppies, kittens, and guppies would not do on a monster hunt. I’m talking about Dobermans, Mastiffs, or the occasional 1600 lb. polar bear. Or even some ‘exotic’ animal like a Pegasus, a tame firedrake, or an invisible six-foot rabbit named Harvey. Consider the possibilities:
A pet dragon that scorches locked doors - or obnoxious visitors - upon
Faithful dogs that are trained to sniff out treasure, avoid traps, and find their way out of mazes.
Trained ferrets to get into and out of tight places perhaps scooping a little loot along the way.
Self-sufficiency...plenty of corpses to feed a hungry pet.
For you space opera buffs, how about a survival adventure/sabotage mystery aboard a lifeboat in space.
How about a Saturday Night at the Olde Watering Hole - one large room with dozens of adventurers present.
For you AIRWOLF fans, BLUE THUNDER addicts, etc., spend the entire adventure inside a one room aircraft (or a Viking-like boat, etc.) ‘moving’ the vehicle in different directions, looking for trouble and booty.
ARMS & ARMOUR: How many of you have ever heard of the Society for Creative Anachronism? Lotsa blank stares, eh, so let me explain: the SCA is a non-profit, educational organization based on the concept of ‘keep the Middle Ages alive by study and imitation.’ Science, technology, and the arts have their own guilds; military equipment and tactics are perpetuated through tournaments, skirmishes and the occasional war; and such truly unpleasant things like plagues and famine are happily ignored. Anyway, I’ve been an authorized fighter for nearly four years, giving and getting my fair share of combat bruises. I’m currently phasing out my trusty conveyor-belt (similar to boiled leather) armor for some lovely steel plate, and 1 spend a considerable amount of time maintaining my weapons (rattan sticks reinforced with fiber-tape) and gear... the amount of wear-and-tear is phenomenal’ Which leads me to the topic of Arms and Armor. Once the stuff is bought and paid for, the Eamon enthusiast seldom gives it another thought. I find this rather disappointing - I can relate to August weekends frying in my armor, or melee fights where allies and enemies get inseparably mixed together (recognizable only by their armor), or long hours spent learning/perfecting the various weapon systems. Magic weapons and endless ATTACK commands are okay, but here’s what I’d like to see some more of:
· An Exhaustion Factor. You put on 30 lbs. of heavy clothes and go play basketball for a while and maybe you’ll appreciate this more.
· Broken armor. Yes, it does break - usually at the worst possible time. And it takes time and resources to fix...If you know how (I’ve learned a little elementary blacksmithing building my SCA plate).
Remember when the kung-fu movie craze started? Here’s a basic movie plot:
1. Student learns kung-fu.
2. School is attacked, teacher shamed/injured.
3. Teacher passes along a ‘secret’ (i.e. ‘magic’) technique.
4. Student takes revenge on villains.
I’d like to see an adventure built along similar lines, with plenty of emphasis on steps 1 and 4.
Well, so much grumbling for this issue. Remember: BE CREATIVE!
John here again --- almost forgot about me, eh?
To go through some of these ideas, let’s examine how some of the could be implemented into Eamon adventures and what some of the problems are.
1. Pets - These are no real problem to do in Eamon, except for a couple of minor points, a.) Being creative. It is fun to run into a monster with an unusual pet. Try something different. Dreaming them up is half the fun. You don’t want to use the old run-of-the-mill pets all the time. b.) The pet should react the same as the monster. This gets a bit trickier, but can be done. Check the adventure #48 Picnic in Paradise - Rebecca reacts as her father, the old warrior does. In order to do this, all you have to do is have the pet as a higher numbered monster than his master. Then make a change to the reaction routine of the base program that if the subscript equals the pet’s monster number, instead of calculating his reaction, simply copy the reaction of his master Sample code of such a change:
3655 1F N = PET THEN MD%(M, 14) = MD%(MSTR,14): GOTO 3670
For a special monster, such as a dragon that scorches locks (or enemies) upon command, you would need special coding in the SAY command area (lines 16000 - 16999) For example, let’s say you have a baby dragon with you that will do this. First you have to give some clue to the player that such action is possible. Perhaps have the description of the dragon say that he looks friendly and obedient, as if he would scorch enemies upon command, or some such thing.
Then put in code like (assume PET is a variable set to the monster number of the baby dragon):
16060 IF LEFT $(S$,6) = "SCORCH" AND MD%(PET,5) = ROOM THEN 16100
16100 REM /// DRAGON-SCORCH
16120 GOSUB 4700:REM VERSION 6.0 MONSTER SEARCH ROUTINE
16130 IF NOT FO THEN ?:?"THE DRAGON DOESN’T UNDERSTAND!": GOTO 100
16140 ?:?"THE DRAGON ATTACKS "; MN$(M);" WITH A":?"BLAST OF FLAME BREATH!"
16150 DF = M:D=2:S=4:GOSUB 7635:GOTO 300
If you aren’t using version 6.0, you won’t have a monster search routine at 4700 and will have to write your own.
Now let’s try something a bit harder, a dog that can sniff out traps and sniff out treasure. Let’s assume the magic dog is monster number 2, you are standing in room 7, with room 8 being directly south as a secret passage, and containing a treasure (artifact #9), and east being a secret pit that you would fall into and die. Special code might be:
205 IF MD%(2,5)=ROOM AND MD%(2,14) = 3 THEN GOSUB 28000
28000 REM /// DOG SENSE ANYTHING?
28010 IF ROOM = 7 THEN ?:?"THE DOG STOPS DEAD IN HIS TRACKS."
28020 IF ROOM = 7 AND AD%(9,4)=8 THEN ?:?"HE BARKS AND SCRATCHES
AT THE SOUTH WALL."
Explanation: In line 205 we first had to determine that the dog (monster 2) was in the room. This is done by checking his field 5 (MD%(2,5)) equal to the room variable ROOM. Then, the program must be sure he is a friend of yours. (In our example he won’t help you unless he is. If both of these conditions are true, then the program will perform the subroutine at 28000.
Line 28010 checks to see if you are in room 7, (since you know there is a pit to the east) and prints the dog’s warning. Of course the warning can be subtle as it is here, or it could be more blatant, such as ‘THE DOG GROWLS AT THE EAST TUNNEL.’ or even ‘THE DOG TRIES TO STOP YOU FROM GOING EAST.’
Line 28020 then checks to see if you are in room 7 again, and if so, it checks to see if the treasure is still in room 8. (You might have already discovered it.)
An even more difficult bit of programming would be the ferrets that retrieve things for you. This type of programming is difficult to simulate. It could be done by using the say command such as ‘SAY FETCH DIAMOND’ at which the ferrets would run into a hole and fetch the diamond and return it. Let’s try this:
YOU ARE IN A SMALL STARK CELL. THERE IS
A COT SECURELY BOLTED TO ONE WALL AND A
SMALL RAT HOLE IN THE WALL UNDER THE
FERRET IS HERE.
YOUR COMMAND? LOOK INTO HOLE
YOU LOOK INTO THE HOLE AND SEE A LARGE SPARKLING DIAMOND!
YOU ARE IN A STARK CELL. FERRET IS HERE.
YOUR COMMAND? GET DIAMOND THE DIAMOND IS OUT OF REACH.
YOU ARE IN A STARK CELL. FERRET IS HERE.
YOUR COMMAND? SAY FETCH DIAMOND
THE FERRET RUNS INTO THE HOLE AND
RETURNS A FEW SECONDS LATER WITH
YOU SEE A SPARKLING DIAMOND.
YOUR COMMAND? GET DIAMOND
The programming needed to accomplish this would be:
1. Get routine - not allow getting diamond if it is still in the room in was originally placed (room 0 would be best). If the adventurer is in the correct room, but the diamond has not been ferreted out, print that it is out of reach.
4210 IF A = 6 AND AD%(6,4)=0 THEN ?:? "THE DIAMOND IS OUT OF REACH.":GT=0:RETURN
2. Look routine - If you are in the stark cell, check for looking ‘into hole’ if this is the case, and the diamond is still in room 0, print that you see the diamond.
IF ROOM = 23 AND (S$ = "INTO HOLE" OR S$ = "HOLE" OR S$ = "IN HOLE" THEN IF AD%(6,4)=0 THEN ?:?"YOU LOOK INTO THE HOLE AND SEE":?"A LARGE SPARKLING DIAMOND!": GOTO 300
3. Say command - If the adventurer is saying ‘fetch’ (followed by some other item name), go to a routine that figures out what he is trying to fetch, then check whether or not the adventurer is in the correct place, the diamond is still in room 0, etc. If so, change the room number of the diamond and print the message that the ferret went to get it.
16060 IF LEFT (S$,5) = "FETCH" AND MD%(9,5) = ROOM AND MD%(9,14)=3 THEN 16100
16100 REM /// FERRET FETCH
16120 IF S$ = "DIAMOND" AND ROOM = 23 AND AD%(6,4) = 0 THEN 16150
16130 … (do whatever else you want)
16140 GOTO 300
16150 ?:?"THE FERRET RUNS INTO THE HOLE AND ":?"RETURNS A FEW SECONDS LATER WITH ":?"THE DIAMOND
16160 AD%(6,4) = ROOM:GOTO 300
Sounds easy, huh?
For some of the other items Jeff mentioned, I would like to say that some of these features are present in Don Brown’s Swordthrust series. Exhaustion, armor breaking etc. have been done in this system. Part of the problem in doing these in Eamon is simply that it is more trouble than it’s worth most of the time. For an occasional change of pace, however, I think they would be refreshing.
by Bob Davis
Hello Dungeon Designers! This issue we will start with something easy - adding commands to your new dungeons.
Using the Dungeon Designer 6.0 MAIN PGN, there are 3 basic (no pun intended) lines to be concerned with: 1910 and 1920 and 290. First, let’s cover lines 1910 and 1920. They should appear as follows:
1910 DATA 30
1920 DATA NORTH,SOUTH,EAST,WEST,UP,DOWN,GET,TAKE, DROP, LOOK, EXAMINE, ATTACK, FLEE, GIVE, INVENTORY, BLAST, HEAL, POWER, SPEED, SMILE, WAVE, SAY, READ, READY,SAVE, LIGHT, OPEN, PUT, DRINK, FREE
Line 1910 has the number of commands that will be valid for this adventure. If you add three new commands to the adventure, then you will need to add three to the number of commands. Line 1920 is a list of the actual commands that will be used in the adventure. To add new commands, simply place them at the end of this list separated by commas - OR, you may start a new line directly after line 1920.
Let’s add three new commands to a hypothetical adventure. They will be EAT, DIG and SLEEP. First we will need to update lines 1910 and 1920 (I will use a new line number) to look like this:
1910 DATA 33
1920 DATA NORTH,SOUTH,EAST,WEST,UP,DOWN,GET,TAKE, DROP,LOOK, EXAMINE, ATTACK,FLEE, GIVE, INVENTORY, BLAST, HEAL, POWER, SPEED, SMILE, WAVE, SAY, READ, READY, SAVE, LIGHT, OPEN, PUT, DRINK, FREE
1925 DATA EAT, DIG, SLEEP
Line 290 decides what line number each command will execute. It should be as follows:
290 ON C GOTO 3000, 3000, 3000, 3000, 3000, 3000, 4000, 4000, 5000, 6000, 6000, 7000, 8000, 9000, 10000,11000,12000, 13000, 14000, 15000, 15000, 16000, 23000, 17000, 18000, 19000, 20000, 21000, 22000, 24000
Notice there is a line number for each command, or 30 line numbers in all. When a command is entered, it is used to search against the command list and is converted to a number and assigned to the variable C.
Normally we could just tack on the line numbers of the new commands at the end of this line. If too many command line numbers are entered however, the total length of the line becomes too long and the line will not be properly saved. To avoid this, I always add another line directly after 290 with the line numbers of the new command routines - in this case:
295 ON C – 30: GOTO 25000, 26000, 27000
When the command is one of the three new ones (EAT, DIG or SLEEP), the command number (C) will be greater than 30. Since there are only 30 line numbers on line 290, control will fall through to the next line number - 295. The number of commands previously defined (30) is then subtracted from C and the ON GOTO works perfectly.
That’s the easy part, now comes the fun part - making your new commands work. As always, the more you know about the Eamon MAIN PGN and its variables, the easier it is to make your new commands work the way you want.
If the dungeon had rhino meat that, when eaten, would toughen an adventurer’s skin, one (or both) of two variables could be changed to simulate this. One would be the hardiness MD and the other is the armor rating MD%(0,8) of the adventurer, either of which could be increased a reasonable amount (1 or 2). But let’s say if a religious band of rhino worshipers witnessed the consumption of the rhino meat, they would begin attacking unmercilessly. How would this be programmed?
First, a few basic things must be checked. Whenever the adventurer tries to eat anything, it must be found in the artifact table and it must be in the room or in the adventurer’s possession. This can be accomplished by using an existing routine in MAIN PGM of DDD 6.0 at 4800 - the artifact search routine.
Once the rhino meat has been found, the room number of the meat must be set to zero to simulate it being eaten. The adventurer’s attribute(s) may then be changed to simulate the thicker skin and the check for the presence of the rhino worshipers can be made. If they are present, the worshipers must be made unfriendly and must be re-evaluated (routine at 3600).
This might sound like a lot of coding, but with several of the needed routines easily accessible the amount of coding is reduced substantially. This is one of the advantages of using DDD 6.0 for designing adventures. The actual code to perform the above simulations is as follows.
25000 REM --- EAT RTN ---
25020 GOSUB 4900:GOSUB 4800: IF NOT FOUND THEN ?:?"YOU CANNOT EAT THAT!":GOTO 100
25040 IF A THEN AD%(A,4)=0:MD%(0,1)=MD%.(0,1)+l: MD%(0,3)=MD%(0,8)+1 :?:?"YOU FEEL YOUR SKIN THICKEN AND BECOME":?" HARDER!"
25060 IF A=6 AND MD%(12,5)=ROOM THEN MD%(12,3)=0:MD%(12,4) = 0 :R3=ROOM:?:?"THE RHINO WORSHIPERS ARE SHOCKED AND":?" ATTACK, BELIEVING YOU ARE EVIL ITSELF!":GOSUB 3600
25080 GOTO 300
25020 - The routine at 4900 makes sure an item was entered with the EAT command. If not, it will prompt for one. The routine at 4800 searches the artifact table for the item entered (RHINO MEAT) with the EAT command. If it is not found in the artifact table, the variable FOUND (FO) will be set to zero. If the artifact is found and either it is in the room or the adventurer is holding it, the variable A will contain the number of the table entry - in this example 6; the supposed number of RHINO MEAT.
25040 - If the item found is RHINO MEAT, the room number ADX(A,4) is set to zero, the adventurer’s hardiness MD%(0,1) and armor MD%(0,9) is increased by 1 and a message prints explaining what has happened.
25060 - If the RHINO WORSHIPERS (monster #12) are in the room and the RHINO MEAT was eaten, the WORSHIPERS’ friendliness MD%(12,3) is set to zero, their reaction MD%(12,14) is set to zero, a message is printed informing the adventurer of the WORSHIPERS new attitude and the monsters are re-evaluated (routine at 3600). Anytime one monster’s reaction is changed, a GOSUB 3600 must be performed to re-calculate the system variables such as the ‘IN BATTLE’ flag.
25080 - line 300 is where all successfully executed commands should go. If a command is unsuccessful, control may be returned to line 100 (as in line 25020).
by John Nelson
This issue I want to be stern to those who are not putting fun stuff in their adventures. I write these columns so people will get some ideas for neat stuff to put in their adventures. Some of you are not paying attention! Heads up! I want to see some improvement here. ‘Nuff said.
This issue I will talk about:
Gates for DDD Version 6.0 adventures
Armor, buried treasure and other extended 6.0 functions
A save game routine that works with a full disk
Some previously undocumented 6.0 features
Part 1 - Gates - How to use them in Version 6.0
Gates were previously discussed in Adventure Log V for version 5.0. At that time, it was not believed necessary to do version 6.0 because in Version 6.0, gates and doors are handled automatically (as long as they are set up. correctly). Since there has been some confusion, however, I will explain it in greater depth this issue.
In version 6.0, gates are artifacts just like a sword would be. But instead of having complexity, dice and sides, -- fields it has no use for -- it has room into, key number and strength. These fields are used by the 6.0 base program to know how the gate functions.
The Room into field tells which room you would enter once the gate or door has been opened.
The Key number identifies which artifact you must have in your possession to open the door or gate.
The strength tells how strong the door or gate is. This will be how many hit points it could take if an adventurer started beating on it with a weapon.
The easiest way to explain how this works is to give some examples. Let’s assume we want to have a gate in room 6, blocking passage east into room 7. We will assume we already have 14 artifacts on our file for weapons and treasures, so we will make the gate itself artifact number 15. It will require a key, which will be artifact 16 - an old iron key.
When entering room 6 in the dungeon edit program, when it prompts for EAST: We know we want to go into room 7, but there is a gate between these rooms, so we have to tell the base program (that will read this stuff later) that there is a gate there and which artifact number it is.
We do this by entering 115 for the EAST prompt. The fact that the number is greater than 100 tells the base program that this is a gate number, not a room connection. The program then has to look at artifact 15 (which it derives by subtracting 100 from the code for East) for further information on whether the gate is locked, etc.
When entering artifact 15, The Gate, the dungeon edit program prompts for Room or Room Into. This is where you enter the 7 for the room you will enter. The program will also prompt for Key# which in this case is 16 and the strength.
The strength is how strong the gate is. It is possible to break down gates with weapons by attacking the.. The designer is responsible for saying how many hit points the gate can take before being broken open. This may be desirable for many reasons: Maybe the adventurer did a power spell and the key disappeared. Maybe he lost it, it was stolen, or he can’t find it. It allows a little more freedom of action for the adventurer. The designer may even intentionally or unintentionally not put a key into the adventure, intending for the player to have to break the gate down.
Once you have set up the east direction in room 6 as 115 and have set up the gate as artifact 15, having a room code of 7, a key of 16 and strength of whatever you want from 1 to 32767, the base program will handle the opening of the gate for you. No programming will need to be added. Artifact 16 can then be defined as a key, but it is really not an important part of the coding, it just has to be an artifact and should be a type 9 (key) artifact.
Part 2 - Number conventions for extended 6.0 usage
When I designed Version 6.0 of the Dungeon Designer, it was actually adopted from a Designer System for Knight Quest, a proprietary super system I was developing.
Using the same general principles developed there, I adapted some of the feature to Eamon. Room code conventions were set up for hidden artifacts, embedded artifacts, and artifacts inside other artifacts. EVERY ROOM CODE YOU COULD EVER IMAGINE was established for Eamon. --- (Oops! Wrong Dragonlips). We have plenty of other room codes that we would like to add to the system eventually, but have not had time to do it yet.
We want to establish standard codes, so that everyone will be using the same ones, and we will be able to put these room codes into the Dungeon List program, so that it can determine where things are.
The existing room codes for artifacts in DDD 6.0 are:
+100 for Inside a container
+200 for Embedded in the room description
+300 for Hidden in a room
Currently, monsters do not have the same room code conventions as above, but this is intended to be a future enhancement.
New room codes we want to add to the system:
+400 for buried in a room
+500 for randomly placed
While we are on the subject of DOD enhancements, further enhancements are also planned that will allow additional artifact types.
Current artifact types are:
0 - Gold
1 - Treasure
2 - Weapons
3 - Magic or Special Weapons
4 - Container
5 - Light
6 - Healing
7 - Readable
8 - Door I Gate
9 - Key
10 - Bound Monster
Additional artifacts are planned for the future as follows:
11 - Shovel / Pick
12 - Armor
13 - Booby Trap
14 - Magic / Special
Additional routines will have to be added to the base program to make these useful.
Digging routine could be something like:
26000 REM /// DIG
26010 GOSUB 4900
26020 HS=0: AF=0: FOR X=1 TO NA: IF AD%(X,2)=11 AND AD%(X,4)=-1 THEN HS =1
26030 IF AD%(X,4) = 400 + ROOM THEN AF=X:
26035 NEXT: IF NOT HS THEN ?:?"YOU DON’T HAVE A SHOVEL." :GOTO 100
26040 IF AF THEN ?:?"YOU FOUND SOMETHING.":AD%(AF,4) = ROOM : GOTO 300
26060 ?:?"YOU FIND NOTHING.": GOTO 300
Note: This will allow you to dig up only one artifact at a time. To find a second object (if there is one) the player would have to dig a second time.
To allow you to change armor within an adventure, a WEAR command could be added as follows. Note that field #6 of the artifact table will contain the hits stopped value for the armor and field #5 will contain the adjustment factor of the armor.
27000 REM /// WEAR
27010 GOSUB 4900: GOSUB 4700: IF NOT FO THEN 90
27020 IF AD%(A,4) <> - 1 THEN ?"YOU DON’T HAVE IT.": GOTO 100
27030 IF AD%(A,2) = 12 THEN AD%(A,4)=0:MD%(0,8)=AD%(A,6):EA = AD%(A,5):?:?"OKAY.": GOTO 300
27040 ?:?"YOU CAN’T DO THAT.": GOTO 100
BOOBY TRAPS will be coded as if they were weapons, but will be activated when you try to get them. Modifications have to be made to the get routine. There is already a special pick-up routine that gets executed whenever you pick anything up. This routine is at 4200. The modifications below will recognize and process artifacts with a type of 13 as booby traps.
4210 IF AD%(A,2)=13 THEN R=AD%(A,5):GOSUB 23800:D=AD%(A,7):S = AD%(A,8): DF=0: GOSUB 7635: RETURN
This code checks that it is a booby trap that the adventurer was trying to get and, if so, reads the appropriate effect from the EAMON.DESC file by setting the record number to AD%(A,5) and doing a GOSUB 23800 to read and print the effect. It then sets up the defender as the adventurer (DF=0) and does a GOSUB 7635 to accumulate the damage and check injuries, etc.
Of course, you will want to be fair to the adventurer. If he examines it before picking it up, he should have a chance of detecting that it is a trap. You would accomplish this by adding code to the look routine. A couple of suggestions on doing this: 1) You could make the discovery a random chance or a sure thing. 2) You may want to have another field (field #6) be something like a) a new artifact type that replaces the 13, upon discovery that it is a booby trap, or b) be the effect number that is read to explain what you find by examining the artifact (a trip wire, a poison needle, etc.). The look routine should have some means of disarming the trap or at least recognizing it.
To use field #6 as a new artifact type:
6710 IF AD%(A,2) = 13 THEN AD%(A,2) = AD%(A,6) : PRINT : PTING "YOU DISCOVER IT WAS BOOBY TRAPPED AND MANAGE TO DISARM IT." : RETURN
To use field #6 as an effect number:
6710 IF AD%(A,2) = 13 THEN AD%(A,2) = 1: R=AD%(A,6):GOSUB 23800: RETURN
AD%(A,2) = 1 sets the artifact type to 1 (treasure). This, in effect will disarm the booby trap. If you didn’t want to disarm it, but only recognize it as a booby trap, then omit this portion of the statement.
Part 3 - Save Game Feature - for large adventures
While we were playing the Mines of Moria we felt an irresistible urge to save the game and come back to it later. This was impossible, because the save game feature had been partially removed by the author. We were able to save the game anyway by interrupting the program with CTRL-C, putting in a diskette with a lot of free space on it, and typing POKE 51,0: GOTO 18040.
To restart the game, we copied MAIN PGM onto the disk with the save files and ran that program. The program would then bomb on the OPEN statements. At that time, we switched diskettes again, to put the regular diskette (MINES OF MORIA) back in, and typed POKE 51,0: GOTO 29060 - WA-LA the game was restarted.
To provide a cleaner way to restart a large adventure, the designer should make the following changes to the base program:
18045 ?:?"INSERT A BLANK DISKETTE AND PRESS ANY KEY TO CONTINUE…";"GET A$:?:?DK$;"INIT MAIN PGM"
29055 ?:?"INSERT ADVENTURE DISKETTE AND":?"PRESS ANY KEY TO CONTINUE";:GET A$:?
To insure these are the correct line numbers for the version of the program you are using, the first line (18045) above should he just AFTER the line to CLOSE the files and do the X = FRE(0).
The second line (29055) should be just before the OPEN statements in the restart routine.
Part 4 - Undocumented features in Version 6.0
There are some features in the newest version of DDD that have not been documented anywhere. They put in during development of some of the adventures. These features are:
1. Plural monster capability
2. Healing Potions are not necessarily good for you.
3. Temporary Truce is possible
1). Plural monster capability - If you have a monster that is really a plural - slaves, guards, army, etc. and don’t want this to print as ARMY ANTS IS HERE. (Improper grammar’) set the monster’s weight to 9999 in the edit program. A line in the base program checks this and when it finds 9999 for a weight, it prints
ARMY ANTS ARE HERE.
If your version does not have this, here is the Code that does it:
150 FOR M = 1 TO NM: IF MD%(M,5) = ROOM AND MD%(M,15 = 1 THEN PRINT MN$(M); " "; MID$("ISARE", 1+ (MD%(M,6) = 9999) * 2,2 +MD%(M,6)=9999));" HERE."
Also lines 7655 - 7675 could be changed similarly, but this has not been incorporated into the DDD yet.
2). Did you know you cart make a ‘healing potion that hurts the adventurer, instead of helping him? All you have to do is make the effect of the healing potion a negative number. When you do this, and the adventurer drinks it, he gets the message ‘SOME OF YOUR WOUNDS SEEM TO OPEN!’ instead of ‘SOME OF YOUR WOUNDS SEEM TO HEAL!’
3). If you have a base program that was created after Temple of the Trolls was written, you have a temporary truce ability. This allows you, as the designer, to set a fixed number of turns where battle will not occur. This comes in handy when you are in the middle of a special process, such as a trading with an enemy or a sales transaction, etc. To use this feature, set the variable TI to the number of turns the truce is to be called for. Each turn, the TI counter is set down by 1. If it reaches zero, the truce is over and the battles may commence.
If your version does not have temporary truce, you can install it by making the following changes.
310 IF NOT NBTL OR TT THEN 500
510 IF TT THEN TT = TT-1
3010 IF NBTL AND S$ <> "FLEE" THEN IF NOT TT THEN PRINT: PRINT "YOU CAN’T DO THAT WITH UNFRIENDLIES ABOUT!": GOTO 100
by John Nelson
This issue we would like to express our thanks to all of the people who made the un-contest the truly great success it was. That’s what we’d like to do, but the problem is, it wasn’t all that great a success. Three very good adventures were added to the list of Eamon adventures, but we were expecting a lot more. I guess we had too narrow a time frame and too small a prize for a really great success. Of the three adventures we received, all three should have been disqualified. As a result, we have no real winner, but unofficially, we have three winners. (What do you expect from an ‘UN-Contest’?)
The three entries were
Orb of Mevtrelek - disqualified because it was sent out for distribution before we received a copy for judging. However, since this was not clearly stated in the rules prior to the receipt, we cannot truly disqualify it, either.
Secret Vigil of Wrenhold - disqualified because it was written by a guy named Davis. Since Bob is on the club staff (sounds redundant), he was disqualified. It also did not meet deadline, although this was because other club duties prevented timely completion, and we certainly shouldn’t penalize Bob for performing club duties, right?! (Right!)
Orb of My Life - disqualified because it had a stupid name. Also it did not meet deadline. Like Bob’s disqualification, this was because of club duties.
Actually we had a tough time even disqualifying these adventures, since we didn’t have any judges, and the rules were very vague. Even in being disqualified, there is no real penalty, since there aren’t any prizes. What’s the point? Why am I talking about this here - in Designer’s Den? Because all of these three adventures, for all their faults and strengths, they had to be designed and programmed. What can be learned from the programming for these adventures?
The Orb of Mevtrelek and the Secret Watch of Wrenhold have a moderate amount of programming to them. In DDD version 6.0 it’s hard to put too much programming in because the base program is already pretty big. In the Orb of My Life I put a lot of special programming in, but had to remove a bunch of code that was already in the base program to make room for it.
In developing Orb of My Life, I made a few enhancements to the base program that may become standard features in the future, because they are so handy. One of these things is the ability to examine something and get some further information about it (without that item having to be an embedded artifact).
For example, you can examine the bed that Sagonne is lying on, even though it is not in the room, even as an embedded artifact. Some of this sneakiness makes it more interesting and fun to discover while playing the adventure.
An idea I came up with when developing Orb of My Life is a text search routine, coupled with an effects file. I didn’t put this into my adventure because of space and time limitations, but my idea is to put in a routine that will scan through the description of a room, looking for words in that description. If a match is found, the program will know you are talking about something in the room and can make an intelligent statement about the item. An effects file could be added where a keyword will be used to activate an effect, a secret passage discovery or an artifact or monster being brought into the room or vanishing.
As a direct result of some of the improvements made for this adventure and because there were other things needed in the base program, the base program was modified to do some additional things. Also, remarks were added to the code to make changes by designers easier.
I have placed the version number 6.2 on this base program. Below is a summary of the features that were added, or little known features that were already there, but never documented that you may find useful when modifying your base program.
1. Monsters unconscious - This was already in place, but never documented. If you want a monster to be in the room, but unconscious, set MD%(m,15) = 2. (where m is the monster number). This will cause the main program to treat this monster as though he was in the room, but he will not participate in battle.
2. Some error messages were somewhat common or generic enough that they were placed at the front of the program and any routine that needs them can simply branch to the appropriate line number. These lines are:
90 - I don’t understand.
91 - You aren’t carrying it.
92 - Okay.
93 - That’s not what you do with it.
99 - It’s too dark to see.
This was done to help conserve memory in the base program. A worthy goal, since the program now takes 80 sectors of disk space.
3. Exits are now printed automatically (except the exit to the main hail and secret passages). This was done to help save the designer from having to use part of the description of a room for the exit descriptions. This will hopefully encourage more elaborate detail in the descriptions. This code can be easily removed, if desired.
4. Abbreviations are now allowed in all routines (unless I missed some, but I don’t think so).
5. Fleeing is now allowed in a direction. This code was in the program before, but was not documented and in some cases, it didn’t work properly. It has been improved and made more efficient.
6. Examine routine has a place to add special discoveries.
7. You can now blast doors, gates, or containers to attempt to open them.
8. The power routine was improved and corrected. There were some power effects that were wrong or could never be attained. The raise dead monster was made a small subroutine, so that if you ever want to put code into your program to resurrect a particular monster, all you have to do is set M = monster number and do a GOSUB to the resurrect routine. The new default effects of a Power spell using this program are:
10% chance - teleport somewhere
15% chance - armor thicken by 2
10% chance - all wounds heal (only if injured)
10% chance - increase all magical abilities (only if uninjured)
20% chance - Sonic Boom
25% chance - resurrect any dead monsters in room
If none of these actions occur, you will get a Speed spell placed into effect.
9. Some of the messages will be different than before. You will never get ‘You don’t know how to read’ when trying to read something that is illegible. Instead, you will get ‘You can’t read it.’ If you try to open an artifact that is not openable, you will get ‘That’s not what you do with it’ instead of ‘You’ll make a mess, wait till you leave.’ When you light a torch or lantern, you’ll get ‘OKAY.’ instead of ‘You managed to light the ...‘. This was to help conserve memory.
10. Line counts are more accurate now, so you shouldn’t be scrolling off while trying to read the descriptions.
There is a drawback to having all these changes put in at once, and that is to get the new program, you’ll have to request another DDD 6.0. The changes were pretty lengthy and we didn’t keep a listing of every line that was changed.
by John Nelson
This is embarrassing. This issue I had planned on letting Pat Hurst, designer of Grunewalde write a quickie article on how he did some special stuff in his newest adventure Buccaneer, but sorry, Pat, I lost your article. It must have gotten thrown out with the level 6 trash. Anyway, if you can get me another copy, or if I find it, I’ll run it next issue, I promise. Thanks.
Okay. Anyway, let’s talk about how to go about this design business in an orderly step by step article, okay? Many of you out there would like to write an adventure, but are not quite sure how to start out. Let’s try a simple example and take you through it. When you get done, you’ll have a miniature adventure.
Follow along with me and we’ll design an entire adventure right here. This is for you beginner’s now, so Evan, Rick, Roger, Sam, Scott, Don and Tom, and some of you other guys, go on to the next article, please.
To begin with, you need a Dungeon Designer Diskette. Version 6.0 will be used here because it has more stuff built into it. This will make designing an adventure faster and easier.
The first thing to do is locate a blank diskette that you don’t mind erasing. Then boot on the DDD 6.0 diskette and select option 1 from the menu (for initialize an adventure.) The program will load and then ask you a couple of questions. It will ask for the name of your adventure lets use ‘QUEST FOR SOCKS’ then it will ask for your name. If you don’t know this one, you’re really in trouble. Then it will ask if this is a six direction or 10 direction. Just type in 6 and make it easier on yourself.
The disk will whirr for a little bit and make the normal noises it makes when it is erasing a diskette. (I hope you took the DDD out. If not, DDD 6.0’s init program will show you the catalog and verify that you want to erase it.
When the disk drive is quiet again, you have an initialized dungeon. Put the DDD diskette back in and load the program MAIN PGM into memory by typing LOAD MAIN PGM. Then put the dungeon you created back in and type SAVE MAIN PGM.
The next step is to create the introduction program. To do this, put the DDD 6.0 diskette into the drive and type LOAD LEADIN PROGRAM. Switch back to your adventure disk again and type DELETE SAVE QUEST FOR SOCKS HERE and press return. Then type SAVE QUEST FOR SOCKS.
Now you’re ready to add rooms, monsters, artifacts, and effects to your adventure! Put the DDD 6.0 in the disk drive and type RUN DUNGEON EDIT.
The program will load and ask you to insert the adventure diskette again. Please do so and press return.
Now, let’s add a room. Press 1 for add, R for room. You will get a screen that allows you to key in the room information. The room name is the first piece of information you have to key in. The room name will always be preceded with ‘YOU ARE’ when the base program is running your adventure, so you want to complete that sentence with your room name. Let’s type ‘IN YOUR BEDROOM.’ and press return.
Then you will give a description of what your bedroom looks like. You have approximately 6 lines of text to describe your room. You may enter punctuation, if you wish. Go ahead and type in an appropriate description for your room.
Now you are ready to type in the directions of movement. This is room 1 you are entering. The next room you describe will be room 2. You should draw a small map and number your rooms. Let’s say that your room exits to the hall. We will make the hall room 2. Let’s further say the exit from your room to the hall is to the north. Therefore for the direction labeled north, key in 2. For all the other directions, let’s leave them zero by pressing the ESC when prompted for them. Now let’s say that the hall goes either to your room (to the south) or the kitchen to the north. The kitchen will be numbered room 3. Therefore, when entering the hall, key in 1 for the south prompt (your bedroom) and 3 for north (the kitchen). You may continue entering rooms in this manner until you get tired of this.
When you are tired of this, you may start entering artifacts or monsters. Monsters are added by selecting 1, M from the menus. Then key in the monsters name. It is printed in the base program as (monster’s name) IS HERE. You might want to put in something like BURGLAR for your first monster. You then enter a description just like you did for the rooms. These descriptions will describe what the monster looks like. You then enter the 12 fields that define a monster. Let’s enter 10 for hardiness, 12 for agility, 0 for friendliness, 50 for courage, 3 for room, 120 for weight, 0 for defensive odds, 0 for armor, -1 (unarmed) for weapon number, 60 for offensive odds, 1 for dice and 5 for sides.
You proceed with adding monsters until you have the idea. The fields you enter for a monster describe how tough, brave, well armed, etc the monster is. If you don’t know what the fields are you may look at your designer manual or experiment.
Artifacts are just about as easy, maybe easier. You select 1, A to add an artifact. The name of an artifact is simply the name. Examples BUTTER KNIFE, COAT HANGER, RUBBER DUCK, SOCKS etc. Version 6.0 understands 10 different kinds of artifacts. Each of these has their own set of data fields. The program will prompt you for these. You can experiment with different kinds of artifacts. Let’s add a weapon: BUTTER KNIFE enter 1 for value, 2 for artifact type, 1 for weight, 3 for room (in the kitchen), 5 for weapon type, 10 for complexity, 1 for dice and 2 for sides. Now, just to show you how it’s done, let’s do a door.
Enter PANTRY DOOR for the door name. Its value is 0, type is 8 (door/gate), its weight is 220, its room is 3. The room into is room 4 (pantry) and let’s say there is a key to it - artifact number 3. (Which we’ll have to put in later). In the kitchen, put the east exit 102. The fact that it is greater than 100 tells the program that there is a door there. The base program subtracts 100 to determine the artifact number of the door (2). When the door is unlocked, the base program will automatically look at the ‘room into’ field to determine which room to move the player into.
When you have entered all of the rooms, artifacts, and monsters you want, press 7 to quit the edit program. You are then ready to test the adventure. To test it, use Eamon Master 2.0 or any other master to take a character on your adventure. Once a character has been transferred, and a FRESH MEAT file exists on your diskette, you can test it as often as you like without going back to the master.
Once you have tried it and have gotten into the testing, I think your confidence and comfort level will increase and you’ll be writing adventures with the best of them.
This has of course, been a real crash course, because an entire adventure could take months and the process could take years, but I think if you’ll try it, you’ll see it really isn’t that tough!
by John Nelson
Okay, last month I wanted to bring you some information from Pat Hurst, but I lost it. Pat has been kind enough to supply me with another copy (although I wish he hadn’t thumb-tacked it to my forehead!) Anyway, thanks for the contribution, Pat.
Pat is, in my opinion, one of the best Eamon authors we have. (Actually, probably my favorite, but I won’t tell him for fear of giving him a swelled head.) Pat has written Grunewalde, Buccaneer, Pyramid of Anharos, and The Dark Brotherhood. Most of his adventures are real epics and won’t fit on a single disk.
The descriptions are very good and continue to keep a person’s interest. Pat would like to explain one of the techniques he used in one of his adventures. So, I turn the rest of the column over to Pat:
In designing my adventure, Buccaneer!, I had a problem in setting the reactions of the various monsters. There are several islands that the adventurer may visit and the inhabitants of each island react to the actions of the adventurer while on the island. The adventurer may peacefully trade on one island, but on another he may have to fight for his life. By his choice of actions, the adventurer is responsible for monster reactions. If he does the wrong thing (such as attack one of the inhabitants, intrude on a sacred area, or disturb an important ritual), the monsters may become very unfriendly. The problem is that each group of monsters must he treated separately from the other groups while each individual in the group must be treated the same as other members in the group.
The 6.0 DDD contains a mechanism for a temporary truce involving decrementing the variable TT. This variable is checked in line 310 of the MAIN PGM so that monsters won’t attack until TT = 0. By setting TT, the designer sets the number of turns that must elapse before unfriendly monsters attack. But in my case this truce period could be of unlimited duration as long as the adventurer didn’t provoke a fight. Using a single variable TI to handle all of the possibilities was impossible. (Note: impossible means too much programming for me!)
My solution requires that all monsters in a group should be assigned the same group number. This group number was placed in the agility field, since this field is not used for monsters in the Eamon base program.
I reserved an agility number of zero for independent monsters. Each group of monsters is given a unique agility number, greater than zero, common to all monsters of that group. During the initialization phase, each monster is assigned a neutral reaction (MD%(M,14)= 2). When an event occurs to change this reaction, a subroutine changes the reaction for all monsters in the group by searching on the monster agility field.
In my adventure, the process is further simplified by dropping the GIVE command, which re-determines reaction. Of course, the GIVE routine could have been modified to also function in this manner, but it was unnecessary in my adventure. I also assumed that if certain events occurred, the monsters involved would become enemies of the player. Again, this may be altered to your needs.
The steps to follow are
1) Assign monster agility numbers in the design process of editing monsters.
2) Assign monster reactions in the INIT phase (starting in line 1000) of the MAIN PGM (see example below).
1145 FOR K = 1 TO 8 : MD%(K,14) = 2: NEXT
1150 FOR K = 10 TO 12: MD% (K,14) = 2: NEXT
1151 FOR K = 18 TO 22: MD% (K,14) = 2: NEXT
Monsters 1-8, 10-12, and 18-22 all have neutral reactions until provoked.
3) Check for events that trigger reaction changes, and do a GOSUB 7950 (code given below) when these reactions change.
In line 7301, below, the player has attacked monster 1. In line 11475, the player has blasted monster 1, and in line 30030, he has done something drastic that the monster didn’t like.
(delete line 7300)
7301 IF MD%(M,2) > 0 THEN GOSUB 7950
7302 IF NOT HIT THEN 7360
11475 IF MD%(M,2)>0 THEN GOSUB 7950
30030 PRINT "’THE HERETIC BLASPHEMES! ATTACK!’": M=1: GOSUB 7950
4) Change the reaction of all monsters in the affected group. This will be all monsters with the same agility as monster M.
7950 FOR K = 1 TO NM : IF MD%(K,2) = MD%(M,2) THEN MD% (K,14) = MG% (M,14)
7951 IF MD%(K,14) <> 2 THEN MD%(K,2) = 0
7953 NEXT: R3 = ROOM: GOSUB 3600: RETURN
5) Eliminate all references to TT. (optional)
Editor’s Note: The above routine was altered slightly from Pat’s original routine to make it faster and more efficient. Line 7951 is optional. Its purpose is to make the monsters only change their reaction once and never change their mind. If you want to be able to change a group back and forth, it should be removed. Also, Pat’s original routine only made monsters unfriendly and would not work to make a group friendly. This was altered by the editor to work either way.
This page last updated on 01/01/2017.