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: