Saturday, 5 October 2019

RetroChallenge 2019/10: Akalabeth Updates

Bug Chasing

I have been debugging my initial attempt to port of Akalabeth to MC-10 equipped with MCX.  I found a number of bugs I had put into the code, and possibly one that is from the original program.

The first bug that I discovered that was my fault was that I missed putting a few 1s at the end of LINE commands. In MS Basic for the MSX standard, you can leave off a number for the color of lines to be drawn by the LINE command. If it is left off the default color set by a COLOR command is used.  But with the Extended Color Basic of the MCX you have to supply either a color number or PSET or PRESET.  PSET is the way to designate the default color, PRESET provides the default background color.  So I had to add lots of 1s to all the LINE commands, and there are lots of them, so I missed a few in my initial edit.

I also found a place where I hadn't replaced a PRINT command with a call to my hires text routine.  When MCX BASIC hits a PRINT command while in hires mode it automatically bumps you out of hires and back into text mode.  This is different from regular extended basic, which can just print the text to the text screen, which is kept in a separate place in memory.  This happened in the Magic Amulet routine when you choose the BAD option and get turned into a Toad rather than a Lizard Man. You'd be switched to text mode and the message "You have been turned into a toad" would be printed on the text screen.  I fixed that problem.

I also noticed that I was down to only 240 bytes after all the main variables had been DIMed and the program had run through most of its routines.  So I decided to trim the program down a little more by consolidating a few more lines using colons and switching a few main array variables from two character long variable names to singles.  Now the DN() and TR()--dungeon and terrain variables are just D() and T().  I also changed the Stats to just three character shorthand (STR/INT/WIS/STA etc.).  This not only saves memory but provides more space on the setup screen, as I realized that Stats and Items can rise to the level of 3 digits, if not more.  Now there should be space for up to five digits for items and stats.

I found a number of errors with the Pause routine. I also added pauses and clear text window commands in a few places to improve the display of information in the bottom left "Command" window.

I found an interesting website that had playthrough information.  It was really helpful in allowing me to playtest and find some of these bugs:
I turns out there is a bit of trick for getting an easy win.  Just choose the Mage, rather than Fighter, and in the first battles, choose the BAD option of the Magical Amulet, which can possibly turn you into a super powerful lizard man.  If the Bad magic turns you into a Toad, then just re-start.  Using this technique and the high speed setting of the emulator allowed me to play through many attempts at getting down to lower levels to see most of the higher level monster.  This is how I noticed that I had missed putting 1s on a few LINE draw commands.  The high speed option of the VMC10 is really helpful for game testing.

Balrog which only appears at level 8 and deeper
I also sped up the text rendering by switching to using ASC to test component of the array that stores the info to draw the letters rather than using VAL. The text draw data takes the form of numbers 1-9.  Now this triggers references to an array with elements containing DRAW commands with those elements stored using numbers 48-57 rather than 0-9.  The nine drawing elements created a coarse set of letters and numbers from drawing element arranged like this:

|  |  |
2  8  4
|  |  |
|  |  |
1  9  5
|  |  |
This allows me to create characters like this lowercase G:
|  *
8  *
|  *
|  |  *
1  9  *
|  |  *
All I have to do is encode 9 digits for each character, such as the G, as follows: 023456700
As you can see, the 1 location and the 8 and 9 locations are zeros and therefore render blanks.  The others using the ASC code will select for their appropriate draw string (48-57) for rendering that character.  By using ASC to do this I can also use a MID$ command without its length argument, since ASCII just send back the ASCII value of the first character of any string.  So this shaves off a further two characters in the command: From MID$(A$,T,1) to MID$(A$,T).  Every little bit helps and I think the ASC command probably is just faster than VAL command too.  I chose to render letters as lowercase because this seemed to give the most differentiation between letters and also generally used fewer lines. Again, every little bit helps.  Some of them like the K and X are a little abstract, but for the most part they seem basically readable.

A Bug that's not mine?

The bug in the original code that I think I found involves a rare condition in which all your items have been stolen (no weapons) and a thief is attacking and randomly stealing items. The routine for it to randomly select an item stored in your items array simply keeps looping back on itself if it finds an array element that is empty.  But if all the items are empty it just keeps looping back in an infinite search for something for the thief to steal-- freezing program execution and never triggering the "you starved to death" routing that will allow the game to end properly.  I fixed the problem by doing a check that all items aren't empty before allowing the program to proceed to the theft search.

I'm now up to AKALABETH_MCX11.TXT in my Github repository:

No comments:

Post a Comment