Copyright © 2023 by Víctor Parada


This is a little game for the 2023 NOMAM's BASIC 10-liners Contest. This program fits in the PUR-120 category, and it was written using FastBasic 4.6 for the 8-bits ATARI XL/XE computers line. Development started on 2022-01-28, and it took 2+6 days. The final version's date is 2023-02-25.

UPDATE: It obtained the 1st place of 9 entries in the category.


Proud of your white Beetle, participate in the Beetles Great Parade. How far can you go?


BEETLES start When the title scren appears, press the button to join the Beetles Great Parade.
BEETLES move You can move to the left and to the right using the joystick. Upwards you can accelerate and downwards you can reduce your speed. You earn a point for every car you pass.
BEETLES round You have to overtake 20 cars in less than 20 seconds. If you do it, the time is extended to overtake 20 more cars, and so on. Every time you get extra time, you also get bonus points (the square of the remaining time), but the path is narrowed a bit.
BEETLES crash When you crash against another beetle or when you get out of the way, your the hood of your beetle will open and you must close it to see again. Precious time will be lost as you have to join the Parade again.
BEETLES honk When you feel that a crash is inminent, press the button to honk. One of the other cars might change to the other side. If you are lucky, you could find a path to be safe. Using the honk too much might lead to a major crash. Use it carefully!
BEETLES gameover When there is no more time, your beetle will stop and the game is over. Honk to join the Parade again.

Development of the game

Big and chunky sprites have a some kind of mystique, and I've written some games with such kind of sprites. While reviewing for the Atari Homebrew Awards lots of games released in 2022, a small game with huge sprites surprized me. It made recall the old Speed Race arcade, and I thought that someting similar could be done in Atari BASIC for the tenliners contest in the PUR-80 category (up to 800 bytes), using a string manipulation trick I developed to manage P/M graphics. I tried a proof of concept, using P0 for the players car, and P1 to P3 as the enemy cars, I could make them scroll down showing at most three of them at any time. The result was too slow for an action game. Instead of discarding this prototype or trying it in Turbo Basic XL, I turned it into Fastbasic and tried it again. The result was nice enough to continue the development.

BEETLES prototype

Initial prototype in Atari BASIC.

BEETLES prototype

Second prototype using Fastbasic and wide P/M graphics.

Not being an Atari BASIC game, the max size restriction increased to 1200 bytes for the PUR-120 category. That is a lot of space for a simple mini game, so I thought on how many features could be added and which would the game rules be. In the features, I thought about a narrowing or zig-zagging path, cars that move with different horizontal speeds and, obviously vertical speed control relative to our own car, which it should be fixed to a given height in the screen. About the rules, I thought about a challenge game counting how many cars you could pass in a given amount of time, or how many cars could you pass until you crash.

BEETLES prototype

Adding car bitmaps and shoulders.

BEETLES prototype

First playable version with collision detection.

After I coded some of the game action, I realized a couple of issues: the road was too wide with many open space to go through and sometimes the enemy cars were randomly aligned to force you into a crash. The solution for the first issue was simple: to reduce the width of the highway and use the sides to show the score and timer in a column. For the second one, it was fun to add a horn: you can press the button to beep-beep and make them change the direction, but not every one, just one of the three, and that one was randomly selected, so you have to horn many times to move them all, but sometimes against yourself!

BEETLES prototype

Adding a left pannel, new bitmaps and crash animation.

BEETLES prototype

New scoring system is displayed.

With enough space available, I added extra animations and sound effects. The bitmap for the car turned into a VW Beetle after some iterations, making it bigger. The rules of the game changed to a stage based ones: you have to avoid a given number of cars in a given amount of times to get into the next stage in a continuous run. At the end of every stage, the paths is narrowed a couple of pixels, so at some time it will be impossible to continue without a crash. Every crash just makes you waste time trying to get the rush. I fine tuned the timer during my tests, so you have to speed up your run if you crashed to complete the stage. Three crashes in the same stage are enough to be disqualified.

BEETLES prototype

Simplifying the animation to save bytes.

During the last development iterations, the code was about 1200 bytes, but hard enough to make it fit 10 lines of at most 120 chars, and I had to decide which features to remove. The first feature to be removed was the title screen, turning it into a very simple text screen. I also replaced the original crash animation using zig-zagging cars with a simpler one that move them straight to the top. This gave me more control over the score and the speed of the game. I also changed the use of each P/M, making player's car be P3 and enemy cars P0 to P2, simplifying some formulas and memory management.

In this process I found that I was not using Fastbasic statements and functions for P/M management but standard POKE instructions for Atari BASIC or TurboBasic XL. I changed the syntax and I found that I had freed about half of a line of code, and that no speed up or slow down of the gameplay was notorious. That was enough space to restore the original intro screen and to improve the crash animation. Also, a small "tick" sound FX was added to signal when a car gets passed.

While writing this doc, I decided to change the crash, and turned it into a small "incident" in order to make the game flow: the hood of the car will open and prevent seeing ahead. That is a simple reason to make you stop and loose time.

BEETLES prototype

Final version with an open front hood.

Some weeks later, I was thinking that the game did not reward completing the stage quick and with the least amount or no crashes. So I take a look at the packaged listing to find some room for 6 bytes in the proper place to add the remaining time to the score. After making some room by changing the order of some statements, I could make room and add the statement. Verifying that the game still have 10 lines, I found that the modified line still had 2 extra bytes available, so I could add more bonus points by adding the remaining time twice or my multiplying it by 2 or 3, but at the end, I multiplied the remining time by itself, so you could get 1, 4, 9, 16 or might be 25 extra points at the end of each stage.

Download and try

Get the BEETLES.ATR file and set it as drive 1 in a real Atari (or emulator). Turn the computer on and the game should start after the loading completes. A joystick in port 1 is required.

NOTE: This game is for PAL computers. If it is played on NTSC computers, the text colors won't be the same, but the game should have the same difficulty.

The code

The abbreviated BASIC code is the following:

The full and expanded BASIC listing is:

(c) 2023 Víctor Parada
dim x(3) byte,y(3),d(3),c(3)
X(): Horizontal position of each car
Y(): Vertical position of each car
D(): Moving direction of each car
C(): Start delay for each car
data f() byte=0,202,180,160
Engine's sound depending on speed
g=adr("{binary data}")+1
Bitmaps of car and opened hood
graphics 18
Set screen to graphics mode 2 (ANTIC 7) without text window
pmgraphics 2
P/M graphics in double line resolution
poke 707,15
P3 player's car is white
mset $D008,4,1
Double width players
poke 623,16
GPRIOR=16: Missiles with 5th player color
mset pmadr(0),512,0
Clears P0-P3 P/M area
mset pmadr(-1),128,$F0
M2 & M3 delimits the street
Pointer to the array (buffer) of P/M's horizontal positions.
To avoid graphic glitches, all cars are moved at once after a VSYNC
Screen position of the timer
position 6,5
print #6,"{binary data}"
exec p 3
Displays title screen
  while strig(0)
Waits for trigger
Street side limits
  exec l
Displays street limits
General counter
Cars needed to pass
  print #6,"{binary data}",,
    "{binary data}",,,,"{binary data}",,n,,,
    ,"{binary data}",,"{binary data}"
Displays left panel
    for i=0 to 2
    next i
Initializes traffic
    exec p 3
Initializes car position
Delay to count cars that gone away (passed cars)
No honk
Syncs with VBLANK
    poke $D01E,0
Clears collisions
Decreases the round timer
Checks joystic position
Right or left?
Move 2 pixels to the selected side (if any)
Up or down? Selects current speed
      sound 0,f(v),12,3
Engine's sound depents on speed
Last state of the button
Current state of the button
      if h-m
Did the state of the button change?
        if h
Changed, and is it now released?
          sound 1
Yes... shut off the horn
No, it was pressed
          sound 1,75,14,8
Makes a beep
Selects a car
makes it move to the other side
Increases general counter
      for i=0 to 2
Computes the position for each of the enemy cars
Gets current horizontal position of a car
Checks if it has to change the direction because it is reaching a border
        if w
Assigns new direction if it reached to a border
Computes the new horizontal position of the car
        if c(i)>0
Checks for a delay for the selected car
delay is based on current speed
No delay
Gets current vertical position of the selected car
          if k<104
Still on screen?
Moves it down
Reached the end
            mset pmadr(i)+y(i),23,0
Removes the car from the screen
            setcolor i-4,rand(15)+1,
Selects the color for the next car
            inc e
Counter for incomming cars
Selects a direction for the car
Selects an horizontal starting position for the car
Selects a vertical position near the top, aligned by current speed
            if e>3
Are incomming cars reaching the bottom of screen?
              inc s
Yes, increase score
              dec n
Decreases the pending cars for the round
              sound 2,8,10,6
Makes a "tick" sound
              if n=0
Was the last car of the round?
Yes, add time bonus
Resets the timer and the cars count for the round
Resets the general counter
                inc a
                dec b
                exec l
Decreases the width of the road
              position 0,4
              print #6,n,
Updates the number of pending cars
              position 0,1
              print #6,color(32) s
Prints the new score
            exec p i
Displays the selected car in its new position at the top
          poke 77,0
Avoid ATRACT mode
        sound 2
Turns off the "tick" sound
      next i
Next car, please!
      poke u,$90+t
Updates the timer
Syncs with VBLANK to avoid glitches
      move r,$D000,4
      -move pmadr(0),pmadr(0)+v,384
Move cars (horizontally and vertically)
    until peek($D00F) or dpeek($D00A) or t=0
Exit loop if crashed or no more time
Turns off FX
Select a sound for the game over FX
    if t
If there is enough time, it was a crash
      move g+20,pmadr(3)+$53,9
Opens the car hood
Selects a crash sound FX
    for f=0 to 48
Move forward all the traffic
      sound 0,72+f,8+v,8-f/6
Plays the sound FX
      for i=1 to 3
        mset pmadr(i),3,0
      next i
Cleans the top of each enemy P/M area
Sync with VBLANK;
      move pmadr(0)+3,pmadr(0),384
Scrolls up the P0-P2 area
      if t
        -move pmadr(3),pmadr(3)+1,127
Scrolls down crashed P3 car
    next f
  until t=0
No more time?
  position 10,4
  print #6,"{binary data}",,
    "{binary data}"
Prints the "GAME OVER" message
proc p i
  pmhpos i,x(i)
  move g,pmadr(i)+y(i),20
Displays the given car
proc l
  pmhpos 6,a-4
  pmhpos 7,b+18
Adjusts street borders

Return to my 10-liners page.

© 2023 by Víctor Parada - 2023-02-04 (updated: 2023-04-03)