Skip to content
Game 3

Finish, test and keep Touchdown

Finish the target, feedback and saved version without changing the flight model behind the player's back.

Continue with Draw the craft and its flame. We have a complete approach over uneven terrain with a generous pad. Finish the target, feedback and saved version without changing the flight model behind the player’s back.

Compare the target width

Replace lines 80, 640, 720, 730.

80 PRINT AT 10,2;"Pad: ====  Safe speed: 0 to 12"
640 FOR c=23 TO 26: PRINT PAPER 6;INK 0;AT 20,c;"=": NEXT c
720 IF side=0 AND x>=23 AND x<=26 THEN LET m$="Too fast for the pad."
730 IF side=0 AND x>=23 AND x<=26 AND v<=12 AND v>=0 THEN LET m$="Safe landing!"

The pad now spans columns 23–26. Both outer columns remain valid because the craft is one cell wide. We changed the drawing and both pad tests together; the skyline and safe-speed limit stay the same.

Keep the preceding wide-pad version for comparison. Try several attempts at each width with the same starting point and flight values. A narrower target increases the alignment demand; more fuel would change how long you can correct an approach. Those are different kinds of forgiveness.

The current challenge uses starting position 400 in column 6, 45 fuel units, gravity +2, thrust −6 and a safe downward velocity of 0–12. The ridge and narrow pad make this a demanding approach. Your first attempt need not succeed, and the values are choices you can investigate rather than rules you must never change.

If the approach feels too hard, why change one setting at a time?

Show the explanation

Changing pad width, fuel and gravity together makes it difficult to tell which change helped. Choose the difficulty you observed—alignment, running out of correction time, or braking—and compare a setting related to it while keeping the others steady.

Complete program for this step
10 BORDER 0: PAPER 0: INK 7: BRIGHT 1: CLS
20 DIM h(32): RESTORE 9000
30 FOR c=1 TO 32: READ h(c): NEXT c
40 FOR c=0 TO 15: READ b: POKE USR "a"+c,b: NEXT c
50 PRINT AT 3,9;"TOUCHDOWN"
60 PRINT AT 6,2;"O / P: steer left / right"
70 PRINT AT 8,2;"SPACE: thrust (with steering)"
80 PRINT AT 10,2;"Pad: ====  Safe speed: 0 to 12"
90 PRINT AT 12,2;"Empty tank? You still coast."
100 PRINT AT 15,2;"S launches. Q quits."
110 GO SUB 800: IF k$="q" THEN GO TO 850
120 CLS: GO SUB 600
130 LET x=6: LET y=400: LET v=0: LET fuel=45: LET r=4: LET burn=0
140 PRINT AT r,x;CHR$ 144
150 PRINT AT 0,1;"FUEL       SPEED       MAX 12"
160 PRINT AT 1,1;"O/P STEER  SPACE THRUST  Q QUIT"
200 LET k$=INKEY$: IF k$="q" THEN GO TO 850
210 LET keys=IN 57342: LET nx=x
220 IF INT (keys/2)-2*INT (keys/4)=0 THEN LET nx=nx-1
230 IF keys-2*INT (keys/2)=0 THEN LET nx=nx+1
240 IF nx<1 THEN LET nx=1
250 IF nx>30 THEN LET nx=30
260 LET burn=0: LET keys=IN 32766
270 IF keys-2*INT (keys/2)=0 AND fuel>0 THEN LET burn=1: LET fuel=fuel-1
280 LET v=v+2-6*burn
290 IF v>60 THEN LET v=60
300 IF v<-30 THEN LET v=-30
310 LET ny=y+v: LET contact=0: LET side=0: LET limit=100*(h(nx+1)-1)
320 IF nx<>x AND y>=limit THEN LET contact=1: LET side=1: LET nx=x
330 IF ny>=limit THEN LET contact=1
340 IF contact=1 THEN LET ny=limit
345 IF side=1 THEN LET ny=y
350 IF ny<300 THEN LET ny=300: LET v=0
360 LET nr=INT (ny/100)
370 PRINT AT 0,6;fuel;"  ";AT 0,19;v;"   "
380 PRINT AT r,x;" ";AT nr,nx;CHR$ (144+burn)
390 LET x=nx: LET y=ny: LET r=nr
400 IF contact=1 THEN GO TO 700
410 PAUSE 2: GO TO 200
600 FOR c=0 TO 31
610 FOR j=h(c+1) TO 21: PRINT PAPER 4;INK 0;AT j,c;" ";: NEXT j
620 PRINT PAPER 4;INK 0;AT h(c+1),c;"#"
630 NEXT c
640 FOR c=23 TO 26: PRINT PAPER 6;INK 0;AT 20,c;"=": NEXT c
650 RETURN
700 PRINT AT r,x;CHR$ 144
710 LET m$="Terrain collision."
720 IF side=0 AND x>=23 AND x<=26 THEN LET m$="Too fast for the pad."
730 IF side=0 AND x>=23 AND x<=26 AND v<=12 AND v>=0 THEN LET m$="Safe landing!"
740 PRINT AT 2,1;m$;"    "
770 PRINT AT 1,1;"R retries. Q quits.            "
780 IF INKEY$<>"" THEN GO TO 780
790 LET k$=INKEY$: IF k$<>"r" AND k$<>"q" THEN GO TO 790
795 IF INKEY$<>"" THEN GO TO 795
796 IF k$="q" THEN GO TO 850
797 GO TO 120
800 IF INKEY$<>"" THEN GO TO 800
810 LET k$=INKEY$: IF k$<>"s" AND k$<>"q" THEN GO TO 810
820 IF INKEY$<>"" THEN GO TO 820
830 RETURN
850 IF INKEY$<>"" THEN GO TO 850
860 PAPER 0: INK 7: CLS: PRINT "Finished.": STOP
9000 DATA 18,18,18,19,19,19,19,19,18,17,16,15,14,14,14,15,16,17,18,19,20,20,20,20,20,20,20,20,19,18,18,18
9010 DATA 24,60,60,126,90,66,0,0,24,60,60,126,90,66,24,36

Let the result have a sound

Add lines 750, 760.

750 IF m$="Safe landing!" THEN BEEP .08,12: BEEP .12,19
760 IF m$<>"Safe landing!" THEN BEEP .15,-12

BEEP takes a duration in seconds and a pitch in semitones relative to middle C. The safe result plays two short rising notes; the other results use one lower note. Decimal .08 means 0.08 seconds. The messages still identify the result with sound off.

These commands run after contact has stopped the flight loop. BEEP occupies the interpreter while it sounds. Putting it on every burn would change update work and potentially control response, so flight stays silent in this version. Listen to the result sounds in the running game; do not infer their quality from the numbers alone.

Check the whole attempt

Run the ordinary starting program and check a safe landing and a failed approach. Retry each result. The site should be unchanged, fuel should return to 45, and no flame or old instrument digits should survive the reset.

Check both pad edges and their adjacent misses, a hard arrival on the pad, a sideways collision while climbing and a downward move crossing the ground. Hold opposing steering keys, combine steering with Space, reach both horizontal boundaries and the ceiling, and hold thrust until fuel is empty. Empty fuel must stop the engine while the craft keeps moving.

Finally hold Q alone during flight, then release it. The game should return to BASIC cleanly. Waiting for release before STOP prevents an old game-control press becoming unwanted editor input. Pressing Q while other controls remain held is not the single-key quit choice used here.

Use both ordinary approaches and deliberately prepared boundary states when testing your changes. A nearly landed test position can establish an edge rule; it cannot establish that the normal approach is enjoyable. Keep those observations separate.

Save something you can reopen

Use SAVE "touchdown" and export the recording as a tape file. The Meet BASIC saving guide covers the recording and export workflow. Give a modified practice version a different name so you retain the comparison.

Load the saved program into a fresh session with LOAD "touchdown", then RUN. Check the title, custom characters, flight, retry and exit. The DATA reconstructs the site and craft; the new session should not need a graphic left behind by another program.

The supplied source uses the sample repository’s MIT licence. Retain its notice when sharing copies or substantial parts and credit your changes. The craft and terrain data were created for this game; there is no borrowed sprite pack to track down.

Touchdown adds a changing velocity, a finite resource and a meaningful landscape to the continuous updates explored in Volley. A saved game and a traceable explanation of its decisions are both worth keeping.

Complete program for this step
10 BORDER 0: PAPER 0: INK 7: BRIGHT 1: CLS
20 DIM h(32): RESTORE 9000
30 FOR c=1 TO 32: READ h(c): NEXT c
40 FOR c=0 TO 15: READ b: POKE USR "a"+c,b: NEXT c
50 PRINT AT 3,9;"TOUCHDOWN"
60 PRINT AT 6,2;"O / P: steer left / right"
70 PRINT AT 8,2;"SPACE: thrust (with steering)"
80 PRINT AT 10,2;"Pad: ====  Safe speed: 0 to 12"
90 PRINT AT 12,2;"Empty tank? You still coast."
100 PRINT AT 15,2;"S launches. Q quits."
110 GO SUB 800: IF k$="q" THEN GO TO 850
120 CLS: GO SUB 600
130 LET x=6: LET y=400: LET v=0: LET fuel=45: LET r=4: LET burn=0
140 PRINT AT r,x;CHR$ 144
150 PRINT AT 0,1;"FUEL       SPEED       MAX 12"
160 PRINT AT 1,1;"O/P STEER  SPACE THRUST  Q QUIT"
200 LET k$=INKEY$: IF k$="q" THEN GO TO 850
210 LET keys=IN 57342: LET nx=x
220 IF INT (keys/2)-2*INT (keys/4)=0 THEN LET nx=nx-1
230 IF keys-2*INT (keys/2)=0 THEN LET nx=nx+1
240 IF nx<1 THEN LET nx=1
250 IF nx>30 THEN LET nx=30
260 LET burn=0: LET keys=IN 32766
270 IF keys-2*INT (keys/2)=0 AND fuel>0 THEN LET burn=1: LET fuel=fuel-1
280 LET v=v+2-6*burn
290 IF v>60 THEN LET v=60
300 IF v<-30 THEN LET v=-30
310 LET ny=y+v: LET contact=0: LET side=0: LET limit=100*(h(nx+1)-1)
320 IF nx<>x AND y>=limit THEN LET contact=1: LET side=1: LET nx=x
330 IF ny>=limit THEN LET contact=1
340 IF contact=1 THEN LET ny=limit
345 IF side=1 THEN LET ny=y
350 IF ny<300 THEN LET ny=300: LET v=0
360 LET nr=INT (ny/100)
370 PRINT AT 0,6;fuel;"  ";AT 0,19;v;"   "
380 PRINT AT r,x;" ";AT nr,nx;CHR$ (144+burn)
390 LET x=nx: LET y=ny: LET r=nr
400 IF contact=1 THEN GO TO 700
410 PAUSE 2: GO TO 200
600 FOR c=0 TO 31
610 FOR j=h(c+1) TO 21: PRINT PAPER 4;INK 0;AT j,c;" ";: NEXT j
620 PRINT PAPER 4;INK 0;AT h(c+1),c;"#"
630 NEXT c
640 FOR c=23 TO 26: PRINT PAPER 6;INK 0;AT 20,c;"=": NEXT c
650 RETURN
700 PRINT AT r,x;CHR$ 144
710 LET m$="Terrain collision."
720 IF side=0 AND x>=23 AND x<=26 THEN LET m$="Too fast for the pad."
730 IF side=0 AND x>=23 AND x<=26 AND v<=12 AND v>=0 THEN LET m$="Safe landing!"
740 PRINT AT 2,1;m$;"    "
750 IF m$="Safe landing!" THEN BEEP .08,12: BEEP .12,19
760 IF m$<>"Safe landing!" THEN BEEP .15,-12
770 PRINT AT 1,1;"R retries. Q quits.            "
780 IF INKEY$<>"" THEN GO TO 780
790 LET k$=INKEY$: IF k$<>"r" AND k$<>"q" THEN GO TO 790
795 IF INKEY$<>"" THEN GO TO 795
796 IF k$="q" THEN GO TO 850
797 GO TO 120
800 IF INKEY$<>"" THEN GO TO 800
810 LET k$=INKEY$: IF k$<>"s" AND k$<>"q" THEN GO TO 810
820 IF INKEY$<>"" THEN GO TO 820
830 RETURN
850 IF INKEY$<>"" THEN GO TO 850
860 PAPER 0: INK 7: CLS: PRINT "Finished.": STOP
9000 DATA 18,18,18,19,19,19,19,19,18,17,16,15,14,14,14,15,16,17,18,19,20,20,20,20,20,20,20,20,19,18,18,18
9010 DATA 24,60,60,126,90,66,0,0,24,60,60,126,90,66,24,36

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 18 (keyboard polling), chapter 19 (BEEP), and chapter 20 (tape storage).