Magical Journey: For Beginners and Experts Simultaneously   34 comments

(Continued from my previous post.)

Previously, we’ve encountered Softside magazine issue 47 (August 1982) with the game Operation: Sabotage. The same issue had a piece by Peter Kirsch entitled Anatomy of an Adventure.

In it he dissects his framework in BASIC that he has used for all his games up to that point:

Early in my adventure writing career, I created an adventure interpreter, or skeleton, as I call it, to serve as the backbone of each of my adventures. It has since been updated many times (now at version 4), but basically remains the same tool.

Magical Journey is clearly version 1, as the same skeleton structure of that game is clearly similar to the general structure Kirsch describes. I’ll go into it in a moment, but a few points from the article:

  • He gets introduced as “author of most of SoftSide’s Adventure of the Month series.” Alas there is no further biographical information.
  • He notes “The days of simply finding treasure and returning it to a storage location are gone forever.” which is a curious comment given how many Treasure Hunts there still are in 1982, but Kirsch got it out of his system back in 1980.
  • He tries different layouts before putting “a final version of my adventure map on a giant piece of heavy paper.”
  • He ran out of memory in writing Titanic Adventure and had to make cuts.
  • His games eventually all had ports for TRS-80, Apple II, and Atari; for making the Atari port used a special routine since the Atari BASIC doesn’t support string array, making a single string and treating it as an array by cutting the part he needs.
  • His parser on TRS-80 and Apple II uses the last three letters. He explains this “alleviates some of the annoying keyboard bounce in the TRS-80”. His Atari parser uses the first three letters because of the Atari string array issue meaning he makes the strings with padding. (I’ve played most of the Kirsch games on Atari, which explains why I didn’t recognize the last-three-letters style parser.)
  • He found Atari BASIC easier to debug because he could change something and still keep running the program, unlike on Apple on Atari.
  • Applesoft BASIC has the issue where if you use A has a variable and you write it before a THEN statement it interprets ATHEN as the command “AT”, so parentheses are required.

For the skeleton, he does something relatively distinct from other BASIC authors to start things off:

He has every single room description as a PRINT statement, and manually sets room exits along with these statements. From Magical Journey, where A is the variable which indicates the room the player is in:

10 IFDT=1THEN320ELSEONAGOTO11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86
11 PRINT”IN A FOREST.”:W=1:N=3:E=1:S=1:GOTO350
12 PRINT”ON TOP OF A TREE.”:D=1:GOTO350
13 PRINT”AT THE BASE OF A MOUNTAIN.”:S=1:E=4:GOTO350
14 PRINT”ON AN OPEN PASTURE.”:W=3:GOTO350
15 PRINT”ON TOP OF THE MOUNTAIN.”:D=3:GOTO350

This is wildly atypical. Consider Hog Jowl mansion (written July 1981, printed January 1982 in 80 Micro), which starts with room descriptions but uses DATA statements instead:

50 DATA “IN A DUMBWAITER.”,0,0,2,0,21,0,”IN A LONG HALLWAY.”,0,6,3,0,0,0,”IN A WORKSHOP.”,0,0,0,2,0,0
60 DATA “AT THE BOTTOM OF A SECRET PASSAGE.”,0,0,0,0,0,0,”IN A LABYRINTH OF TUNNELS.”,0,9,0,0,0,0
70 DATA “IN A TORTURE CHAMBER”,2,0,7,0,0,0,”IN A LABYRINTH OF TUNNELS.”,0,11,8,6,0,0,”IN A LABYRINTH OF TUNNELS.”,0,12,0,7,0,0
80 DATA “IN A LABYRINTH OF TUNNELS.”,5,0,10,0,0,0,”IN A LABYRINTH OF TUNNELS.”,0,0,11,9,0,0,”IN A LABYRINTH OF TUNNELS.”

This is the method given in other tutorials at the time, like the booklet for Deathship. Kirsch used DATA for objects and verbs, so clearly had a notion of just using a “data table” for exits rather than having to specify what the variables equal each and every time. My guess is due to the Atari string handling he didn’t want to deal with changing the method.

The remainder of the skeleton also follows the Magical Journey structure fairly closely. There’s a routine for display exits (“IFN>0PRINT” NORTH”; :B(2)=N”), a player input routine, special routines for movement, taking, and dropping, and then the whole list of other verb routines. This is followed by DATA statements for objects and verbs, and then — quite importantly for me, as you’ll see — the line

3000 PRINTA$” WHAT?”:RESUME390

What’s going on here is that the game is set up to automatically send errors to 3000. The intent is for anything that confuses the parser past what it can understand has at least some grace and a sequence reset back to resetting the parser. In practice, it means that if there’s a bug in the main code, it will stop what’s going on and jump straight to WHAT, as opposed to breaking out with a custom error message explaining what’s wrong, making the game much harder to debug.

Unfortunately, I only realized what was going on fairly late in my process of debugging Magical Journey.

For a while, I thought the issue above was potentially some sort of parser misdirection, but no; in the portion of the code that handles removing and adding objects to the player’s inventory, there was a straightforward typo. See if you can spot it:

1100 FORK2-1TO5:IFC$(K2)=H$(K3)THENC$(K2)=R$:GOSUB1150:RETURN:ELSENEXT:RETURN

That should be K2=1 to 5, with an equal sign, not a minus sign.

Or consider the hungry dwarf I gave a screenshot of last time:

There’s a farmhouse with an oven, pie filling, and pie crust, and you can BAKE PIE with them all together, but after YOU HAVE JUST BAKED A RHUBARB PIE. the game told me WHAT? and gave me no item. Spot the error:

810 PRINT”YOU HAVE JUST BAKED A RHUBARB PIE.”:PE=1:A$(59)=”RHUBARB PIE”:H$=”59)=A$(59):A(59)=25:K3=21:R$=””:GOSUB1100:K3=25:GOSUB1100:M$=””:K3=21:GOSUB1200:K3=25:GOSUB1200:GOTO5000

A few more along these lines happened, so I was simultaneously exploring the map and then every once in a while searching the source code for a misplaced character. This was as close to the metal as adventuring gets. (I also hit one inexplicable bug at the very end which I’ll get into later.)

Fortunately, the game itself was extremely simple in terms of puzzles. Find SNAKE FOOD, it goes to some RATTLESNAKES.

A GIANT CHICKEN wants to eat some CORN.

This leaves a golden egg.

For an only slightly more elaborate example, some FLYPAPER was next to some FLIES was near a GIANT KILLER FROG.

The meta-map of the game seems slightly elaborate…

…but for the most part there is only a handful of obstacles that block your way. In addition to the pie mentioned, a troll needs a toll which you can offer with a SILVER DOLLAR (not marked as a treasure) found down a pit. Even a dragon is relatively easy to defeat.

Two rooms away are a GAS MASK and some SLEEPING GAS, and the dragon is described as wide awake.

The only part slightly messy to juggle is that the game can return you to the start in two cases; in one case (passing through a dwarf house) you need to take the warp back, because it puts you at a treasure (a gold watch) before returning to the starting area.

To get back to the starting area to the main junction you need the shovel, so if you’ve left it behind, this means your game is softlocked, which is kind of rude for what is clearly intended as a beginner’s game.

The only slightly less obvious puzzle; you throw sneezing powder to defeat a MADMAN swinging an ax.

My major hang-up turned out to be at the very end. Quite inexplicably, after getting in the cave past the dragon, and heading west, the game decided to always crash, or at least stop with WHAT? when trying to show the room name, then end up in endless loop. This turned out to be the last room.

The end room is marked in red.

I still have no idea the reason for the crash. I ended up having to add some code to essentially hack my way out of the bug:

300 N=0:W=0:E=0:S=0:U=0:D=0:Y=0:CLS:PRINT”YOU’RE “;:IF(DK=0)*(A>5)DT=1
305 IF A = 72 GOTO 82
310 GOTO10

Line 305 is mine. Rather than going to the select-a-room routine, I just have the game jump directly to the relevant line that displays the room name (82). This bypasses whatever is going on with line 10 to have a bug.

With this fix in place, I could finally see the last room.

Pressing the button congratulates you and then tells you how many of the 17 treasures you found.

6000 PRINT”CONGRATULATIONS! YOU’VE MADE IT ALL THE WAY THROUGH AND BACK.”:IFNT=17PRINT”YOU FOUND ALL 17 TREASURES.”:GOTO6100
6050 PRINT”YOU ONLY FOUND”NT”TREASURES, HOWEVER. THERE ARE”17-NT”STILL OUT THERE SOMEWHERE.”
6100 INPUT”TO PARTAKE ANOTHER JOURNEY, HIT “;A$:RUN

I should possibly be thankful for the bugs. Other than the interest of the “rucksack” holding all treasures while ignoring the inventory limit, there wasn’t much of theoretical interest, but I essentially had to study all of the source code in order to make it to the end. The adventure wasn’t an abstract magical journey as much as one programmer’s journey — badly typed by someone else in the past — as interpreted by some quirky source code.

Unfortunately, some of the rooms remain inaccessible, including one to the west of a room “near the magic garden”. You’ll see on my meta map it currently goes to the opening forest, but it isn’t supposed to do that — it is supposed to go to a tool shed where you can find a ring.

Feel free to check the source yourself to try a diagnosis (including my extra line 305). It seems to have trouble with room numbers 72 or larger (jumping to lines 82 and up). Alternately, you can download a disk here I have prepared that can be run directly with the emulator trs80gp (just drag and drop the file on the emulator). I can’t guarantee there aren’t more bugs. (For example, colors of keys will change when you drop them, but at least that isn’t important for winning the game.)

Posted March 5, 2024 by Jason Dyer in Interactive Fiction, Video Games

Tagged with

34 responses to “Magical Journey: For Beginners and Experts Simultaneously

Subscribe to comments with RSS.

  1. About the typo you comment:

    1100 FORK2-1TO5:…

    Which should be instead:

    1100 FORK2=1TO5:…

    I wonder how it was possible it run without producing a Syntax Error. The expected BASIC syntax for a FOR… NEXT is

    FOR = TO [STEP ]

    So… I’m really confused here.

  2. Sorry, I wrote the FOR syntax with less than and more than symbols, and they got eaten. I meant:

    FOR loop_vble = start TO end [STEP step]

    NEXT [loop_vble]

    • I guess there’s probably an ON ERROR GOTO 3000 instruction at the start of the program to override the syntax error.

      • Yep, it’s at line 380.

      • I didn’t have those luxuries back in the day with Sinclair BASIC. I mean On… ERROR did not exist. I guess that’s why I never think of that possibility.

        ON… GOTO and ON… GOSUB were feasible though, since the parameter to a GOSUB or GOTO was an expression, not a literal, so you could write something like:

        100 REM go sub to location management number in 'a'
        110 GOSUB 8000 + (a * 100)
        

        That’s why it didn’t have sense IF x THEN 1000, you always had to specify GOTO or GOSUB.

  3. > He has every single room description as a PRINT statement, and manually sets room exits along with these statements. From Magical Journey, where A is the variable which indicates the room the player is in.

    > This is wildly atypical. Consider Hog Jowl mansion (written July 1981, printed January 1982 in 80 Micro), which starts with room descriptions but uses DATA statements instead:

    Well, it somehow remembers me my own way of writing games at that time (I was ten or eleven years old). As you say, the average way was to use DATA, but I used to do something similar to (Sinclair BASIC):

    7000 REM Rooms
    7100 REM 1 Hall
    7110 LET t$ = "The hall of this house is really dusty. You can go up to the first floor."
    7120 LET o$ = "You can see a chair and a door here."
    7130 LET e(5) = 2
    7140 LET o(1) = 1: LET o(2) = 2
    7150 RETURN
    7200 REM 2 First floor
    7210 LET t$ = "The landing opens to a corridor to the west. You can also go down to the hall."
    7220 LET o$ = ""
    7230 LET e(6) = 1: LET e(4) = 3
    7240 RETURN
    ...
    

    I used to draw map with connected rectangles, which represented rooms. Each rectangle had a number, starting from the upper left corner. Also, all objects were assigned a number.

    I cleared the exits array and the objects array before the GOSUB to each room.

    This way of programming had two advantages:

    You don’t spend memory twice. Once you load the DATA info, you are spending double RAM for each room: both the description in the DATAs, and that same description in the locations array.
    It was trivial to debug the program.

    Well… what can I say. I actually found strange to see DATA’s in other text game listings, it seemed to me like impossible to debug.

    • IIRC in TRS80 BASIC when you READ a string, it didn’t duplicate it but assigned the variable with a pointer to the text in the DATA statement. This saved memory and also executed faster because it didn’t need to copy the text.

      As most of the early articles about writing adventures were for the TRS80, they used this method. And that led to it being used on other machines where it wasn’t so efficient.

    • I realize I hadn’t asked: Are there any games of yours I should be looking out for upcoming in the 80s?

  4. I wonder if the emulator is truncating the 255-character line 10 to only its first 240 characters (thus chopping off all the jumps to lines 82 through 86).

    If this is the issue, then the inserted line 305 might make the fix (for all locations, and also including a check for the player having light) if expanded as follows:

    305 IFDT=1THEN320ELSEIFA=72THEN82ELSEIFA=73THEN83ELSEIFA=74THEN84ELSEIFA=75THEN85ELSEIFA=76THEN86

  5. This all makes me wonder how viable it would be to make an educational game along these lines. You get a fairly fun game, but whoops, the coder screwed up a bunch of variables in a subtle way, timers are too short, objects move too slowly or too fast, rooms don’t line up how they should.

  6. Hey Jason, Thanks for the source code. Think I have everything working, although I only got 16 treasures in this playthrough: https://youtu.be/28oei-kl25E

  7. In all fairness to Peter Kirsch, I think you may have had a buggy version. When I checked the version I had, it did not have the typos at lines 810 and 1100. There were numerous other differences, as well. For example, mine had changes in spacing and nearly all terminating periods were preceded by a space. This begs the question, where did the listing originally come from? I had always assumed that it was Peter Kirsch’s first adventure prior to his involvement with SoftSide. It certainly wasn’t published by SoftSide, at least it wasn’t in any of the magazines (I was a subscriber from the beginning) and it wasn’t in any of the ‘Adventure of the Month’ series.

    Peter’s use of PRINT statements for room descriptions was actually very clever when you stop and think about it. When you use DATA statements, the strings are stored twice, once in the DATA statements and once in the string arrays. If you check his later games, you can see that he quite often stores a constant room description in a string, then prints that string. For example, in his initialisation, he may use J$=”a maze of twisty passages, all alike.”, then he just prints J$ in the (say) 12 rooms with the same description, thus saving 23 repeats of the same string. He also use IF statements to vary the room description, if needed. You can’t do that with DATA statements.

    I’m sure his rationale for doing this was to minimise the changes needed when writing games for the three platforms – Apple II, TRS-80 and Atari 400/800. Unfortunately, he didn’t make use of the Atari’s dynamic access to DATA statements. He could have just stored the strings in DATA statements and RESTOREd the line that the data statement was in, then READ and print the data in that line, although that negates the use of commas, so he’d have to handle those with multiple DATA statements, a technique I used to use myself back in those days.

  8. Aha! I spoke too soon. A Google search found an archived version of this blog post, where I found that Magical Journey was published in “The SoftSide sampler: TRS-80 entertainment programs” and it’s available on the Internet Archive. I can now see that your version and my version are both different to the original listing, no doubt typed in by different people. I’ve always wondered where this program came from. Now I can sleep easy.

    • Yes, this was all about starting from the version I had and checking against the book (without have to go through every line and spoiling the game). Where did you get your copy from?

      (Btw, printing errors can also happen, so even if the book had an error it might still not be kirsch’s fault! That happened with Arctic adventure.)

  9. I’ve never been very good at recording where I downloaded games from, so I have no idea where I downloaded this one.

    I’ve finished comparing the listing I had against the book and correcting any typos. I did this in a text editor, saved it with the 0x0d carriage returns, manually changed the 0x0a linefeeds in a hex editor, imported it to a disk image using TRSTools, then loaded it into the TRS32 emulator. After all that mucking about, I discovered that it doesn’t like the 0x0a linefeeds when reading from an ASCII file. I then edited the listing to remove all the linefeeds, only to find that some of the lines are too long. The TRS-80 has a maximum line length of 240 characters. As an example, line 10 is 255 characters and this is why you can’t access rooms greater than 81. The line is truncated at that point. Lines 650, 850 and 2000 are also too long. It would have been impossible to type the listing as printed, so I wonder how Peter Kirsch managed to do it.

    I’ll see if I can edit the file to get a workable copy, but the line numbering makes this pretty awkward.

    • Easier way to port trs-80 code over is either

      1.) dump it all in the code at willus.com when you open a BASIC file — I’d recommend just using magical journey’s and overwriting it — then do the “run edited program on disk”. If you then export “disk 0” it’ll have it as a DSK file which automatically runs the BASIC source you made

      2.) or you can use trs80gp, start BASIC, and use paste with the whole thing in clipboard

  10. Okay, I’ve got a runnable version. Let me play it first to make sure it works okay. It’s 2:40 a.m. here, so I’ll have to do it tomorrow. I’ll get back to you in a day or two.

  11. Game completed with 17 treasures and visited all rooms.

    There are a couple of bugs, but nothing that prevents you completing the game once you have fixed the line length issues. The main one is rubbing the sticks. If you do this before visiting the underground cavern, it tells you you’ve started a fire, but the 2 twigs don’t change to burning twigs and the underground cavern is lit, so you don’t know that it was dark in the first place. This is what happened to me the first time I played. Even if you rub the sticks in the underground cavern, you can drop the burning twigs somewhere else and the underground cavern is still lit. The underground cavern is the only room that’s dark, even though there are lots of caves and tunnels that you would expect to be dark.

    Overall, a fun little romp, but nothing very challeging, apart from the maze-like map in some areas.

    • Bug where you can drop the lit object is authentic. Bug where you don’t get the burning twigs object is not.

      If you post up the code (or just email) I can give a check

  12. I couldn’t see any way to include an attachment, so email sent.

  13. Whoops. I was wrong. When I re-checked, rubbing the twigs did change them to burning twigs. I could have sworn that didn’t happen before.

  14. Shared copy of the fixed source code in DMK form so that it will auto-run the BASIC file in a TRS-80 emulator:

    https://drive.google.com/file/d/1HDdDaxkvjz-dTCra9oUlJedIulXLKt1j/view?usp=sharing

  15. Just read your preliminary Dr. Who playthrough. Sorry for the SN error. That version is quite old (in my github numbering system its #3 versus the most current #16). Here’s a link to my latest MC-10 distro: https://drive.google.com/file/d/11pXdOi8f4RvfvnD3NlCwaD3EMV-K7DGV/view?usp=sharing

    I’ve just completed bringing back to life an old magazine type-in from July 1981 called “Castle Adventure” by Dave Trepasso published in Computronics Magazine April 1982. It’s file CASTLE will also be added to the distro file shortly. https://jimgerrie.blogspot.com/2024/03/castle-adventure-by-dave-trapasso-1981.html

    • Thanks! Since there’s no save feature it didn’t really hurt that much.

      And I will add Trepasso to my list.

      • Also just brought back from death a magazine series from 1991 presenting a BASIC text adventure game engine and sample adventure. The magazine folded before the final installment of the series, so the sample game was never finished, but all the location and items were in place. Just had to put those clues together and use the complex adventure engine tools to program the “input” and “reactions” scripts to actually allow for the completion of the story. If you played it, you’d likely be the only one after me to have ever done so. Here’s a link: https://jimgerrie.blogspot.com/2024/03/adventure-by-lets-compute-magazine.html

      • nice!

        while we’re in this thread, I still need to make a post about Magical Journey being fixed at least just for reference. Do you have a link to your version or just the video?

  16. All my game ports can be downloaded as a zip distro (“Download” button), or played online (“Play” button) through my GameJolt page:

    https://gamejolt.com/games/jgmc-10games/339292

    If you select “Play” just have to click on the “8-bit Basic Text Adventures” menu item and then select MJOURNEY from the cassette menu. Then type RUN and hit Enter on the main Emulator (green) screen. Or my stuff (but not MJOURNEY or LCADVENT yet, but soon hopefully) can be downloaded or played online from the Coco Archive:

    https://colorcomputerarchive.com/repo/MC-10/Software/Games/Jim%20Gerrie's%20Games/

    And hopefully from the Internet Archive, if the bugs can be ironed out of its Emularity for the TRS-80 MC-10.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.