This program is an action game in which the player controls an operative inside a nuclear power station, navigating corridors to collect fourteen radioactive fuel rods and deposit them in lead containers while avoiding laser fire and a Guardian Robot. The game uses 21 user-defined graphics (UDGs, characters 144–164) loaded via POKE USR at startup from DATA statements, providing custom sprite shapes for the character, robot, explosions, and environmental tiles. Movement is handled through STICK input (line 2050–2080), with ATTR checks detecting wall tiles (value 57), hazard tiles, and container tiles (value 56) for collision logic. A DATA-driven path at line 9990 controls a moving goal indicator across the top of the screen, cycling through column positions to guide the player. The animated title screen (lines 9820–9977) uses multi-colored block graphics to render a stylized logo that cycles through INK colors in a loop.
Program Analysis
Program Structure
The program is divided into several functional regions:
- Initialization (lines 110, 500–510): Sets up variables and loads UDG data if needed, then jumps to the title screen.
- Main Game Loop (lines 1000–1500): Calls the movement handler, randomly triggers hazard routines, and loops indefinitely.
- Movement Routines (lines 2050–2850): Dispatches on STICK direction and handles left/right/up/down movement with collision detection via ATTR.
- Hazard Routines (lines 3000–3200): Vertical laser beam (line 3000) and horizontal laser beam (line 3200), each checking if the player is in the beam’s path.
- Goal/Scoring Logic (lines 3500–3560): Reads the next target column from a DATA sequence and checks whether the player has reached it at row 2.
- Death and Injury Screens (lines 4000–4750): Handles fatal hits (line 4000) and injury/recovery (line 4700).
- Fuel Rod Collection (lines 5000–5220): Detects container tiles and fuel rod pickup, tracks the count in
rs. - Mission Complete (line 6000): Triggers when all 14 rods are collected.
- Screen Setup and Game Start (lines 9000–9080): Draws the complex play-field using block graphics and UDGs.
- Instructions (lines 9200–9420): Multi-page mission briefing with a humorous “self-destruct” refusal branch.
- UDG Loader (lines 9500–9650): Installs 21 custom characters by POKEing pixel data from DATA statements.
- Title Screen (lines 9820–9977): Animated block-graphic logo that cycles INK colors in a tight loop.
- Goal Path Data (line 9990): A long sequence of column positions driving the moving target indicator.
User-Defined Graphics
Characters 144–164 (UDGs \a through \u) are loaded at lines 9500–9520 via a nested loop that READs 8 bytes per character and POKEs them into USR (CHR$ z). The 21 × 8 = 168 bytes of pixel data are spread across DATA statements at lines 9700–9790. These UDGs represent the player sprite (\a), walking animation frames, an explosion sequence (\k–\n), the robot (\i), fuel rod (\j), and various wall and floor tile components.
STICK-Based Movement Dispatch
Lines 2050–2090 read STICK(1,1) and branch to one of four direction subroutines. The bit values mirror the standard joystick encoding: 4 = left, 2 = down, 1 = up, 8 = right. Each direction subroutine first adjusts the candidate coordinate, then performs an ATTR check on the target cell before committing or reverting the move.
| STICK value | Direction | Handler line |
|---|---|---|
| 4 | Left | 2500 |
| 2 | Down | 2600 |
| 1 | Up | 2700 |
| 8 | Right | 2800 |
ATTR-Based Collision Detection
Rather than maintaining a separate map array, the game reads screen attribute bytes directly using ATTR (ny,nx) to determine what occupies a cell. Key sentinel values are:
57— wall tile (blocks movement in all directions)56— lead container (triggers fuel rod deposit at line 5000)63— floor tile that allows downward movement187— fuel rod pickup tile (triggers collection at line 5200)
Variable j as a Computed GO SUB Target
The variable j is initialized to 0 at line 9820 and set to 2050 at line 9420 after the player accepts the mission. Line 1000 executes GO SUB j, which means before the mission is accepted j=0 points to a non-existent line (a deliberate no-op technique), and after acceptance it dispatches to the STICK handler at line 2050. This avoids a conditional branch in the tight game loop.
Randomized Hazard Frequency
Line 1010 uses INT (RND*rc) — where rc starts at 17 and decreases by 1 each time a rod is collected — to gate the hazard subroutines. As more rods are collected, the denominator shrinks, making hazards trigger more frequently and increasing difficulty.
Line 1020 calls GO SUB 3100+(100*l) where l alternates between -1, 0, and 1, selecting between: a short delay loop at 3100 (when l=-1), the vertical laser at 3000 (when l=0, offset gives 3100… actually l=0 gives 3100 — the vertical laser is at 3000, horizontal at 3200). When l=1, GO SUB 3200 fires the horizontal laser.
DATA-Driven Goal Indicator
Line 3500 reads successive column values from the DATA at line 9990 and prints a UDG target marker (\t) at row 2 at the new column while erasing the old one tracked in gx. When the data is exhausted (sentinel value 2 at the end of the sequence), RESTORE 9990 resets the pointer. The player must reach row 2 at the indicated column to score a rod deposit.
Injury and Death System
A hit-counter variable m tracks cumulative damage. When m<3, the injury routine at line 4700 is called instead of the death screen, giving the player two “lives” worth of hits before a fatal outcome. The player is prompted to press X to restart from the current position after an injury. After the third hit, the death/game-over screen at line 4000 displays statistics.
Title Screen Animation
Lines 9825–9977 render a block-graphic title logo using a dense series of PRINT statements containing ZX Spectrum block graphic characters. The outer loop (line 9825) cycles INK colors from 4 down to 0 and then loops back via line 9977, creating a color-cycling animation. A counter j is incremented each pass; when it reaches 16 (line 9850), the program jumps to the instructions screen, giving the title approximately 16 color cycles before auto-advancing.
Notable Bugs and Anomalies
- Line 6030 contains a typo:
"CONGATULATIONS!"should be"CONGRATULATIONS!". - Line 3560 (the scoring branch from the goal check) contains a
FORloop that referencesGO TO 3225inside the loop body rather than aNEXT, meaning the loop never actually completes normally — control always exits via the GO TO. This is an intentional animation idiom but could be considered a loop structure anomaly. - Line 4730 (
CLS : GO TO 9010) is unreachable; the preceding line 4720 loops back to 4710 unconditionally untilINKEY$="x", at which point line 4740 is called, bypassing 4730 entirely. - The
DELETE 1,statement at line 9410 (in the self-destruct branch) is a TS2068-specific command that deletes program lines, providing a dramatic “self-destruct” effect if the player refuses the mission.
Content
Source Code
110 LET l=-1: LET m=0
500 IF PEEK 65370<>28 THEN GO SUB 9500
505 RESTORE 9990
510 GO TO 9820
1000 GO SUB j
1010 IF INT (RND*rc)=1 THEN LET l=l+1: IF l>1 THEN LET l=-1
1020 GO SUB 3100+(100*l)
1030 GO SUB j
1040 GO SUB 3500
1500 GO TO 1000
2050 IF |(1,1)=4 THEN GO TO 2500
2060 IF |(1,1)=2 THEN GO TO 2600
2070 IF |(1,1)=1 THEN GO TO 2700
2080 IF |(1,1)=8 THEN GO TO 2800
2090 RETURN
2500 LET nx=nx-1
2515 IF ATTR (ny,nx)=57 THEN GO TO 2550
2520 PRINT INK c;AT ny,nx+1;"\g";: BEEP .05,-8: PRINT AT ny,nx;"\f"; INK 7;AT ny,nx+1;" ": BEEP .05,-3: PRINT INK c;AT ny,nx;"\a"
2525 RETURN
2550 LET nx=nx+1: RETURN
2600 LET ny=ny+1
2603 IF ATTR (ny,nx)=63 THEN GO TO 2620
2605 IF ATTR (ny,nx)=56 THEN GO TO 5000
2615 IF ATTR (ny,nx)=57 THEN GO TO 2650
2620 PRINT INK c;AT ny-1,nx;"\d";AT ny,nx;"\e": BEEP .05,-8: PRINT INK c;AT ny-1,nx;"\b";AT ny,nx;"\c": BEEP .1,-8: PRINT INK 7;AT ny-1,nx;" "; INK c;AT ny,nx;"\a"
2625 RETURN
2650 LET ny=ny-1: RETURN
2700 LET ny=ny-1
2710 IF ATTR (ny,nx)=187 THEN GO SUB 5200
2715 IF ATTR (ny,nx)=57 THEN GO TO 2750
2720 PRINT INK c;AT ny,nx;"\b";AT ny+1,nx;"\c": BEEP .05,-8: PRINT AT ny,nx;"\d";AT ny+1,nx;"\e": BEEP .1,-3: PRINT INK 7;AT ny+1,nx;" "; INK c;AT ny,nx;"\a"
2725 RETURN
2750 LET ny=ny+1: RETURN
2800 LET nx=nx+1
2815 IF ATTR (ny,nx)=57 THEN GO TO 2850
2820 PRINT INK c;AT ny,nx-1;"\f": BEEP .05,-8: PRINT INK 7;AT ny,nx-1;" "; INK c;AT ny,nx;"\g": BEEP .05,-3: PRINT INK c;AT ny,nx;"\a"
2825 RETURN
2850 LET nx=nx-1: RETURN
3000 LET hx=16*(INT (RND*13))+27
3010 INK 2: PLOT hx,32: DRAW 0,119: BEEP .07,30: INK 7: PLOT hx,32: DRAW 0,119
3020 IF nx<>INT (hx/8) THEN RETURN
3025 IF ny<3 OR ny>17 THEN RETURN
3030 LET m=m+1: IF m<3 THEN GO TO 4700: GO TO 3225
3100 FOR x=1 TO 10: NEXT x
3110 RETURN
3200 LET hy=2*INT (RND*7)+3
3210 PRINT INK 4;AT hy,2;"\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h\h": BEEP .07,20: PRINT INK 7;AT hy,2;" "
3220 IF hy<>ny THEN RETURN
3221 LET m=m+1: IF m<3 THEN GO TO 4700
3225 FOR x=1 TO 6: BEEP .05,7*x: PRINT INK x;AT ny,nx;"\k";AT ny,nx;"\l";AT ny,nx;"\m";AT ny,nx;"\n": NEXT x
3230 PRINT AT ny,nx;" "
3235 GO TO 4000
3500 PRINT INK 7;AT 2,gx;" "
3510 READ g: PRINT INK 2;AT 2,g;"\t"
3515 LET gx=g
3520 IF nx=g AND ny=2 THEN GO TO 3560
3530 IF g=2 THEN RESTORE 9990
3540 RETURN
3550 LET m=m+1: IF m<3 THEN GO TO 4700
3600 FOR x=1 TO 6: INK x: PRINT AT ny,nx;"\k": BEEP .03,8*x: PRINT AT ny,nx;"\l": BEEP .03,(8*x)-10: PRINT AT ny,nx;"\m": BEEP .03,(8*x)-20: PRINT AT ny,nx;"\n": BEEP .03,(8*x)-30: GO TO 3225
4000 PAUSE 100: INK 0: PAPER 7: CLS
4020 PRINT "OPERATIVE DECEASED:": BEEP .1,0: PRINT
4030 PRINT "All life functions zero": BEEP .1,0: PRINT : PRINT
4040 PRINT "STATUS REPORT:": BEEP .1,0: PRINT
4058 PRINT "Fuel rods recovered: ";rs
4060 PRINT "Mission success: ";INT (rs/14*100);"%": BEEP .1,0: PRINT : PRINT : PRINT : PRINT
4070 PRINT "Press:": PRINT : PRINT "1: For Mission Instructions.": PRINT "2: To start.": BEEP .1,0
4080 IF INKEY$="1" THEN GO TO 9200
4090 IF INKEY$="2" THEN GO TO 9000
4100 GO TO 4080
4700 FOR q=1 TO 10: PRINT AT ny,nx; INK 6;"\a"; INK 2;AT ny,nx;"\a": BEEP .02,q: NEXT q
4705 PRINT INK 7; PAPER 0;AT 0,2;"OPERATIVE INJURED. PRESS 'X'";AT 21,0;"FOR MEDICAL ATTENTION & RESTART": BEEP .1,0
4710 IF INKEY$="x" THEN GO TO 4740
4720 GO TO 4710
4730 CLS : GO TO 9010
4740 PRINT INK 1;AT 0,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::";AT 21,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
4750 PRINT AT ny,nx; INK c;"\a": GO TO 1000
5000 IF c<>3 THEN GO TO 5100
5010 LET c=0: LET rc=rc-1
5020 FOR x=-40 TO 40 STEP 10
5030 PRINT INK 2;AT ny,nx;"\j"
5040 LET ny=ny-1
5050 PRINT INK c;AT ny,nx;"\a"
5060 LET rs=rs+1: IF rs=14 THEN GO TO 6000
5070 RETURN
5100 LET ny=ny-1: RETURN
5200 IF c=3 THEN GO TO 5300
5210 LET c=3
5220 FOR x=1 TO 7: PRINT INK x;AT ny,nx;"\i": BEEP .5,6*x: NEXT x: RETURN
5300 LET ny=ny+1: RETURN
6000 PAUSE 100: PAPER 7: INK 1: BORDER 2: BRIGHT 1: CLS
6020 PRINT "MISSION COMPLETED:": BEEP .1,10: PRINT
6030 PRINT "CONGATULATIONS! All rods recovered Station now safe.": BEEP .1,10
6040 PRINT : PRINT : PRINT : PRINT : PRINT : PRINT : PRINT : GO TO 4070
9000 PAPER 7: BRIGHT 0: CLS : LET c=0: LET ny=19: LET nx=15: LET rs=0: LET gx=4: LET m=0: LET rc=17
9010 PRINT INK 1;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
9020 PRINT INK 1;"\::\::": FOR x=2 TO 28 STEP 2: PRINT AT 1,x; INK 3; FLASH 1;"\p"; INK 1; FLASH 0;"\::": NEXT x: PRINT AT 1,30; INK 1;"\::\::"
9030 PRINT INK 1;"\::\::"; INK 7;" "; INK 1;"\::\::\::"
9035 FOR y=3 TO 15 STEP 2: PRINT AT y,0; INK 1;"\::\q"; INK 7;" "; INK 1;"\r\::\::": PRINT AT y+1,0; INK 1;"\::\::\::": FOR x=3 TO 25 STEP 2: PRINT AT y+1,x; INK 7;" "; INK 1;"\u";: NEXT x: PRINT INK 7;" "; INK 1;"\::\::\::\::": NEXT y
9040 PRINT INK 1;"\::"; INK 7;" "; INK 1;"\::\::"
9045 PRINT INK 1;"\::"; INK 7;" "; INK 1;"\::\s\::\s\::\s\::\s\::\s\::\s\::\s\::\s\::\s\::\s\::\s\::\s\::\s\::"; INK 7;" "; INK 1;"\::\::"
9050 PRINT INK 1;"\::"; INK 7;" "; INK 1;"\::\::"
9055 PRINT INK 1;"\::\::": FOR x=2 TO 28 STEP 2: PRINT AT 20,x; INK 0;"\p"; INK 1;"\::": NEXT x: PRINT AT 20,30; INK 1;"\::\::"
9060 PRINT INK 1;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
9070 PRINT INK c;AT ny,nx;"\a"
9080 GO TO 1000
9200 CLS : INK 0: PAPER 7: BORDER 7: CLS
9210 PRINT "LOCATION:": BEEP .5,10: PRINT ''"The Bruce Automated Nuclear Power Station, patrolled by Guardian Robots and protected by a Laser Defence Mechanism.": BEEP .5,10
9220 PRINT AT 18,3;"Press ENTER to continue"
9240 PAUSE 0: CLS : PRINT "PROBLEM:": BEEP .5,10: PRINT ''"More trouble with the Commodore XL600 Computer!"''"Result: A fuel rod handling malfunction. All rods are exposed!"''"Time to critical radioactive runaway condition is unknown!": BEEP .5,10
9245 PRINT AT 18,3;"Press ENTER to continue"
9250 PAUSE 0: CLS : PRINT "MISSION:": BEEP .5,10: PRINT ''"Your mission, should you decide to take it, is to replace the outdated computer with modern Hi-Tech 2068's."''"Then move the fuel rods into protective lead containers.": BEEP .5,10
9260 PRINT AT 18,3;"Press ENTER to continue"
9310 PAUSE 0: CLS : INK 2: PRINT "TOP SECRET:": BEEP .5,10: PRINT ''"1. Fuel rods are located at the top of the screen and are recognized by their flashing radiation warning indicators": BEEP .5,10
9320 PRINT ''"2. The lead containers are in a corridor at the base of the screen.": BEEP .5,10
9330 PRINT '"3. You must transport the rods to the containers, avoiding the laser fire and Guardian Robot.": BEEP .5,10
9340 PRINT '''"Press ENTER to continue": PAUSE 0
9375 CLS : INK 0: PRINT "YOUR DECISION:"''''"1. Accept mission at all risk."'''"2. Refuse mission (program will self-destruct in 10 seconds)": BEEP .5,10
9380 IF INKEY$="1" THEN GO TO 9420
9385 IF INKEY$="2" THEN GO TO 9400
9390 GO TO 9380
9400 INK 7: PAPER 0: CLS : FOR w=1 TO 5: CLS : BEEP .05,w: BEEP .05,w+5: BEEP .05,w+10: PRINT AT 10,15;11-w: PAUSE 50: NEXT w
9405 FOR w=1 TO 6: BEEP .05,w+5: BEEP .05,w+10: BEEP .05,w+15: PRINT AT 10,15;6-w: PAUSE 55: NEXT w
9410 FOR w=40 TO -40 STEP -5: BEEP .05,w: NEXT w: PRINT AT 10,13;"POOF!": DELETE 1,
9420 LET j=2050: GO TO 9000
9500 FOR z=144 TO 164:
9510 FOR v=0 TO 7: READ a: POKE USR (CHR$ z)+v,a: NEXT v
9520 NEXT z
9650 RETURN
9700 DATA 0,8,28,42,8,20,20,20,0,0,0,0,0,0,0,8,28,44,8,20,20,16,0,0
9715 DATA 0,0,0,0,8,28,26,8,20,20,4,0,0,0,0,0,0,2,2,6,3,2,5,4
9730 DATA 0,64,64,96,192,64,160,32,0,0,0,170,85,0,0,0,60,60,255,255,255,255,60,60
9745 DATA 126,195,165,153,153,165,195,126,0,0,0,24,24,0,0,0,0,0,60,36,36,60,0,0
9760 DATA 0,126,66,66,66,66,126,0,255,129,129,129,129,129,129,255,224,208,64,160,160,32,0,0
9775 DATA 0,24,60,126,126,60,24,0,0,96,96,126,104,96,0,0,0,6,22,126,22,6,0,0
9790 DATA 0,16,16,56,16,124,124,0,165,255,153,90,126,36,24,0,126,255,255,255,255,255,255,126
9820 PAPER 7: BORDER 7: CLS : LET j=0
9825 FOR y=4 TO 0 STEP -1: INK y
9850 LET j=j+1: IF j=16 THEN GO TO 9200: BEEP .5,-25: CLS : PRINT
9853 BEEP .5,-25: CLS : PRINT
9860 PRINT " \:'\':\''\: \: \:'\''\':\ :\''\''\: \: \:'\''\':\ :\: \: "
9865 PRINT " \: \ : \: \: \:.\..\..\ :\..\..\. \: \: \ :\ :\ : \: "
9870 PRINT " \: \ : \: \: \. \ :\ . \: \: \: \ :\ : \: \: "
9880 PRINT " \' \ ' \' \' \''\''\''\ '\''\''\' \' \''\''\''\ ' \ '\' "''
9900 PRINT " \: \:'\':\''\: \:'\''\':\ :\''\''\: \:'\''\':\ :\''\''\: \ :\ :\''\': \: \ :\''\''\' "
9905 PRINT " \: \: \ : \: \:.\..\.:\ : \: \:.\..\..\ :\..\..\. \ :\ :\..\.:\. \: \ :\..\..\. "
9910 PRINT " \: \: \ : \: \: \ : \: \. \ :\ . \: \ :\ : \: \: \ :"
9915 PRINT " \' \' \ ' \' \' \ '\''\''\' \''\''\''\ '\''\''\' \ '\ '\''\''\' \''\''\''\ '\''\''\' "''''
9930 PRINT " \:'\''\ :\''\: \: \ :\ :\. \: \':\' \:'\'.\ :\''\: \: \. \: \:.\ : \ '\:'\ :\''\: "
9935 PRINT " \:.\..\ :\..\: \:.\.:\ :\ '\: \ : \:.\.'\ :\..\: \:.\:.\: \: \': \: \ :\..\: "''
9945 PRINT " \:'\''\ :\''\. \: \':\' \: \:'\''\ :\''\: \: "
9950 PRINT " \:.\..\ :\''\. \: \ : \: \:.\..\ :\''\: \:.\.. . . . . ."''
9975 NEXT y
9977 GO TO 9825
9980 GO TO 9200
9990 DATA 3,4,3,4,3,4,5,6,7,8,9,8,7,6,5,6,7,6,5,6,7,8,9,10,11,12,13,14,15,16,17,18,17,16,15,14,14,13,12,13,14,13,12,13,14,15,16,17,18,17,16,17,18,19,20,21,22,23,24,24,23,22,23,24,25,26,27,28,27,26,25,26,27,28,2
9998 CLEAR : SAVE "Mission" LINE 1: BEEP .4,15
9999 VERIFY ""
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

