C64 Lunar Lander from LoadStar #1

Lunar Lander Commodore 64 disks

Commodore 64 Lunar Lander

Note: This page contains affiliate links and the author can obtain a commission with a purchase.

Back in the days when computers were still hooked up to black and white television via a switch box adapter that attached opposite end to an RF connectors, kids set to work on creating demos, utilities, and games. Due to the popularity of a computer called the Commodore 64, many users set out to create their own masterpieces, which eventually found their way into a publicized disk subscription service. One of my favorites, was called Softdisk Publishing. It was originally created for the Apple computers, but soon others followed. In that era programs had to be saved to a disk and no surprise to this day floppy disks can still be purchased online

When a person first purchased a personal computer in the early 80’s, they were often lured by a small variety of games that began filling the store arcades, as advertised through television commercials. One computer that really fascinated me was called the Commodore 64. I was intrigued when I first saw the amazing colorful graphics, amazing sound, and demos that were often broadcast in electronic stores of that age.

This article will focus on the style of game design by reviewing one of the earlier publications released by Softdisk Publishing at around 1983. The program was called Commodore 64 Lunar Lander and it was written in a programming language called Basic. I will review it here.

Lunar Lander Commodore 64 Review

The primary goal of the game is to navigate among mines (diamond shapes) without crashing into them as the rocket ship begins to descend from the top center of the screen toward the bottom. Since it is written in Basic, it suffers terribly from delayed timers. The game seems to utilize a lot of loops that progressively limit the gameplay. Often you are just waiting for the screen to redraw the mines before you can even move the ship.

When you first enter the screen using the Commodore 64 Lunar Lander program, the ship must be moved slowly to the bottom of the screen. Gravity is attached to the sprite and begins to push it down. As you are navigating the controls, be sure not to slam into any of the mines (#) signs. Well such was the day of PET Ascii, when graphics were not the most important element of a game. However, to be honest this version needs a lot of work, but I can only imagine that someone was in a hurry to get it published into a disk subscription and wrote it in a day or two. Yet this was the nostalgia of this generation and still had many users glued to their television screens to wait on each new issue published monthly by Softdisk.

If I had to sit down and write my own revision today, I would surely append machine language subroutines to handle the speed of both the ship and the mines, setting them on timers. That was very common for many famous game titles back in the day. Still sitting down at my Commodore 64 today put a smile on my face as I began to explore through the earliest programs I had come to love during that era. Good stuff!

C64 Lunar Lander game

You can view the program completely here in PDF form and it is explained further down the page.

[wonderplugin_pdf src=”https://www.c64brain.com/wp-content/uploads/2021/05/C64-Lunar-Lander1.pdf” width=”100%” height=”600px” style=”border:0;”]

Finally let’s get an overview of the program’s structure and layout.

Lines 3-14 set up some variables as listed here:

3 EX=0
11 BZ=10
12 POKE 53280,0 – set border color to black
14 RW=1531:RZ=1764:RE=1:TE=1:RM=1397:TM=1

Lines 100-151 setup DATA statements

100 DATA0,24,0,0,24,0,0,60,0,0,126,0,0,90,0,0,90,0,0,219,0,0,195,0
110 DATA0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,1,255,128,3,255,192
120 DATA3,255,192,15,255,240,40,255,120,56,255,28,49,255,140
130 DATA 0
140 DATA0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
150 DATA0,195.0,0,219,0,0,90,0,0,90,0,0,126,0,0,60,0,0,24,0,0,24,0,0,24,0,0,24,0

Line 160 – clears the screen
Lines 170-257 – Setup the game playing description where you can learn how to play the game.

170 PRINT “R(yellow)14 spacesEMOON LANDER(yellow)”
180 PRINT
190 PRINT”USE JOYSTICK IN PORT 2″
191 PRINT
210 PRINT”LEFT THRUSTS LEFT,UP THRUSTS UP”
211 PRINT
212 PRINT”RIGHT THRUSTS RIGHT,DOWN THRUSTS DOWN”
220 PRINT
230 PRINT”WATCH OUT FOR THE MINES”
240 PRINT
250 PRINT”LAND GENTLY OR YOU’LL BOUNCE”
251 PRINT
255 PRINT”YOU GET 10 TRIES,HIGHEST POSSIBLE SCORE”
256 PRINT”IS 10,LOWEST IS -10″
257 PRINT

Line 270 – enter sprite in memory between 832-958

270 FORJ=0TO126:READX:POKE832+J,X:NEXTJ

Lines 280-290 – initialize VIC registers for the sprite

280 XO=53248:YO=53249:CO=53279
290 X1=53250:Y1=53251:E=53269
300 POKE2040,13:POKE2041,14
308 POKE53281,6
309 POKE53287,1
310 POKE53275,2
319 POKE53288,2

Lines 320-324 – setup the rest of game description screen. Wait for keyboard input (at lines 323-329)

320 PRINT”YOU HAVE A LIMITED AMOUNT OF FUEL”
321 PRINT”THE HIGHER THE LEVEL THE LESS FUEL”:GOSUB6000
322 PRINT: PRINT””SEELCT SKILL LEVEL (1-5)”
323 GET E$:IF E$=”” THEN 323
324 IF E$=”2″THEN I$=”000045″
325 IF E$=”3″THEN I$-“000030″
326 IF E$=”4″THEN I$=”000020″
327 IF E$=”5″THEN I$=”000015″
328 IF E$=”1″THEN I$=”000060″
329 IF E$>”5” OR E$<“1″THEN323
330 PRINT:PRINT”R(cyan)PRESS FIRE BUTTON TO START(reverse off)”
331 PRINT

Lines 342-402: setup joystick and the screen

342 JO=PEEK(56320):IFJOAND16THEN342

350 POKEE,0
370 V=75:H=120:VO=0:HO=0
380 POKE54296,15:POKE54278,240
400 PRINTCHR$(147)
401 G=31:FORK=1TO9:X=1024+G:C=55296+G:L=0:FORD=1TO25:POKEX+L,160:POKEC+L,0
402 L=L+40:NEXTD:G=G+1:NEXTK

Begin the main loop:

403 PRINT”SQR(yellow)(10 spaces)ELUNAR LANDER(yellow)”
410 FORJ=1TO6: PRINT: NEXTJ
420 FORJ=1TO6: FOR K=1TO30
430 C$=” “:IFRND(1)<.1AND(K<20ORK>25)THENC$=”(yellow)(shift A)”
431 PRINTC$;:NEXTK:PRINT:NEXTJ
435 PRINT:FORJ=1TO4:FORK=1TO30
436 C$=” “:IFRND(1)<.1AND(K<14ORK>18)THENC$=”(control V)*”
440 PRINTC$;:NEXTK:PRINT:NEXTJ
448 FORQ=1984TO1984+30:POKEQ,160:POKEQ+54272,0:NEXTQ
450 FORJ=1TO31:PRINT”(white)R=(reverse off)” ;:NEXTJ:PRINT”R ESCORE”;
451 PRINT”(down)(4 left)”;S;”(right)”;
458 Q=V+50
460 POKEXO,H:POKEYO,V:POKEX1,H:POKEY1,V
465 TI$=”000000″
470 K=PEEK(203):GETK$
471 IFTI$>I$THEN749
500 V1=.1:H1=0
501 EO=1:JO=PEEK(56320):IFNOTJOAND1THENV1=-5:EO=3
520 IFNOTJOAND4THENH1=-.2
530 IFNOTJOAND8THENH1=.2
531 IFNOTJOAND2THENV1=.5:EO=3
532 GOSUB3000
540 GOTO560
550 IFK=64THENV1=.1:H1=0:EO=1
560 IFPEEK(E)=EOGOTO600
580 POKEE,EO:IFEO=1THENPOKE54276,0:GOTO600
590 POKE54273,8:POKE54276,129
600 IFH1=H9GOTO630
610 H9=H1:K=SGN(ABS(H9))*129:POKE54273,99:POKE54276,K
630 VO=VO+V1:HO=HO+H1
650 IFV<50THENVO=ABS(VO)
660 IFH<20THENHO=ABS(HO)
670 IFH>240THENHO=-ABS(HO)
680 V=V+VO:H=H+HO
700 POKEXO,H:POKEYO,V:POKEX1,H:POKEY1,V+10
710 C=PEEK(CO):IF(CAND1)=0GOTO470
720 IFV>210GOTO780
730 IFV+VO<100GOTO470
748 GOTO750
749 PRINTCHR$(19);”OUT OF FUEL!”:GOTO751
750 PRINTCHR$(19);”CRASHED”
751 S=S-1:QW=54272:FORR=QWTOQW+24:POKER,0:NEXT:POKEQW+24,47:POKEQW+5,64+7
752 POKEQW+6,240:POKEQW+4,129:POKEQW+1,36:POKEQW,85
753 FORX=1TO30:POKE53287,2:POKE53287,7:POKE53287,8:POKEE,0:POKEE,1:NEXTPOKEE,0
754 FORZ=15TO0STEP-1:POKEQW+24,INT(Z):NEXT:POKE53287,1:TI$=”000000″
755 FORX=1TO5:POKE53280,2:POKE53281,1:FORZ=1TO10:NEXTZ
756 POKE53280,0:POKE53281,6:FORZ=1TO10:NEXTZ:NEXTX
759 BZ=BZ-1
760 GOTO820
780 IFVO>1ORVO<0THENVO=-ABS(VO):GOTO470
790 PRINTCHR$(19);”LANDED!”
791 GOSUB7000:S=S+1:BZ=BZ-1:TI$=”000000
800 POKEYO,219
820 POKE54276,0:POKE54296,0
830 IFBZ<1THENGOTO1000
831 V=75:H=120:VO=0:HO=0:POKEE,0
832 POKE54296,15:POKE54278,240
833 FORX=1024TO1034:POKEX,32:NEXTX
834 FORX=1104TO1120:POKEX,32:NEXTX
835 GOTO403
1000 PRINT”GAME OVER”
1001 PRINT”REWANT TO PLAY A GAME?(reverse off)E”:PRINT
1002 BZ=10:S=0
1003 POKE198,0:WAIT198,1:GETZZ$
1004 IFZZ$=”Y”THEN330
1005 GOTO8000:REM **** END ****
2000 VV=54272:POKEVV+6,0:POKEVV+5,31:POKEVV+1,180:POKEVV+4,33
2001 FORNN=1TO100:NEXTNN
2002 POKEVV+4,0:GOTO1999
3000 POKERW,90:POKERW+54272,1:POKERW-RE,32:RW=RW+RE:IFRW>1504+28THENRE=-1
3001 IFRW<1506THENRE=1
3002 POKERZ,86:POKERZ+54272,7:POKERZ-TE,32:RZ=RZ+TE:IFRZ>1774+28THENTE=-1
3003 IFRZ<1744+2THENTE=1
3004 POKERM,35:POKERM+54272,2:POKERM-TM,32:RM=RM+TM:IFRM>1384+28THENTM=-1
3005 IFRM<1384+2THENTM=1
3008 RETURN

Sound:

6000 POKE54296,15:POKE54295,0
6010 VV=54272:POKEVV+1,40
6040 POKEVV+6,240:POKEVV+5,0:POKEVV+4,0
6050 POKEVV+4,17
6060 FORMM=150TO0STEP-1
6070 FORNN=NMTO50-MM
6080 POKEVV+1,NN
6090 NEXTNN:NEXTMM
6100 POKEVV+1,3
6150 POKEVV+6,0:POKEVV+5,5:FORNN=3TO100STEP5
6160 POKEVV+1,NN:POKEVV+4,33
6170 FORMM=1TO40-0.25*NN:NEXTMM
6180 POKEVV+4,0:FORMM=1TO120-NN:NEXTMM
6190 NEXTNN
6200 POKEVV+5,31:POKEVV+4,129
6210 FORNN=40TO200STEP0.1
6220 POKEVV+1,NN
6230 NEXTNN
6240 POKEVV+4,0
6260 RETURN

7000 POKE54296,15:POKE54295,0
7010 VV=54272:POKEVV+1,40
7040 POKEVV+6,240:POKEVV+5,0:POKEVV+4,0
7050 POKEVV+4,17
7060 FORMM=20TOSTEP-1
7070 FORNN=MMTO70-MM
7080 POKEVV+1,NN
7090 NEXTNN:NEXTMM
7100 POKEVV+1,3
7105 RETURN
8000 PRINT”(clear)(blue)(3 down)LOAD”CHR$(34)”PAYLOAD”CHR$(34)”,8″:PRINT”(4 down)RUN(home)”
8002 POKE631,13:POKE632,13:POKE198,2