
What does it take to create a “real” video game on the Commodore PET?
What does it take to create a “real” video game on the Commodore PET? So far we have essentially a tech demo, we need to add remaining aspects before we can hand it off to someone to play test.
This is part 4 of the Commodore PET Programming and XC-BASIC3 series. For such a simple premise, we have actually covered a surprising amount of ground!
Part 1: We discussed the PET hardware and the programming options.
Part 2: Draw on the PET screen and get the basics moving.
Part 3: Make a playable shoot ’em up game, with movement, shooting, collisions, score, and win/lose states.
Now, in Part 4, we make our foundational code into a real game. For that we need to add enemy attacks, animated explosions, shrinking alien formations, and difficulty ramping.
Plan of Attack
Check out the latest code on my Online Retro IDE, where you can see and experience the enhancements:
- Aliens can now fire back
- The player ship can be destroyed
- A simple explosion animation
- Alien formations shrink as rows and columns are cleared
- Alien speed increases as their numbers drop
The game loop now uses separate timers for different actions
They Shoot Back Now – Adding Alien Missiles
This is the most obvious missing feature from the previous code, there was very little challenge if the Aliens were passively waiting to be shot. We need the invaders to … invade, and to go on the attack!
For this we need to add new variables to allow for alien shooting:
ALIEN_SHOOTING– Is a missile active?ALIEN_MXandALIEN_MY– the location of the missleALIEN_SHOOT_DELAY– tune the missile movementALIEN_SHOOT_TICK– a counter to use for missile timing
This pretty much mirrors the logic used for the player bullet but in the opposite direction.
Only one alien missile is active at a time, though there is almost always an active missile due to them resetting as soon as they hit something or the screen boundary. The missile starts from the bottom of the alien formation at a random location that is forced to align with an active alien on the bottom row (it looks wrong when the firing is located purely randomly).
This means we need to tune our random selection to possible columns of aliens, with the Y being set by the bottom row.
IF ALIEN_SHOOTING<>1 THEN
REM aliens at ALIEN_LEFT+0,2,4.. (every other column)
NUM_COLS=(ALIEN_RIGHT-ALIEN_LEFT)/2+1
IF NUM_COLS<1 THEN NUM_COLS=1
ALIEN_MX=ALIEN_LEFT+2*CINT(RND()*NUM_COLS)
IF ALIEN_MX>39 THEN ALIEN_MX=ALIEN_RIGHT
REM CHECK IF THERE'S AN ALIEN THERE SO CAN SHOOT (use ALIEN_BOTTOM - bottom row)
IF PEEK(SCREENADDRESS+(40*ALIEN_BOTTOM)+ALIEN_MX)<>32 THEN
ALIEN_SHOOTING=1
ALIEN_MY=ALIEN_BOTTOM+1
END IF
END IF
Better Randomisation
If we just select a random number then the computer will produce a predictable series of numbers. We need a random “seed” value if we want something approaching truly random generation.
A simple trick used in many vintage games is to use human nature as the source of the seed. Our PET counts from the moment it is powered up in “jiffies”. In the welcome screen we pull the clock value at the moment the player starts the actual gameplay, and this gives us a large and unpredictable number to use as our seed:
SEED=(PEEK(142)*256)+PEEK(143)
RANDOMIZE SEED
Player Hit Detection and Lives
Now that aliens can shoot, the player must be able to be hit, giving the game an element of risk.
This involves:
- Comparing missile coordinates with the player position
- Reducing the
LIVEScounter - Resetting the missile
- Updating the HUD with the new values
IF ALIEN_MX=X AND ALIEN_MY=Y THEN
LIVES=LIVES-1
IF LIVES<1 THEN GAME_OVER=1
ALIEN_SHOOTING=0
CALL PLAYER_EXPLOSION()
CALL HUD()
ELSE
RETURN
END IF
For added fun we also animate a little explosion by calling a PLAYER_EXPLOSION() subroutine. This is a simple animation created by drawing and erasing characters repeatedly using TEXTAT X,Y with a small delay between animation “frames”.
Alien Formations That Shrink
When aliens are killed we leave gaps in the formation. The challenge then is ensuring the formation only wraps when the remaining visible aliens hit the side of the play area rather than based on the original full formation boundaries.
This is one of the more tricky improvements as it involves math without bogging down the microprocessor and therefore slowing gameplay.
Our boundaries are recorded in the variables:
ALIEN_BOTTOMALIEN_LEFTALIEN_RIGHT
Recall the visible aliens are stored in data strings, so these must also be trimmed when columns at the extreme ends of the formations disappear.
This has to be a quick operation as it happens during player firing collision detection. I found the quickest way in my testing was to check the strings using PEEK plus a string offset (slightly faster than using LEFT$ or RIGHT$), and set a flag for if the column was empty (or not):
IF PEEK(@ALIEN_ROW(1)+STR_OFF)<>32 THEN COL_EMPTY=0
IF PEEK(@ALIEN_ROW(2)+STR_OFF)<>32 THEN COL_EMPTY=0
IF PEEK(@ALIEN_ROW(3)+STR_OFF)<>32 THEN COL_EMPTY=0
IF PEEK(@ALIEN_ROW(4)+STR_OFF)<>32 THEN COL_EMPTY=0
IF PEEK(@ALIEN_ROW(5)+STR_OFF)<>32 THEN COL_EMPTY=0
Increasing Difficulty
Classic Space Invaders speeds up as aliens are eliminated but up to now we were going at a set pace. This feels like the game is too easy and only gets easier as you destroy the formation.
There are a few ways to introduce ramping up difficulty but I decided to simply adjust ALIEN_DELAY using values based on feels and vibes. I’d love to know how you would do things differently.
The delay is reduced when alien count drops below certain thresholds:
- 40 aliens: slow movement
- 30 aliens: faster
- 20 aliens: faster again
- 10 aliens: very fast
This simple change is enough to dramatically increase tension near the end of each wave, especially if the alien formation is close to the bottom of the screen when it accelerates!
Separating Game Timers
Earlier versions moved everything inside the main loop but due to having different operations needing their own timing we now have:
- Alien movement timer
- Player bullet timer
- Alien shooting timer
All are based on a simple pattern:
TICK = TICK + 1
IF TICK > DELAY THEN
DO_THING()
RESET TICK
ENDIF
Putting It All Together
It’s not finished by any means, but now the game has:
- Aliens moving as a formation that adjusts boundaries to the remaining attackers
- Aliens fire missiles that can hit the bases or the player
- Increasing difficulty (which could be adjusted later to have easy, medium, and hard settings on game start)
- Player explosions and remaining lives
Although the graphics are simple PET characters, the underlying mechanics are now very close to the classic arcade formula, and offer a good foundation for the final finished game and porting to other machines.
In the next part we will add some finishing touches and optional extras …
Original article by retrogamecoders.com


