Thursday 29 December 2022

"Dr. Who Adventure" by James Smith (1982)


I ported this text adventure quite some time ago, but my techniques for squeezing games into the 20K space of the MC-10 have improved a lot since then.  I now don't have to use the two-file data-loading methods that I discuss in that post.  I've learned other ways to save memory space, especially regarding the management of string space.  By renumbering lines by ones and using all my other memory saving techniques I have now got Dr. Who Adventure to fit into 20K.

I worked from a scan of this game first published in Australian magazine Micro-80, Volume 3, Issue 8.  It was not a very good scan, so it was a real challenge to get the game working.  And once I did I discovered a very challenging early 8-bit BASIC text adventure. Originally requiring the loading of two separate programs to allow it to fit in the memory of a 16K TRS-80 Model 1, I have finally succeeded in modifying it to work as a single program for the TRS-80 MC-10.  I have also made some bug fixes (many of which I can't remember). However, the most significant is probably this one:

890 IFRND(0)>.998ANDWTANDPS<>99PRINTSY"hit over the back of the head and everything goes black...You awake to find that everything you were holding is gone.":FORI=2TO16:IFO(I,1)=90THENO(I,1)=6:NEXTI:GOTO840ELSENEXTI:GOTO840

This routine involves you getting mugged and all your items NO(I,16) from I=2 to I=16 being moved to location 6. Unfortunately, Smith did not also add the code needed to deduct the "weight" of each item from your inventory. They just get re-located. Since you have a max weight of 20 (each item has its own distinct weight), once you are mugged it's possible that if you recover the items you won't be able to carry all the ones you need back to Galafry to win the game. You have to be carrying the items when you reach the throne room and "talk" with the other Timelord there. Other items also "disappear" without subtracting their weight, but most of these were game ending anyway, since they involve you giving away or eating items, etc. that you need to win. In any case, I rationalized all the dropping/giving /eating routines to subtract the weight of the lost items.

Another significant bug involves the jumping out of FOR/NEXT loops. This has the practical impact for memory saving that all NEXTs have to include the variable reference, otherwise strange results can occur in the return to the top of unclosed FOR loops. The offending code occurs in the very fancy multiple word parsing subroutine:
860 J=0:K=-1:FORI=1TOLEN(A$):X$=MID$(A$,I,1):IFX$=" "THENIFKTHENNEXTIELSEK=-1:NEXTIELSEIFNOTKTHENSW(J)=SW(J)+X$:NEXTIELSEIFJ<5THENK=0:J=J+1:SW(J)=X$:NEXTI
870 FORI=1TOJ:SW(I)=LEFT$(SW(I)+"   ",3):NEXTI:K=0:FORI=1TOJ:A1=1:AN=78:FORI1=1TO78:AI=INT((A1+AN)/2):X$=MID$(SC,AI*3-2,3):IFSW(I)>X$A1=AI+1ELSEAN=AI-1
880 IFX$<>SW(I)ANDA1<=ANNEXTI1ELSEIFX$=SW(I)V(K)=ASC(MID$(S1,AI,1)):K=K+1:IFK>2THENGOSUB1840ELSENEXTI:GOSUB1840ELSENEXTI:GOSUB1840
I unraveled all the ELSEs used in this code and then made it so that the FOR/NEXT loops exit gracefully. This allowed me to remove all the variable references attached to NEXTs.  And it also prevents the variable stack from blowing its lid, which is deadly when you're trying to save every byte.

I have also changed some of the parameters of the game that were overly frustrating. You used to be limited to a random number of Tardis rides, which ranged from 20-40. Since the planets the Tardis goes to are arbitrary whenever you "reset" it, the game can be quite arbitrary in the level of challenge it presents.  I simply set it to 40. The random location selection is challenge enough.  I also changed the "search" function to a much lower level of possibility of not revealing items hidden in rooms.  As well, I made the "Renticulator" device report the exact number of required items that you have found.  It used to report a randomized "approximate" number. I made it report the exact number of required items  because it will be tough enough for people to figure out what it does, although a hint is given in the instructions published in the magazine and included in the CASA: Solutions archive description of the game.

Smith obviously loved using randomness to make his game more challenging, but it was to an extreme extent-- a typical flaw in early BASIC text adventure games.  Many authors of the era took grotesque pleasure in making their games diabolically tricky.  But it could often be too much.  In this game there are random mazes and random events a plenty, such as the "mugging" or walking off cliffs etc., so I don't feel bad about toning down the arbitrariness.  There is a really clever game here under all the gratuitous arbitrariness, with lots of interesting NPC interactions (for an 8-bit BASIC game) and a clever sense of humour, which I want other people to try and enjoy.

'PlayDalek' is pretty hot stuff

DRWHO can be played online here:

The VMC10 Emulator with DRWHO in the JIMG subdirectory of the Cassette directory can be downloaded here:

Friday 9 December 2022

Usborne Books "Dungeon of Doom" (1984)


By Les Howarth, Cheryl Evans and Chris Oxlade, this game was the example program at the heart of Write your Own Fantasy Games by Usborne books. It's a fairly straightforward RPG, but unlike many others of the era it lets you design endless dungeons and characters. You can create dungeons of  up to 5 levels of difficulty (I have changed this to 9 for my version). I ported the game to Micro Color BASIC for TRS-80 MC-10 from BBC source found on Github typed in by Brian C as a first step to his conversion of the game to the modern Ruby programming language. I added a simple 3D first person view using a SG4 graphic system mocked up by Erico Patricio Monteiro. He's a real wizard of semi-graphic design. I have wanted for some time to find a program that could put his 3D graphics to good use. I think this one does that nicely.
 
The most difficult part of the conversion was re-creating the save/load features for the dungeon maps and character info. I had to consolidate various array variables so I could use a single CLOAD*array,"FILENAME" command for each file. For example, the map data also needed to save the starting position and level of the map.  It took a while but I was able to do it. The other thing I had to do was consolidate three separate programs (Map Maker, Character Generator, and Game Play Module) into one. This would allow me to post the program on the Net in a simple way for people to try it without all the fuss of loading and running multiple programs. It also allowed me to allow the player to create a character, map and then simply play the game from a single menu. However, you do get presented with the options to load files if you wish and are playing on an emulator that allows file saving and loading or on real hardware. The program requires you to create or load a character and create or load a map before it will allow you to enter the play game option of the menu.

I needed the 3D option because the original program used character redefinition to create unique character graphics to represent the items on its two-dimensional map of the dungeon. However, redefining screen characters is impossible on the MC-10. Instead, I simply upscaled the 8X8 redefined characters into SG4 8X8 pixel images that get presented in front of you on your first-person view when you come into contact with them.

DDOOM
3D View Top Left, 2D Map Top Centre

Meanwhile on a simple 2D map, you can see the walls, with monsters and traps flashing briefly as you move.  Activated monsters and traps briefly flash red and then monsters move to track you in the regular wall colour (cyan). Other items flash briefly but simply in the wall colour. They all appear when they are right next to you as you move, or when you use your torches to (R) "Reveal" in a grid up X3 in the 4 directions around you. Torches are limited, and pressing "R" also activates monsters, so torches have to be used carefully.

In the course of porting the program I uncovered a few bugs and quirks that I "fixed:"
  1. In the Dungeon Maker the variable used in the (O) "Offer" routine that allows you to haggle over prices was incorrect. The amount removed from your gold supply was the secret lowest possible price used by the computer to assess your offer rather than your offer.
  2. When you bumped into a monster while another monster was already active, the monster you bumped into wouldn't activate, but simply sit there. The program would remove a small amount from your health if you kept bumping into it, but that was it.  You couldn't even initiate conflict with it.  You could only fight the active monster.  I changed the program so that when you bump into monsters they activate and attack.  Any other active monster deactivates. The primary changes occur in line 210
  3. In line 2460 the DATA statement lists some short hand names for weapons and armour.  However, it was defined in a way that seemed different from the weapons and armour list of the character definition program. These short hands are used in the combat routine to indicate weapons that get broken. So weapons would be reported as broken that your character would not even be able to own.  So I realigned the two lists.  The problem was that the Game Play module was missing the broad sword, so everything was off by one.
  4. Line 1310 contained a real game breaking error discussed by WhatHoSnorkers. The metamorphosis spell randomly allows magical users to materialize any of the graphic characters used in the game in front of them. This included the "Idol" character, which ends the game in victory (conceivably to used only on the last of the levels of your dungeon).  So you could enter the dungeon launch the spell, get an idol, and finish the game. I created a short sub list of items that does not include the idol or exit from the level.  So you can materialize chests, safe spaces, vases, monsters, entry doors and traps.  Also, if a monster appears, it wouldn't necessarily activate and attack. The program made a check that if anything else appeared, it would deactivate any active monster on the chance that the materialized item actually was created in the space of that monster (i.e. transforming it into the new item and replacing it).  So I switched the program to just deactivate any active monster, and then check the transformed space to see whether a monster was there, which would then activate it if that was so. Otherwise, you are safe. These changes occur in the line 1340 area.
  5. There was an error in my BBC source, but not the original listing in the book, whereby experience was increased by .5 for every monster killed instead of .1, which made advancement too fast. The BBC micro also used the short hand "CAN" for labelling the number of your torches. I think this was for candle. I changed it to "TOR" for torches, since that is what is used in the Character Generator module. I have made further tweaks (downward) to the EXP earned so that experience keeps better pace with moving through dungeons with about 6-8 monsters slain  providing enough to get the player to the next level.  So when making dungeons, I would recommend putting at least 6, if not 8 on each level.
  6. Around line 1480 I added a routine to give the player random weapons when chests are found and "Got" if they are a fighter class (only weapons they are entitled to carry). This occurs only for a random number of chests opened. Similarly, you can on a chance of 1 in 6 find one of the 6 magic spells if you are a magic using class. Finally, there is a random chance (1 in 9) to find 2 torches. The original game provided no way to replenish broken or used up items. And weapons get broken quite frequently. The result is that your character would just get progressively weaker the deeper you went, which goes against the general principle of designing dungeons to get tougher as you go deeper.  It also gives a greater incentive for searching for chests than the single treasure point you get for each, which only contributes to your score. Now chests also play a practical function as well.
  7. In lines 620-650 the monster seeking routine was weird. A monster could get hung up on corners because the move routine was based on decimal incremented moves. These decimal moves were done to allow for different speeds for the monsters. The highest of the 3 would track the fastest, but the result was that often a monster could only always get at you once you moved to a parallel fully open track. I changed the system to move using only 1 space for each move, but that moves were activated only a random number of times based on the monster type. So the 3rd of the monsters is still the fastest, but there is also a slight randomness to all of their movements.
  8. Line 250 of the source has an IF that checks for I$>"" which was meant to trigger a small decrement of your health/strength for movements and actions.  When you input a command to move or do something then I$ will not be equal to null (<> "").  In other words, you've used energy.  Maybe the I$>"" command works on BBC BASIC to achieve this but I doubt it would work on any Microsoft incarnation of BASIC.  But I didn't spot any alternative code listed in the original book notifying the user to change this line for the other computers accommodated in the book (C64, VIC, Sinclair Spectrum).  So I think it might simply be a typo.  The result would be that you would not expend energy when doing stuff, just when fighting, which might have been bad enough and so the missing effect probably wasn't noticed by the programmers when testing.
  9. Line 730 defined the chances for monsters to break your weapons.  However, it does so in a way that seemed to make it more likely for the lower level monsters to break stuff more easily than the higher.  It simply looks for whether a random number based on the monster codes -2 (i.e. 7-9) equals 1. That means the lower 7 monster has a higher chance for a 1 to occur (1 in 7) than the higher monster, which only has a (1 in 9) chance.  I switched it so the higher level monster has the higher chance of breaking things.  It should be consistently meaner.  It certainly does more damage and moves quicker.  This should allow for the user to populate deeper levels with more of the higher level monsters to make those levels consistently tougher.
  10. Line 1630 is where to score is calculated. It involves using your current experience F(5) as a multiplier of treasure and also adds your strength and vitality, but it also adds your agility F(3) stat, which seemed strange, as this state never changes in the game beyond what you set it to when creating your character.  I think the reference was a mistake (between F(3) and F(5)) and that the authors really intended to add your current strength, vitality and experience level in their calculation, since experience level is a stat that changes depending on your performance.
  11. In line 50 of the Game Module, which checks for whether you have hit the "F" key to fight with a monster, there is also a check to see if the monster is actually active. That check was IF DX<255.  DX is the numeric value for the horizontal difference between your X location and the monster's X location. There is also a DY, which is the difference in vertical distance.  If no monster is attacking or when a monster is killed, DX is set to 255, so this variable plays the dual role of being the flag for when a monster is active and when you are not under attack (DX=255). Clearly, the authors were making sure that when you chose to fight, that a monster was also trying to fight you. But by not actually checking the specific distances of DX and DY, you could fight monsters through walls and even at great distances, once they were activated. This seemed very strange. So I changed the check to require that the distance between you and the monster in both the X and Y directions must be under 2. In other words, you can only fight monsters if they are next to you or right on top of you (i.e. zero distance--in your square-- which is also possible).
  12. I changed the Cleric class from being able to use only a knife (just like magicians) to being able to use the mace and the gauntlet. When I played original D&D, Clerics could use maces.  And why not a gauntlet too?  After all, they are acting as God's right hand against the denizens of the deep!
  13. The program excluded the shield from the calculation of your armour strength. I think the authors probably actually intended to exclude some of the shinier items like the gold helmet and the headpiece.  I suspect that they wanted to use such items as red herrings to lure the gullible into spending their money recklessly.  However, I think they might have at one point (as noted above with the differences in item lists between modules) shuffled items to perhaps help create a better illusion of legitimacy of the red herring items and inadvertently left out the humble shield from the calculations. I changed it so that the headpiece and gold crown (gold is relatively soft, and likely to be thin if used for something as large as a helmet) don't factor in, but that the humble shield does. The shield is one of the items that non-fighter class characters have access to, such as the cleric, so it is an important item for the purposes of balance.
  14. I made Spell 1 somewhat variable in its effectiveness. It allowed you a one shot kill of a monster, which seemed excessive. Now it gives you a 1 in "Your Aura" chance of failing to work. So the higher your Aura the better your chances the spell will be effective. And if your Aura decreases (which using higher level spells can cause), your general effectiveness as a magician decreases too.
  15. At line 1760 a check is made when you try to exit the dungeon to see if you have earned enough experience to be ready for the next level. It does this by checking your current experience level and seeing if it is at least +1 the experience you had when you started the level of dungeon you are on.  However, experience is calculated by percentage increments but only ever reported as an INT number, so you could enter a level with a certain EXP, say 5.2, which would be reported as 5, and then obtain EXP 6, but exactly 6 and be told you still "NEED EXPERIENCE." I found this confusing. So I changed it so that you only need to obtain INT(starting EXP)+1. That way, when you enter a level you know that you just need to get +1 whatever you see as EXP to be able to move on to the next level.
  16. Line 890 it reads "890 IF F(3)+F(6)< RND(M)+2 THEN M$=T$(4):HT=0".  Then just after that line you subtract the damage done by the player to an attacking monster: "900 MS=MS-H:GOSUB 430".  I think the reference to variable HT (thanks Greg Dionne for bringing this to my attention) is meant to zero out the damage if the player happens to miss (i.e. when message T$(4) is printed which is "missed").  But that doesn't happen because a different variable name HT is used instead of H.  In other words, the player never misses.  I suspect that when I fix this the difficulty of the game will go up.  I'll have to do some testing to see.
  17. I changed the reference to "Sire" in the "olden timey" lingo of the character creator routine to the plainer "Sir".  I think even in the middle ages ordinary folks weren't "sires"-- just the monarch.
Finally, I made some changes to make the game work better on the MC-10. The arrow movement keys are switched to the familiar (and marked) AWSZ diamond pattern. This necessitated changing the combat key from "A" for attack to "F" for fight.  I added a help screen in the Game Play module to let the user know what the keys do.  I also added a prompt to give you the choice of leaving when moving onto the exit. This way you can continue to scrounge for items. This was just a problem for the MC-10 version, since the player can't really identify objects, including the exit, until she/he tries to move into a space.

The program is called DDOOM and because it was an example program I have put it in my "Educational" list of program on Mike Tinnes' javascript emulator. Since Usborne is on record as having put their early computer books I am going to allow folks to use my version.  It can be played here by selecting DDOM from the Cassette list and then typing run in the main emulator screen:

The full emulator can be downloaded here. DDOOM can be found in the JimG subdirectory of the Cassette directory.


And if you want some premade dungeons, you can find a .zip file with 5 of them, and a couple of pre made characters throw in a this link: https://drive.google.com/file/d/1xs7ocowKySWy70H5Yt_wfkVfOUrL8pDy/view?usp=sharing

If you are looking for a classic RPG experience from the early 1980s 8-bit era, you should give this program a try.  It's a real nice one.


Acknowledgements

Thanks to WhathoSnorkers for his excellent set of videos on the game.  He was the one who made me aware of the game-breaking error that I discuss in #4 above.  His fixes and updates also inspired me to put in the fixes to the Chest routine, which allow you to find treasures, magic and torches.

Thanks again to Erico for his wonderful wall graphics.

Addendum

Here's me playing and winning a C64 version:


It's from a site with lots of useful information on playing the game:
Usborne Books has made its old programming how-to books available free to download: https://usborne.com/ca_en/books/computer-and-coding-books

P.S.

A new version of the emulator has been created by Greg Dionne and Mike Tinnes that allows for file load and save.  This greatly eases the ability of people to try the game.  I have created a little web page to allow folks access to the program via that version of the Javascrpit MC-10 emulator:

Friday 4 November 2022

Classic Rally-X Arcade Game Written in BASIC

I've been working on my attempt at a "re-programming" of Rally-X in BASIC for a while. But I've never quite been able to feel satisfied with it until today.  Darren Atkinson's  machine language subroutine for refreshing the screen from a large sequence of array strings was a big help.  Before it, I had been using a bunch of PRINT MID$ of the array strings, and it was just too slow to refresh the screen background in an adequate fashion.

Now it is just a barely noticeable page flipping background effect.  But the speed of game play was actually up to a point of being a little too fast for fair navigation with such a small window.  The enemy car can swoop in and really get you.  Part of the reason for that is that the key sensing routine that I was using consisted of the single check for all 4 directions:

ONK(PEEK(2)ANDPEEK(17023))GOSUB1,2,3,4

But as I have learned from Greg Dionne, these key sensing PEEKs have their limitations, and will occasional "latch" when certain double key combinations are input. When that happens, the only way to "unlatch" and be able to input a desired direction is to release all keys, hit another key other than the one you were trying to input, and then select the arrow key you wanted.  It's a fairly intermittent and rare effect, so in many game application its not a problem. The advantage of needing to do only 2 PEEKs to get a direction outweigh the occasional quirky response.  But in this game good reliable responses are really needed.  The enemy can really get close, and every keystroke counts. So I switched to the keyboard rollover peeks suggested by Greg Dionne. That table provides absolutely reliable return values for the four direction keys.  But it uses individual IF statements to determine which keys are pressed:

5 CLS
10 IF PEEK(2) AND 4 AND NOT PEEK(16952) THEN PRINT@1,"W";
20 IF PEEK(2) AND 1 AND NOT PEEK(16946) THEN PRINT@2,"A";
30 IF PEEK(2) AND 4 AND NOT PEEK(16948) THEN PRINT@3,"S";
40 IF PEEK(2) AND 1 AND NOT PEEK(16949) THEN PRINT@4,"D";
50 GOTO 5

In the past I would have recoiled over using multiple IFs and preferred instead to use a single ONK(PEEK(2)ANDPEEK(17023)GOSUB1,2,34 method.  The use of a "lookup" K() array in combination with the simple PEEK method seemed highly efficient to me. But I have learned that in Micro Color BASIC the IF runs very quickly in terms of its implementation in the interpretation of each command, whereas ON/GOSUB does not run so quickly.  Also, I was able to eliminate the A() array, which removed a variable from the variable table, which is good for memory and also a source for a slight increase in speed.  The fewer the variables that must be searched for each variable reference,  the faster things go.  And, as I noted, the game was running just a little too quickly anyway, so I could afford a slight slowdown.

I've also searched for all the "speedups" that I can in terms of the code.  I've eliminated all
IF A<>0 THEN references and replaced them with
IFATHEN references
I've replaced more ON/GOSUBs used instead of simple IFs, in speed critical areas of the code (the main loop mostly).  I was able to include some actions as a direct part of the key movement IFs, rather making jumps to subroutines.

I think all these final edits have contributed to making the game truly a playable arcade style game in BASIC.  I was inspired to make these efforts by the Racing Car game jam on Itch.io, where the challenge is simply to "have fun with our beloved retro computers," the retro programmers Facebook group https://www.facebook.com/groups/RetroProgrammersInside.

Here is a demo of game:


Unfortunately I can't do it justice simply because I'm carp when it comes to playing video games.  But if you would like to give it a try it can be played in the online TRS-80 MC-10 Javascript emulator:


Just select RALLYX from the Cassette menu and then type RUN and hit Enter in the green main screen.  The controls are WASD, just in case you can't read the characters in the chunky Semigraphics-6 font of the MC-10. The pixel resolution of that screen is 64 X 48, and there is not provision for regular text being displayed.  So unfortunately, the letters and numbers have to be rendered in the blocky pixels.  It takes a little getting used to, but with a little time you will be recognizing the letters and numbers.  It's just one of the limitations we users of this quirky 8-bit micro are used to.

Inspired by the smooth motion of the key input of RALLYX, I also decided to modify and update my version of Steven Wozniak's "Little Brickout."  Now it also uses Greg Dionne's PEEK method, and is much more responsive.  Since I was also using multiple IFs, I was able to make some improvements to the animation of the paddle that made it flicker less.  I could just remove the end of the paddle that needed to be removed to move it in a specific direction instead of both ends. Here's a vid of the new version:




Monday 24 October 2022

"Mosquito" by Mr. Slump (1985)

 


I ported a game to the TRS-80 MC-10 from for the NEC PC-6001. It was originally published in MICOM BASIC magazine 1985-01 (see above). This new version uses the SG6 graphic mode of the MC-10 rather than the higher res graphics of the original that can be seen in this pic:


My version looks like this:


Programs like this are fairly easy to port because although the images on screen look like graphical sprites they are in fact rendered using a "graphic character" module on the NEC PC.  I think that module is mostly for producing text on screen using Japanese characters, but it can also simply render Roman characters.  So underneath the apparent graphic game, the program is just printing and moving text characters on screen.  All I had to do was switch those characters to semi-graphic 6 characters to get a quasi low res graphic game for the MC-10 curtesy of the creative BASIC programmers for the popular NEC PC-6001 series (an intro 8-bit computer for many Japanese kids back in the early 80s).

You can see how the graphic character module actually allows characters to be printed overtop of each other in the original. For example, the player "sprayer" is actually just an uppercase V and an uppercase D overlaying each other.  I think the author felt it looked like some standard garden spray can, perhaps with a kind of handle.  But I had to render the player sprayer as a simple block with a nozzle sticking out to the left.  You can only shoot left.

The instructions published with the game were the following:
Press "s" to start the game. Move the spray can around with the arrow keys (on the MC-10 these are AWSZ and I used Greg Dionne's suggested key-polling peeks for better responsiveness and true 8 way motion through key combinations). Press spacebar to spray it. If the spray hits a mosquito it will die. If it hits the = that appear on the screen it will stop the spray. Kill enough mosquitos and the level will advance. If a mosquito touches your spray can it is game over, it’s also game over when you run out of spray. You start with 20 shots of it.

I found myself wishing that the game had more than 20 shots, or that there was some way to earn more shots than ones you start with.  But it would seem you are limited only to those 20 shots.  At my level of play I would normally get around 250.  It would be neat to know if other better video game players could score higher.

It's publication details are Micom Basic (マイコンBASIC) December 1985.

As usual it can be played online using an MC-10 emulator here (at least for a little while as I test the game and others do as well).  It's listed on the "Other 8-Bit BASIC Game Ports" menu item once you launch "the game" on GameJolt: https://gamejolt.com/games/jgmc-10games/339292

Here's a vid playthrough:



Friday 7 October 2022

David Meny's "Pirate Island" (1985)

I was contacted by David Meny about whether there was a place to play his old BASIC text adventure  games online (Escape from S.S.A.D.B. and Pirate Island).  I had already converted his SSADB (which he had noticed) and was working on his Pirate Island (PISLAND). He gave me permission to share them.

They can be played here: http://faculty.cbu.ca/jgerrie/Home/jgames_TextAdventures.html

In the course of porting Pirate Island, I noticed a few oddities:

First, the solution/walkthrough posted by Dorthy on the CASA archive seems to be missing an "OPEN DOOR" at the very beginning, which I needed to add to get out of the cabin you start in. It's possible the PC version she played was different.  The only thing with that possibility was that I worked from a PC GWBASIC source file that I found online.

Second, there seems no reason the player should be able to simply GET GARLIC after giving the captain the coordinates to find the Island.  The puzzle would seem to be that you should BUY the GARLIC from the cook after the captain gives you the bag of silver (your "pay") for providing the coordinates.  I think the fact that this changes after you give the coordinates to the Captain might simply be the result of a confusion between the flag variable for signaling that the correct coordinates have been provided and the flag for indicating that one has been given the bag of silver.  In any case, I changed it so you still have to BUY the GARLIC from the cook after your interaction with the captain, and also added a check that indicates that you do in fact have the silver to do so.  Otherwise, you could buy the garlic even without being given the silver (and you could also do it from any room, if you knew about it already).  I also added a check to allow you to GET the garlic (and not be killed by the cook) if you happened to put it down after buying it. I also fixed another oddity. You could put the bag of silver down but then you couldn't pick it up again (GET).  That routine only searched 12 items, instead of 14 (the bag of silver is item 14), so it couldn't see the bag was available to pick up if it was dropped.  I also noticed that the printing of a list of items in any room only seemed to print one item, even if others were in the room.  So I made it so that the program prints an exhaustive list of items in a room.

Finally, in the course of porting I streamlined the code and stripped out some redundant variables, fixed some problems with initialization and re-initialization and corrected a few spelling and style errors. I also had to shorten some messages in order to fit the program into the 20K available to expanded MC-10 (with its 16K expansion pack). I also changed it so that the SCORE actually adds to 200/200 when you win rather than 210/200 and I changed the way the score ratings function. Instead of not triggering a category reference if you happened to hit a score exactly at the junction between categories (i.e. searching on > rather than using a >= check to demarcate the categories), now the categories are exhaustive in the ranges they cover.

I also added a game SAVE and LOAD feature (it can only be used in a full emulator, not the online version).  In my correspondence with Mr. Meny I had asked whether his games had this function and he had commented that some recent online reviews he'd come across commented negatively on the absence of SAVE/LOAD, which he felt was a little humourous for relatively small 1980s BASIC text adventures.  I agree. The games don't need it, but it was helpful for me in game testing Pirate Island and relatively easy with the array save command of the MC-10 (CLOAD*Array). I just had to collate all the the arrays (and various flag variables) into a single comprehensive multidimensional array.

Here's a brief demo:


Wednesday 10 August 2022

Darin Andersen's "Dark Castle" (1984)

I ran across a type-in game listed on the "Giant List of Classic Game Programmers".  It was called "Dark Castle" by Darin Andersen and published in Rainbow magazine. I thought that a program that made it to the Giant List from the Coco was worth looking up, as that list seems more disposed to documenting Atari and Commodore programs. It wasn't a game I'd heard of, but I found a disk and cassette version of it easily enough on the Coco Archive.

The original title screen

It had a really neat hi-res graphic title screen, but otherwise everything seemed to be rendered on the ordinary text screen. So I thought I could swap a Semigraphic 4 image and make a version for the MC-10.  I tried my hand at recreating the feel of the original. I think it came out okay.

New SG4 graphic title page

As with so many of my attempts to port old games to the MC-10, I think I stumbled across a number of bugs in the original.  However, it's often hard to be sure that they are bugs or if the programmer was simply satisfied with the way the game played.  In this case, I think it might be a little of both. Until I made the corrections I found it impossible to win the game, or even get close to winning.

I'm not a great game player, but I do a lot of testing when porting and after a while, you inevitably get better at playing.  You also have an intimate knowledge of the code to draw on for play strategies. So when it seemed impossible to make progress, I started to suspect that there were serious problems.

I would typically get killed in the first 5 rooms. The most common reason for this was simply waiting too long to use a "healing" spell.  Part of the reason for this failure was that there was no report of your health on screen.  Instead you had to press a key (I changed it to "R" instead of "I") to get a report (i.e. "information") of your stats.  Your "experience" (XP) was always listed on screen, but from what I could tell, it made no difference in game play.  It was simply a kind of score of the number of monsters you'd killed.  It seemed to make more sense for your health to be listed on screen so you could make a better judgement of when it was perilously low and that it was time to hit "H" for a "healing" (a healing spell?).  Otherwise, you had to continuously interrupt combat/play to check your stats, which was annoying.

Main Bugs

The other reason I died so easily was that all the monsters seemed to do the same level of damage (around 15-20), which could kill you in 5 or so hits. This was despite the fact that their stats seemed to indicate a range of power: hit points and damage done and experience gained.  But when I looked at how the damage done variable (D) was included in the calculation of an attack, I saw that it wasn't.  Instead the value used to calculate whether you had been hit, as adjusted by your armour and shield, was used (R).  So if you had a shield (1) and leather armour (2), an RND 0-19 value was generated, then the armour/shield value was subtracted, an a determination made of whether the value was below 12.  If so, you were saved from being hit. So, if you "rolled" a 19, this would be reduced to 16 from your armour adjustments and you would be hit since the value was above 11.  Then the damage done would also be this value.  So in effect the value of damage for any monster could only be between 12 and 19.  Actually, the math had the shield being subtracted from the armor and then the result subtracted from your random 19, which makes it worse for you to have a shield.  I fixed that.

277 '<><><>< MONSTER ATTACK
278 R=(20-0)*RND(0)     Why (20-0)?
279 R=R-(AC-SH)            Why subtract shield value (1) from armour (2-5) before subtracting both?
280 IFR <12 THEN 86      No hit if number is above 12
281 CLS 4
282 ST=ST-INT(R)          Why use the number calculated to hit as the damage?
283 PLAY "O1L255V30CEDV10O3"
284 IF ST<0 THEN CLS0:GOTO 286
285 GOTO 81

And I changed it so damage is determined by the number assigned for each monster type, which is stored in variable D when each monster is selected for an encounter.  So the more dangerous monsters can cause significantly more damage (Vampire and Beholder), but the weaker ones much less (blobs and orcs).

This also fixed a problem with the "hunger" routine. That routine cycles in colour from cyan to yellow to red (extreme hunger) as you move about and fight.  If you are in the red too long, then a value of 3 would be assigned to D and a call made to the monster hit routine. Since that routine didn't use D, but the last monster "to-hit" value (R)  instead of beginning to languish from hunger, you could die quite quickly.  In fact I didn't even realize that the hunger routine was doing this.  Every once and a while, it would just seem like an invisible monster had started hitting me after combat had finished. Now, hopefully, the player will realize that the red "hunger" light needs to be attended to before the player starves to death.

Another difficulty I faced was that you only run across Markets to replenish items every 15 rooms

139 IF RM/15<>INT(RM/15) AND RM<>1 THEN RETURN

This seemed crazy hard. You also had to make it through 45 rooms in total before branching to the final Gem/completion segment of the game, which also seemed a excessive slog.

134 IF RM=45 THEN 300

It is not uncommon for weapons to break, leaving you completely defenseless early on in the game.  Since the monsters travel one-to-one for your moves, if you lose a sword early and have no backup, which is likely at the beginning when your resources are scarce, you're done for.  There is no way to out-distance all the monsters you will encounter until a Market appears in room 15. It seemed unreasonable, so I shifted it to every 5 rooms for a Market to appear and I adjusted the treasure values earned from defeating the different monsters downward by half to help account for the higher frequency.  I also used the "experience" count to improve your ability (slowly) of avoiding weapon breaks (RPGs should reward experience). And when you buy an expensive "teleport" it will not only take you to a Market, but will jump you forward a room.  So hopefully now it won't be quite a slog.  A win should be within reach of an evening's play.  Perhaps back in the day (when software was scarce) the author and others would have accepted weeks of monumental and perhaps forlorn effort.  Perhaps playing for highest experience would have been reward enough when you were competing with friends around a single home computer.

Such reward might have had to be enough because it also seemed that the instructions for the final gem finding game stage were missing.

134 IF RM=45 THEN 300

The instructions begin at line 296 but no jump is made to that number.  So the player would just be thrown into that final game completion sequence at 300 without any hints about what they had to do, including the critical instruction to press "M" to bring up a map of the location of the gem.  So I changed it so that the instructions are shown and I tried to clarify them.  The sequence involves moving your blue dot across the screen while avoiding a spider (red dot).  You must run off the edge of the room in the appropriate directions to move yourself slowly towards the part of the room where the diamond is located.  Again, since the spider dot moves one-for-one for your moves, it will eventually zero-in on you and then keep hitting you until you are dead (you go into the final screen with your strength from the prior stage).  Again, it seemed unwinnable.  So I changed it to the spider moving 3 out of 4 of a random number of 4 for each of your moves.  So if you move carefully and make good judgments about which edges to head for, you can avoid contact.  I also made the position of the gem and the location of each spider random, rather than fixed.

Other Improvements

I improved the checks to avoid overlapping items on the screen such as where the Monster Portal and the Markets appear.

I got rid of all the redundant LET commands.  Tightened up the code and applied speedup techniques (removed spaces, IFTHENIF rather than AND, shortened variable names, removed redundant variables, packed lines, etc.)

I also tweaked the cost of a few items.  Fixed some spelling mistakes.  Added some "hit C key to continue" prompts.  Improved the movement bounds checking.

I added more detailed graphics for the monsters and other items in the rooms and also the player character graphic.  Here are the new monsters I created:


I think these look much better than the simple blocks and dot graphics used in the original.

Final Thoughts

There are probably many other tweaks and changes I have missed discussing here, but the above are the main ones.  I think I have made the game more playable and winnable than the original.  It is still tough.  You have to pay attention to hunger and your strength and make sure to buy enough food and "health" spells to replenish yourself.  You have to make other good purchase choices, such as getting extra replacement swords and bows as soon as possible. Other strategies include avoiding combat and simply heading for the door.  Use bow attacks to avoid damage. With some luck, you should be able to make it to room 20, where there will be a Market, which you can use to get your health maxed and proceed to room 21, which will trigger the final "Gem Room stage."

I think the original game might have been very frustrating.  I am doubtful that anyone ever made it to the end of the full 45 rooms before the Gem stage. And if they did make it to the Gem room, I imagine that few completed the game without the instructions to help them figure out what to do with the "moving dot" before the spider came and pummeled them to death.  So why did the game make it on to the "Giant List of Classic Game Programmers"?  It might have been based simply on the appeal of that super cool title screen!

Here's a playthrough of the fully updated version:





Tuesday 26 July 2022

Larry Bethurum's 1966 "Bingo"


I have ported a very early BASIC game program from a Dartmouth-style BASIC to Micro Color BASIC for the TRS-80 MC-10. The source code I worked from required a fair amount of debugging to make sure that the game operated properly.  Although the game is noted in the Wikipedia discussion of the early history for video games, it was very difficult to find source code for it using Google.  Simple searches using the author's name and the game title didn't produce any links to source but only details like those mentioned in Wikipedia, such as:
Larry Bethurum, from the Phillips Exter Academy, submitted the BASIC source code of a bingo game to the DECUS user group. Comments in the code suggest the game was written on January 23, 1966 [gamicus.fandom.com/wiki/1966_in_video_gaming]
It was only when I returned to the mention in Wikipedia that I was able to chase down a reference link to the source code preserved on a Net archive site: http://pdp-10.trailing-edge.com/decuslib10-01/01/43,50110/bingo.gam.html

There were some major bugs in the source that would have prevented proper operation of the game:

1580 REM  THIS IS THE SLANT CHECK (M=-1) FOR BINGO*** 
1590 X=F
1600 Y=F
1610 IF B(X,Y)<>0 THEN 1740:REM FIXED ERROR-- CHANGED TO 1740 FROM 1720
1620 X=X+1
1630 Y=Y+1
1640 IF Y<F+5 THEN 1610
1650 IF Y=11 THEN 1700
1660 PRINT"YOU'VE GOT A   B I N G O * * *"
1670 W=1:WW=WW+1
1690 RETURN
1700 PRINT"I'VE GOT A   B I N G O * * * *"
1710 V=1:VV=VV+1
1720 RETURN

1730 REM  THIS IS THE SLANT CHECK (M=1) FOR BINGO***
1740 X=F+4
1750 Y=F
REM 1750 LET Y=X (THIS SEEMS TO BE AN ERROR)
1760 IF B(X,Y)<>0 THEN 1880
1770 X=X-1
1780 Y=Y+1
1790 IF Y<F+5 THEN 1760
1800 IF Y=11 THEN 1850
1810 PRINT"YOU'VE GOT A   B I N G O * * *"
1830 W=1:WW=WW+1
1840 RETURN
1850 PRINT"I'VE GOT A   B I N G O * * * *"
1870 V=1:VV=VV+1
1880 RETURN

The highlighted errors would prevent the program from jumping to the "slant check" for Bingo (bottom left to top right corner) at line 1740. And the error within that routine of assigning Y=X would have then prevented that routine from operating correctly even if it was jumped to.  Also, the search routines for the other directions used many jumps from out of uncompleted FOR/NEXT loops, which might not have caused problems on the original platform (some kind of DEC minicomputer) and BASIC, but put the Micro Color BASIC on the MC-10 into conniptions.  So I also had to change all those search routines so that proper exits from those FOR/NEXT loops occurred.

When the player chose to "play again" the program returned to a point at the beginning which involved re-DIMing already dimensioned arrays, which causes an error in Micro Color BASIC.  It also did not not zero certain variables like the win checks for each player stored in V and W or RESTORE the READ pointer for re-reading data. The original version of BASIC might have done this automatically, perhaps when re-dimensioning occurred, but in Micro Color BASIC, the process of re-starting had to be fixed to prevent these problems.  

It is possible that some of these bugs may have prevented users from having a particularly happy experience with the program, which might explain why there is so little record of the game on the Net today.  Or these might just have been bugs that entered into the program in the course of someone typing it in from the DECUS newsletter in which it was originally published.

The game was originally written for a system that would have printed its results on paper.  The program makes reference to "Dartmouth" as the location from which the program is being run which seems a reference to Dartmouth College, the original home of BASIC.  So it seems likely that the program was originally meant to be run on a Dartmouth BASIC time-share system using a printer as the primary output device. This would have prevented anything in the way of dynamic interaction between the user and the program. In effect, the program simply runs a virtual game of Bingo, which the user was encouraged to follow along with using "a pencil" and the printout of the two cards (the user's and the computer's).  The user is told to mark both their own and the program's card. Then the program would declare (and print) the winner at the end. So in the course of my debugging I decided to add some new options to increase the challenge of the game in keeping with its new 8-bit home computer environment.

I added MC-10 graphics around the bingo cards.  I added a display of the numbers on the cards being marked in reverse video.  Then I decided to add an arcade element.  The user must spot and "mark" the numbers of their own card under the constraint of a time limit. This was meant to recreate the tension of real Bingo players trying to keep track of all their cards and marking them with their dabbers as the numbers are called.  I added a very minor ability for the computer to also occasionally "miss" marking the number being called when in this mode.  I added a report at the end of the game of how many games the player wins and how many the computer wins.  Finally, I added a game level element which simply adjusts the speed of the delay for the player to hit the row number (1-5) of the number on their card for the number being called.  If they mess up and hit a wrong number, they fail to mark the number on their card.  The level also effects the degree of possibility that the computer will miss marking a number on its card.  However, if the user selects "no" to the "prompt mode" at program start-up the game will play like the original program.

The source for my version of the program can be found here:

https://github.com/jggames/trs80mc10/tree/master/quicktype/Casino/Bingo

The game can be played on GameJolt. Choose "Play Game" then the "Classic 8-bit BASIC game" menu option.  Select "BINGO" from the cassette menu and then type RUN.

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

Friday 24 June 2022

Jim Menick's "Draw Poker"


I already posted about Jim Menick's BASIC text adventure game "Space Derelict."  That program was an example program from his book BASIC Adventure and Strategy Game Design (1984). Jason Scott mentions that there was a version of the book for the Apple, but I worked from a scan of an edition for the TRS-80 Model IV computer.  I have now cleaned up the scan of his example listing for the "strategy game" component of the book, which is a variation of Draw Poker. The "house rules" for that game are:

  • Each player starts with $100
  • $1 Ante
  • Minimum of (pair of) Jacks for opening
  • 3 raise limit
  • $5 bet limit
I don't know if these are standard rules, or idiosyncratic to this 5 person (including you) computer version of the game. The most interesting aspect of the game is that the other 4 A.I. players are apparently designed with unique playing strategies/styles.  They each have names:
  • Marvin
  • Gerry
  • Walter
  • Betsy
It's a very detailed variation of Poker in BASIC.  It seems to handle betting, passing, dealing around among the players, raising, dropping out, etc.  If you drop out, the other players continue to play without you.  I'm not sure if the players are good players, but they are certainly good enough to beat me and my meagre card skills, including the occasional bluff.  

The program was very large.  I had to engage in another of my monumental "shrinking exercises," which involve the following steps:
  1. Remove all spaces between commands and variables.
  2. Eliminate single command lines and pack multiple commands on lines as much as possible.
  3. Change as many multi-character variables as possible to single letter variables.
  4. Scan the code for redundant/duplicated code and then shift that to a subroutine.
  5. Shrink and streamline messaging, which had to be done anyway to shrink a 80 X 24 game screen down to a 32 X 16 screen of the TRS-80 MC-10.
  6. Omit <>0 references in IF statements.  The variable by itself, if a non zero, can simply trigger the if.
Before any of that could be done, I had to chase down all the typos and bugs from my transfer/typing of the game listing from a digital scan.  There were also some apparent errors in the listing, including a missing line at 28070 with a needed NEXT. This was for the winner determining subroutine. I think it just got dropped from being printed in the book.  There was also a reference to variable S5 at line 2642, which I think should be a reference to S5(X), since there is no other non-array S5 references in the code, and all the other references are to S5(X).  I switched it, hopefully it doesn't break something.

It is strange that there seems to be no preservation of the game on the Net.  Like Frank DaCosta's BASIC programming "How-to" book for the TRS-80, I think the listings were simply too long for many people to have had the fortitude to actually type-in and fully debug the game back in the day.  Perhaps, this coupled with the minor printing errors, simply drove people insane, and so beyond Menick himself (and De Costa), few might have ever obtained working copies of the game.  It would seem that neither author distributed/published working copies of their games by way of other media than in book form for typing-in.

I'll continue to bug test and see if other errors emerge.  I have yet to fully test the routines triggered when players lose all their money and drop out of the game and what happens when the human player runs out of doe.  That will simply take some time of test play.  Of course, if there is anyone out there who wants to contribute to game testing, the 5CARD can be played here (at least for the testing phase):


Just select the game from the cassette menu, and then type RUN.

Please let me know if you find any bugs or have any comments on the abilities of the 4 A.I. players.

I got a Full House!


Bug Addendum:

I have been intensively testing the game. In addition to a bunch of problems introduced by me in the process to get the game working and pared down to fit in an MC-10, I've found what I think are some existing bugs in the original program:
  1. There was an error in the routine that examines 2 pair hands to find the highest card.  Instead of looking at the cards in the hand and comparing which was higher, Menick compared the pointer array variable values to the positions of the first cards for each pair. Those values needed to be put into another array holding the values of the cards themselves to obtain their actual values as cards.  Pointers within, pointers within pointers!  He only went 2 levels deep when he needed 3-- easy to do in such a massive program with massive lines of these multiply embedded pointers.    This happens in my program around line 2901 which is a little subroutine I carved out so that it could also be used by the "Untranslated Player hand" routine latter in the program.  I also unpacked some of the "pointer within pointer" analysis to a subroutine to make the lines shorter, since those kinds of lookups happen a lot and have the same general format.
  2. The card replacement routine was really messed up.  If you didn't pick correctly and then simply hit N at the "Replace" prompts, it would realize that you hadn't selected enough cards to replace and take you back to start at the top of your card list again.  But it already had replaced the cards you selected and wouldn't turn them back to what they originally were. It also would not re-wind the cards drawn counter!  This meant that if you repeated hitting "N" and kept "restarting" your selection you could effectively eat through the entire remainder of the deck and blow the lid of the array holding those cards! That would cause a catastrophic "out of bounds" error.  So I revamped and stored your (up to) three selections, and then only change them after you have selected the cards you truly want.  So if you make errors, just hit N until it restarts the process as many times as you need.
  3. There are places where INPUT is used, such as for "Bet?" and ""How many Cards? selections.  But a numeric variable is used for input, which means if you happen to enter a letter, you get a new line and the message "Redo" and then a newline with a new prompt, which would cause the screen to scroll. Needless to say this really messed up the screen real-estate. So I switched the input to use a string variable and then assign it using VAL to the original numeric variable. So if you enter anything that is not a number it just assumes it's a zero.
  4. Minor issue with the game ending.  If you had exactly $1 left at the end it would let you ante up and enter the game with $0.  Then it would keep telling you you were trying to make an illegal bet in an endless loop.  I added logic to terminate the game if you had 0 after your ante.  I also made it so that if you get the pot up to over 480 it reports your "winnings" and thanks you for playing and ends the game. The other players are made to drop out if they have less than $5 each so if you have $500-16 there could be no players left for you to play with.  I don't know how the game would handle only you entering into the actual game play without other players. Menick doesn't seem to have considered this eventuality happening.  I guess he just thought his A.I. players were that good!  Anyway, the game now has a (hopefully) functioning win routine.
  5. This one is not really a bug, but it allowed me to push the memory needs down enough that I had enough space to put back in some of the more elaborate game messages. Menick used three string arrays for presenting the cards: One for holding the card's value, one for the suit and one for these two strings combined for the whole card.  E.g. 7  ,  H  and  7H.  This was done for each of the cards. These arrays were for 40 items each: 5 cards for each of the five players, and then up to 3 cards for each player's replacement cards.  Each time these were changed Menick had to update each of three string arrays: Value, Suit and Combined Value/Suit. The combined Value/Suit would used when a card needed to be printed on screen.  But since they were always changed together it seemed redundant to manage a separate "combined" string.  I just stripped it out and simply printed the Suit and Value strings together in the few places needed. The removal of an entire 40 item string array really freed up space, and broke the back of my memory woes. Menick didn't need to worry about such things since he was programming on a TRS-80 Model 4, which I believe had 128K (and at least 48K for BASIC), and not a measly 20K like the MC-10. Such luxury.
  6. At the beginning of the subroutine that checks for a straight flush in lines 2630-2647 a variable IN(X) is set to 0. Then a check is made after a search is made in the initial part of the routine for a straight to see if the value of IN(X)=1.  If it is then the subroutine is exited and the program moves on. If not, then the values for aces in the hands (14) are shifted to 1s and the whole routine is run again. I can only surmise that this is to check for a straight in the order A1234.  If straight is found for either the first search or second a branch is made to elsewhere. But if the second search occurs, no change is made to the value of IN(X) to indicate that the "second check" has occurred but no straight of the A1234 type found. So the routine just keeps being run in an endless loop. So I added IN(X)=1 after the first check for a straight is made, so that the branch out on S(X)=1 occurs after the second check.
  7. In testing the winning and losing subroutines of the game it became apparent that Menick must not have ever got to that point in his own play testing (or perhaps only on the Apple version).  I created the win and lose conditions by breaking out of the program during the Ante screen, and then changing the banks of each player stored in R(X) and then entering CONT. I was able to figure our that there was something wrong with the dropping out part of the program for "busted" players.  A variable P(X) had to be set to 1 after the "busted" message gets printed, but wasn't. That variable then triggers the awareness that the player is not able to Ante and is also used to prevent printing the player onscreen and skip them for dealing duties, etc.
  8. There was a problem with the routine that reexamines your hand after you make card replacements. Menick didn't re-initialize the variables storing your hand values before re-starting the hand analysis subroutine (starting at line 130). So if you had a hand with 2 pairs, and then selected new cards that left you with no recognized hand type (pair, 2 pairs, 3 of kind etc.) that routine wouldn't find anything to report about those recognized hands, so it wouldn't change the reporting variable, effectively leaving your hand with the type of hand identified from before making your replacements.  So if you started with a pair, and then replaced one of those cards in a way that left you with zilch, it would report that you still had a pair. It's possible that this might be a result of something that I changed, but I tried very early version of my edits of the game (I keep a succession) , and the problem was there, so I think it's original. Menick simply didn't test like I did by entering crazy entries again and again with the emulator cranked to the max speed.  It would be very rare (except for Betsy who seems to be a little rash) for players to smash up their own existing hands and then stay around (bluff) to the brutal end just to lose and see their hand described. They'd normally fold. So it's likely Menick wouldn't have noticed this bug. But by playing many games on high speed I noticed this first in my own hands (I was just replacing cards at random and sticking around to the end to make sure I could see all the hands to check them).  Then I noticed it happen in one of Betsy's hands too.
  9. I changed the annotation of how hands are reported. It now takes the form of "Full House 6's",  "Four T's" or "Three A's" etc. The subroutine at 32000 finds the value of the highest card for 4-of-a-kind and full house hands.  At line 3410 and 3440 I added a S$ before the GOSUB32000-- The S$ stores the apostrophe and S characters printed after the card number of the highest card in the hand. This annotation was missing from the determination of four-of-a-kind hands (except for one instance). The 32000 subroutine (now relocated to 85) would not work unless this annotation was present like it was for Full House hands.  I adjusted the 32000 routine to deal with the apostrophe and streamlined its operation. 
Challenge

What are the different "playing styles" of the 4 A.I. players?  I haven't examined those routines in depth or read Menick's book in detail. I might do. If so, I will come back here and add an addendum to my addendum and let you folks know. Otherwise, if you want to examine the code yourself, it can be found here:

Final updates can be seen here:



Wednesday 15 June 2022

"Star Command Sigma" by ASCII 1982

I had noticed several screen shots of a game called "Star Command Sigma" for the NEC PC6001. It looked like a BASIC game-- a rendition of the vast family tree of Star Trek games-- But since it was by ASCII, a major software company in Japan from the early days of home computing in the 80s, I expected that it would be especially well done. So when I finally got an emulator working for the NEC PC 6001 and located a huge repository of software, I went looking for it. I was able to list it to a file and get the source code. It was not hard to translate.

I have done other games from the NEC PC-6001 using James the Animal Tamer's Virtual NECTrek PC, which was a short lived North American variation of the PC-6001. The BASICs are similar Microsoft variations and the fact that they both use the Motorola MC6847 video chip makes things fairly straightforward.  The NEC uses LOCATE instead of PRINT@, but I just switch its two X and Y arguments to PRINT@X+32*Y, and get the same results. The NEC has some fancy graphics modes, such as the ability to define a virtual console/window on part of the screen, and some super sound generation. But I was able to translate most of this stuff in a downgraded way. One advantage of the MC-10 is that its screen printing and BASIC generally run faster. There is a speed sacrifice to be paid for all the NECs fancy abilities.

Here are some comparisons screenshots of the game working on the PC-6001 emulator and the Virtual MC-10.  They show some of the differences in how the two computer systems implement the MC6847:

NEC PC-6001
MC-10
The NEC allows all the possible character colour layouts provided by the VDG, whereas the MC-10 can only easily access black on green text. The NEC also has an extended character set with lowercase and special symbols, such the degree symbol (little raised circle), which is used in the game.

You'll notice that the Klingon's are called "KLIMZONs" in the NEC variation. However, ASCII provide a variable for storing the name, so you can easily change it to Klingons. I guess they had to worry about copyright infringement, but they wanted customers to be able to easily switch  to full copyright infringement mode if they desired. You'll notice though that they still use an "E" for your ship (I wonder what that stands for?).

ASCII also embedded some strange characters at the beginning of each of the main menu item titles as they were listed in the DATA statements. These weird characters are processed when the titles are read in and combined in a single variable that reads "by ASCII."  I guess they were a little worried about copyright infringement of their own. It's kind of like Bill Gates multiple Easter eggs hidden in Microsoft BASIC, such as in the original Commodore BASIC for the PET, that can print out "Microsoft." If any one tried to pirate the code, Bill could just hit a few keystrokes and reveal the Easter egg message and claim ownership!  I thought of switching it to "JimG2022" or some such, but in the end, it's their program.  If they come gunning for me they can happily sell my version to the massive legions of MC-10 users out there!

The music is a bit of a mess.  First of all I don't read music.  Second, the MC-10 only has a simple SOUND command, and not the fancy PLAY command of the NEC.  Still I have butchered the notes listed in those PLAY commands to get some meagre semblance of the original musical refrains for the intro, win and lose screens. I had to be somewhat creative in the implementation of sound effects, but sometimes the program also used the simpler SOUND command, and in other cases I tried to take clues from the notes listed in PLAY commands.

The scrolling "window" allowed for by the CONSOLE command of the NEC had to be dispensed with.  Instead I went with a system of the top of the bottom half of the screen being used for commands, the middle for messages and help info, and the bottom line for combat messages. No scrolling is allowed.  Instead, as messages roll in, a small left pointing arrow appears in the bottom right corner.  When it does, you can hit a key to skip directly to the next message/event. Otherwise a brief pause will occur to allow the player to read the message before it is replaced or erased.

The game is very feature rich. There are options that I have not seen implemented in any other variation of the classic Super Star Trek game. I wont go into complete detail here, but it is a very well-thought out set of command options that will make for a challenging set of tactical decisions as you try to destroy all the Klingons, Oh, I mean Klimzons. The enemies even occasionally shoot torpedoes back at you, which you can launch a counter measure against using the
QWE
  ASD
   ZXC
direction keys.  The NEC used the STICK command to read a direction from the joystick, but I switched it to this keypad arrangement. Hit one of these keys just after the enemy launches a torpedo (or when the left pointing "continue arrow" message is displayed) and you might get lucky in destroying the incoming torpedo. The enemies even move during combat (and other times) so you will find that occasionally they warp out of the way of danger or new ships can arrive to complicate your life.

Below is a playthrough. I lose. I didn't realize that a feature that allows you to get energy from a star is "paid for" by sucking time off of your countdown timer.  If I hadn't been so greedy (and ignorant of how all the features are interconnected) I might just have won!  See if you can spot the moment of my fateful decision...


While investigating the game I also discovered that ASCII went on to make a fancier graphic character version for the MSX line of computers:



So the MC-10 now has a neat little game recovered from the early 1980s to help it to keep pace with the "big boy" systems of the 8-bit era. I wonder of Mr. Godai (listed in the title screen above) is the same programmer who made the version for the NEC?  If so, thank you Mr. H. Godai for a wonderful game.


Addendum

I modified the title page to make the sigma look more like the original:


I also fixed up some of the more awkward "Engrish" phraseology, such as "Torpedo is breakdown."  I changed this to "torpedo damaged" and modified "Klingon" to plural "Klingons" (etc.) on the status screen.  I still don't know what "Offensive cycle" means and what the number attached to it represents.  It's probably something like "threat level" or possibly, the number of combats you have had with Klingons, or something like that. If anyone has suggestions, I'd appreciate hearing them. Perhaps I'll change it if I figure it out.

I added plurals and gender neutral terms to the status report


Addendum to the Addendum

Curtis Boyle mentioned the program on the Cocotalk web show and commented that it was good to see a nice version of Star Trek on the MC-10.  However, it is actually an addition to a number of other Trek variations that I have ported to the MC-10 as part of my efforts to collect up classic BASIC programs for preservation purposes.  It's not Curtis's fault that he wasn't aware of these wider efforts on my part, although I might have made him feel that way when I made a video to bring these other Trek programs to his attention. I didn't mean to offend (Sorry Curtis).  Just goes to show how much tone is lacking from the quick messaging that forms such a part of digital life today. Much thanks to Curtis for the great job he does presenting the details of the projects and activities of the community. In any case, here's the vid with a run down of some of the other Trek offerings on the MC-10:


I've also made a special "all Trek" themed game list for the online MC-10 emulator. One program not mentioned in my video is "Save Spock", which if I recall correctly I ported from some obscure Coco disk: http://faculty.cbu.ca/jgerrie/MC10/JG_Star_Trek.html


Addendum to the Addendum Addendum
Noticed some spelling mistakes in the "Encounter in the Near Tholian Sector" game while reviewing my video. Don't know if those are mine from the porting process or from the original, but in any case I've fixed them up.