Skip to content

Instantly share code, notes, and snippets.

@primaryobjects
Last active December 6, 2025 23:23
Show Gist options
  • Select an option

  • Save primaryobjects/6dfa9e98c0f59eec3773e11f545e1538 to your computer and use it in GitHub Desktop.

Select an option

Save primaryobjects/6dfa9e98c0f59eec3773e11f545e1538 to your computer and use it in GitHub Desktop.
A Batari Basic (Atari 2600) game similar to Berzerk.

Batari Basic (Atari 2600) Game

Run the game using VS Code with the Atari Dev Studio extension. Once compiled to a ROM, run using the Stella emulator.

Animation

set tv ntsc
set romsize 8k
rem set kernel_options pfcolors
rem https://alienbill.com/2600/atari-background-builder/
rem **************************************************************************
rem BERZERK-STYLE GAME
rem **************************************************************************
rem **************************************************************************
rem Variable declarations - use letters m-z to avoid conflicts
rem **************************************************************************
score = 00000
scorecolor = $0E
dim m0_active = m
dim m1_active = n
dim e_dir = o
dim e_timer = p
dim cur_level = q
dim plr_lives = r
dim gstate = s
dim shoot_wait = t
dim death_wait = u
dim e_shoot_wait = v
dim temp = w
dim sound0_timer = x
dim sound1_timer = y
dim flash_counter = z
dim sc1 = l
rem **************************************************************************
rem Initialization
rem **************************************************************************
gstate = 0
cur_level = 1
plr_lives = 3
player0x = 40
player0y = 50
player1x = 100
player1y = 40
missile0x = 0
missile0y = 0
missile1x = 0
missile1y = 0
missile0height = 2
missile1height = 2
COLUP0 = $42
COLUP1 = $36
COLUPF = $8E
COLUBK = $00
m0_active = 0
m1_active = 0
e_dir = 1
e_timer = 0
shoot_wait = 0
death_wait = 0
e_shoot_wait = 30
sound0_timer = 0
sound1_timer = 0
flash_counter = 0
sc1 = 0
NUSIZ0 = $00
NUSIZ1 = $00
rem **************************************************************************
rem Main Loop
rem **************************************************************************
main
temp = gstate
if temp = 0 then goto do_title
if temp = 1 then goto do_play
if temp = 2 then goto do_levelup
if temp = 3 then goto do_dead
if temp = 4 then goto do_gameover
goto main
rem **************************************************************************
rem Title Screen
rem **************************************************************************
do_title
COLUBK = $00
scorecolor = $1E
playfield:
................................
..XXXX..XXXXX.XXXX..X...X.X...X.
..X...X.X.....X...X.X...X.X...X.
..XXXX..XXX...XXXX..X...X.X.X.X.
..X...X.X.....X.X...X...X.X.X.X.
..XXXX..XXXXX.X..X..XXXXX.X...X.
................................
................................
........PRESS.FIRE..............
................................
................................
end
player0:
%00000000
end
player1:
%00000000
end
if joy0fire then gstate = 1 : cur_level = 1 : plr_lives = 3 : score = 0 : player0x = 40 : player0y = 50 : player1x = 100 : player1y = 40 : m0_active = 0 : m1_active = 0 : AUDV0 = 0 : AUDV1 = 0
drawscreen
goto main
rem **************************************************************************
rem Level Up
rem **************************************************************************
do_levelup
death_wait = death_wait + 1
flash_counter = flash_counter + 1
rem Rainbow flash effect
temp = flash_counter / 2
temp = temp & 15
COLUBK = temp * 16 + temp
rem Level up sound effect
if death_wait < 30 then AUDV0 = 8 : AUDC0 = 4 : AUDF0 = death_wait
if death_wait = 30 then AUDV0 = 0
playfield:
................................
.............X..................
............XXXX................
..........XXXXXXXX..............
.........XX..XX..XX.............
.............XX.................
.............XX.................
.............XX.................
.............XX.................
................................
................................
end
player0:
%00000000
end
player1:
%00000000
end
temp = death_wait
if temp > 60 then player0x = 40
if temp > 60 then player0y = 50
if temp > 60 then player1x = 100
if temp > 60 then player1y = 40
if temp > 60 then m0_active = 0
if temp > 60 then m1_active = 0
if temp > 60 then AUDV0 = 0
if temp > 60 then AUDV1 = 0
if temp > 60 then flash_counter = 0
if temp > 60 then death_wait = 0
if temp > 60 then gstate = 1
drawscreen
goto main
rem **************************************************************************
rem Player Died
rem **************************************************************************
do_dead
COLUBK = $40
death_wait = death_wait + 1
playfield:
................................
........X.X....X.X..............
.........X......X...............
........X.X....X.X..............
................................
...........XXXXX................
.........X......X...............
........X........X..............
................................
................................
................................
end
player0:
%00000000
end
player1:
%00000000
end
temp = death_wait
if temp > 20 then plr_lives = plr_lives - 1 : death_wait = 0 : temp = plr_lives
if temp = 0 then gstate = 4 : AUDV0 = 0 : AUDV1 = 0
if temp > 0 then temp = death_wait : if temp = 0 then gstate = 1 : player0x = 40 : player0y = 50 : player1x = 100 : player1y = 40 : m0_active = 0 : m1_active = 0 : AUDV0 = 0 : AUDV1 = 0
drawscreen
goto main
rem **************************************************************************
rem Game Over
rem **************************************************************************
do_gameover
COLUBK = $00
scorecolor = $36
playfield:
................................
................................
..XXX...XXX..X...X.XXX.........X
.X.....X...X.XX.XX.X..........X.
.X..XX.XXXXX.X.X.X.XX.........X.
.X...X.X...X.X...X.X..........X.
..XXX..X...X.X...X.XXX.XXXXX.X..
................................
........PRESS.FIRE..............
................................
................................
end
player0:
%00000000
end
player1:
%00000000
end
if joy0fire then gstate = 0
drawscreen
goto main
rem **************************************************************************
rem Gameplay
rem **************************************************************************
do_play
rem Set level
temp = cur_level
if temp = 1 then gosub lvl1
if temp = 2 then gosub lvl2
if temp = 3 then gosub lvl3
if temp > 3 then gosub lvl4
rem Sprites
rem Handle sound timers
if sound0_timer > 0 then sound0_timer = sound0_timer - 1
if sound0_timer = 0 then AUDV0 = 0
if sound1_timer > 0 then sound1_timer = sound1_timer - 1
if sound1_timer = 0 then AUDV1 = 0
player0:
%01111110
%01111110
%00111100
%11111111
%00111100
%00111100
%01100110
%11000011
end
player1:
%00111100
%01111110
%11111111
%01111110
%00111100
%01011010
%10011001
%10000001
end
rem Movement
temp = player0x
if joy0right then temp = temp + 1
if temp < 150 then player0x = temp
temp = player0x
if joy0left then temp = temp - 1
if temp > 10 then player0x = temp
temp = player0y
if joy0up then temp = temp - 1
if temp > 10 then player0y = temp
temp = player0y
if joy0down then temp = temp + 1
if temp < 80 then player0y = temp
rem Wall collision
if collision(player0, playfield) then player0x = player0x - 1 : player0y = player0y + 1 : AUDV0 = 0 : AUDV1 = 0
rem Shoot delay
temp = shoot_wait
if temp > 0 then shoot_wait = temp - 1
rem Player shoot
temp = m0_active
if temp = 0 then temp = shoot_wait
if temp = 0 && joy0fire then m0_active = 1 : missile0x = player0x + 3 : missile0y = player0y : shoot_wait = 10 : AUDV0 = 4 : AUDC0 = 8 : AUDF0 = 10 : sound0_timer = 3
rem Move missile
if m0_active = 1 then missile0y = missile0y - 2
temp = missile0y
if temp < 5 then m0_active = 0
if collision(missile0, playfield) then m0_active = 0
rem Hit enemy
if collision(missile0, player1) then m0_active = 0 : score = score + 10 : sc1 = sc1 + 1 : player1x = 100 : player1y = 40 : AUDV0 = 8 : AUDC0 = 6 : AUDF0 = 5 : sound0_timer = 5
rem Enemy AI
e_timer = e_timer + 1
temp = e_timer
if temp > 30 then e_timer = 0 : e_dir = e_dir + 1
temp = e_dir
if temp > 4 then e_dir = 1
temp = e_dir
if temp = 1 then temp = player1x : temp = temp + 1 : if temp < 145 then player1x = temp
temp = e_dir
if temp = 2 then temp = player1x : temp = temp - 1 : if temp > 10 then player1x = temp
temp = e_dir
if temp = 3 then temp = player1y : temp = temp - 1 : if temp > 10 then player1y = temp
temp = e_dir
if temp = 4 then temp = player1y : temp = temp + 1 : if temp < 80 then player1y = temp
rem Enemy wall
if collision(player1, playfield) then e_timer = 0
rem Enemy shoot delay
temp = e_shoot_wait
if temp > 0 then e_shoot_wait = temp - 1
rem Enemy shoot
temp = m1_active
if temp = 0 then temp = e_shoot_wait
if temp = 0 then m1_active = 1 : missile1x = player1x + 3 : missile1y = player1y : e_shoot_wait = 60 : AUDV1 = 3 : AUDC1 = 7 : AUDF1 = 15 : sound1_timer = 3
rem Move enemy missile
if m1_active = 1 then missile1y = missile1y + 1
temp = missile1y
if temp > 85 then m1_active = 0
if collision(missile1, playfield) then m1_active = 0
rem Hit player
if collision(missile1, player0) then m1_active = 0 : gstate = 3 : death_wait = 0 : AUDV0 = 8 : AUDC0 = 8 : AUDF0 = 10 : sound0_timer = 5
rem Player-enemy collision
if collision(player0, player1) then gstate = 3 : death_wait = 0 : AUDV0 = 8 : AUDC0 = 8 : AUDF0 = 10 : sound0_timer = 5
rem Level up
temp = cur_level
if temp = 1 && sc1 = 10 then cur_level = 2 : gstate = 2 : death_wait = 0
temp = cur_level
if temp = 2 && sc1 = 20 then cur_level = 3 : gstate = 2 : death_wait = 0
temp = cur_level
if temp = 3 && sc1 = 30 then cur_level = 4 : gstate = 2 : death_wait = 0
temp = cur_level
if temp = 4 && sc1 = 40 then cur_level = 5 : gstate = 2 : death_wait = 0
temp = cur_level
if temp = 5 && sc1 = 50 then cur_level = 6 : gstate = 2 : death_wait = 0
rem Hide missiles
if m0_active = 0 then missile0x = 0 : missile0y = 0
if m1_active = 0 then missile1x = 0 : missile1y = 0
drawscreen
goto main
rem **************************************************************************
rem Levels
rem **************************************************************************
lvl1
COLUBK = $00
COLUPF = $8E
playfield:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X..............................X
X..............................X
X..............................X
X..........XXXXXX..............X
X..............................X
X..............................X
X..............................X
X..............................X
X..............................X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end
return
lvl2
COLUBK = $02
COLUPF = $4E
playfield:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X......X...................X...X
X..............................X
X......X...................X...X
X..............................X
X......X....XXXXXX.........X...X
X..............................X
X......X...................X...X
X..............................X
X......X...................X...X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end
return
lvl3
COLUBK = $04
COLUPF = $2E
playfield:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X..X...........................X
X..X...........................X
X..XXXXXXX.....................X
X..............................X
X...........XXXXXXX............X
X..............................X
X..................XXXXXXX..X..X
X...........................X..X
X...........................X..X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end
return
lvl4
COLUBK = $06
COLUPF = $CE
playfield:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X..X.....X.....X.....X.....X...X
X..............................X
X..X.....X.....X.....X.....X...X
X..............................X
X..X.....X..XXXXXX...X.....X...X
X..............................X
X..X.....X.....X.....X.....X...X
X..............................X
X..X.....X.....X.....X.....X...X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment