Wednesday, 30 April 2025

How Repetition 64 was formed

 28th April 2025

During the winter of 2025, I had some time spare in the evenings to participate in the "Simon Basic" game jam run by Phaze101 and Retro Programmers Inside. The idea of the game was to create and develop a game suited for a retro computer or console which resembles the old classic type-in game "Simon Says". We know there were popular toys in the 1980s and 1990s called "Simon Says" or "Einstein". Let me explain more about the theory of the game.

"Simon Says" is a simple game, where you watch a sequence of lights (and listen to the sounds) played by the computer. After listening to the sound, your task is to repeat the sequence of the lights/sounds in the correct order. If you successfully completed the sequence you move on to the next round, where an extra light/sound is played. The game keeps playing on until you select a wrong note/light.

Well, being that I did not make anything for a very long time for the game Jam, due to either 1. the production idea was too difficult, 2. I didn't have enough time available and was very busy on another project. I decided to create my own entry for the game jam. There was a rule though. "The game must use any form of BASIC". I was allowed to use machine code, as long as I keep it minimal. The game that came to light was "Repetition 64".

A rough start

When I started working on "Repetition 64". The first thing I wanted to do was work on the basics of the game. I needed to have some sprites to prepare the buttons. I booted up CBMPRGStudio V4.5.0 to create sprites for the game project using the sprite editor. It was simply a square. Then afterwards, I exported the square sprite as pBASIC data. (pBASIC is an BASIC interpreter that uses labels rather than numbers, then after compiling, generates the listing using numbers. I hated working with line numbers, because I easily got myself lost. pBASIC on the other hand made life much easier).  Since a whole sprite consists of 64 sprites ($00-$3f) I needed to work out where to POKE the sprite data. So I POKE the data to $2000-$203f. (8192-8255). This was only for the first part of the project.




A touch of randomness

The next thing I had to do was think "how am I able to make the computer be able to play the notes at random?". This idea was fun, but I got round to a simple solution. It was to generate a for/next loop which generated a random set of numbers between 1 and 4 (using dice simulation RND functions) and then POKE the random number table TO $c000-$c0ff (49152 to 49407) inside the loop as 256 bytes in memory. 

Getting the computer to play the notes

The first thing I did was used CBMPRGStudio's built in SID editor to prepare the chords for each of the notes for the game. After I was happy with those, I exported them as GOSUB labels ready for the game to be able to play them. Of course I also had to create a loop that completely initialised the sounds.

The easy part was preparing the random numbers into memory (49152), the hardest part was getting the computer to play the random sequences. Apparently not, it wasn't that hard to be honest. All I had to do was create another for/next loop and PEEK each number from the random number sequence table. Then afterwards I checked if a marked variable matches the number of the random number, and then jump to a subroutine in the listing to play the correct colour and note. 

Getting the player to play the notes

A similar trick to computer playing the notes was made to get the player to play the notes and light up the correct squares. However, there was one trick I had to do to solve this trick and that was of course check if a wrong note was being played. If the variable stored from the player was played incorrectly then the program jumps to a subroutine that process a fail sound and then deducts one life from the player. Then loop to the computer playing the same sequence again. If the player got the sequence correct, then the level variable increments by one, and adds one extra sequence to the sequence play/read loop. The program can play a maximum of 255 sequences, but I highly doubt the player can do that.

Scoring and bonus

I made this game allow add 150 to the score variable for a correct note played, and if a whole sequence was completed, I added 1,000 points to the score variable. Also after eight levels were completed, I added an extra life to the lives variable.

Adding skill levels.

Having one skill level during game play was pretty much boring. I already had one slow speed set for an easy game. So, I created a variable set as a skill level, which was set if F1, F3, F5 or F7 was pressed. F1 set up the easy skill level, F3 set up normal, F5 set up hard and F7 set up the totally difficult setting. The skill levels were based on the speed of the playing time for each of the notes. After play testing through these in the main BASIC program, I was very pleased with what I did, I decided to work on presentation.

Presentation and music

I wanted to make Repetition 64 more presentable. This was so that the game focused more on the quality design, than being just a standard basic game with a plain black screen and 4 sprites with four colours. While designing the graphics, the custom made character sets and screens were designed first using Charpad V2.7.6 free edition. Then afterwards I started a new character set project in CBMPRGStudio and imported the graphics font and other data into memory. The reason being was because Charpad only allows limited attributes. I wanted to use both colour and screen RAM based on custom colour data, rather than character sets. After importing the character set and re-colouring the character screen for both the title screen and game screen. I exported both screen data and colour RAM as PETSCII graphics and exported the character set as BASIC into the project. After generating the whole BASIC program, I came across a snag, where the screen and colour data did not display in the correct row, and also the sprite data overlapped the BASIC listing also. 



I needed to solve this problem, quick and fast before running out of time. The solution was to keep the BASIC listing, but instead of using DATA statements and PETSCII screen layout listings, I decided to rely on creating some limited machine code. This had to be done for the sprites and the screen display. Also I wanted to add an interrupt to the title screen so that it can scroll text across the screen and also play some music I made in Goat Tracker Ultra V1.5.5. So I created some small routines to create an IRQ raster interrupt with scroll text and play music. To finish off, I tested the IRQs, screen display routines, etc (outside the BASIC listing) and used a M/C monitor on the Action Replay to convert the hexadecimal addresses to decimal SYS addresses. Then afterwards, I put the SYS addresses into the BASIC listing.




Making the Music

I had an old tune which was already released on the title screen. Since there was still a little bit of time, I decided to make some music exclusively for this game. This was made using Goat Tracker Ultra V1.5.5. The music had some 80s space disco sort of feeling, also featured echo lead sounds to definitely give out a space kind of effect. I feel that this could be one of my best tunes by far this year - but could I beat that in my next game C64 project later on this year? We will have to wait and see.

Putting the game together

So, then you may wonder how did this game get put together? Well, the rule for the competition was that the game MUST have a BASIC dialect and should also be runnable from BASIC. I followed that rule. However, putting the game together required two different builds. The first part was compiling the pBASIC listing into C64 BASIC (using CBMPRGStudio). Then afterwards, add an import binary command of the actual BASIC listing along with the machine code program, charset, sprites, the two screens and music (with a safety offset of two). This resulted to 116 blocks file size.

The finished release

I did two versions of the game. The first was the game jam version (The 116 blocks release), where everything remained uncrunched and was runnable from BASIC. The other version (featured on TND's itch.io page) features exactly the same game, but instead, the game was crunched the good old Public Domain tool, Time Cruncher V5.0 from 1988. I used the BASIC run (JMP $A659) command and $37 as $01 to set the BASIC listing to run the program after decrunching from memory. Finally I put the TND presentation linker on to the game, crunched again with Exomizer and everything was running nicely. The reason for why Exomizer's Exo BASIC wasn't used was because it wasn't compatible with the tape loader I used for the TAP version and crunched with TC V5, worked fine for me.




So how did the project turn out.

Development of Repetition 64 lasted a while, during the cold awful winter and the project went really well. If there were improvements made to this game, I probably would have added scrolling character graphics, like I did with a few of my games, add a custom option where you could play in cross mode as well as square. I probably would have moved the sprites around to increase more craziness for the player who plays it, but that could be "Rotor Repeat" later on this year, in order to mark the 25th anniversary since my first ever C64 release in September 1995. However, I was developing towards a deadline, and decided to keep it pure and simple, but presentable at the end.

Where to get the game

The game was created specially for Retro Programmers Inside and Phaze101, but I have not supplied the whole project code publicly yet, in respect to the game jam rules. However, after the game jam has finished broadcasting, I have now uploaded the entire project onto my github page publiclyso that you can load it into CBMPRGStudio. You can find the code here:


https://github.com/RichardTND/Repetition64

You can download the Repetition 64 from my itch.io page which is via this link below:


https://richard-tnd.itch.io/repetition64


 






How Repetition 64 was formed

  28th April 2025 During the winter of 2025, I had some time spare in the evenings to participate in the "Simon Basic" game jam ru...