Star Fleet 2068 AD is a space combat strategy game in which the player commands a starship to defend Federation star bases against waves of up to ten enemy ships. The program uses a dual-display system: a main navigation view rendered with UDGs on the 22-row play area, and a zoomed tactical screen for weapons targeting that scales world coordinates to screen positions using a factor-of-three mapping. Seven function definitions handle coordinate conversions between a packed cell format (rows×32+column) and screen positions, and a separate machine-code routine (24 bytes POKEd at address 61241) performs fast screen block copies. Gameplay variables include shields, sensors, photon torpedoes, phasers, fuel, warp factor, and player rank, which advances through six titles from Captain to Fleet Admiral as the player destroys successive waves of ten ships. The SOUND keyword drives both alert klaxons and weapon-fire audio effects, and the system clock at addresses 23672–23674 is read to implement per-turn time limits that tighten with increasing rank.
Program Analysis
Program Structure
The program is organized into a large set of labeled subroutine blocks, entered via GO TO 3510 at line 140. Initialization occupies lines 3510–4030, and the main game loop cycles through navigation (640), weapons (1580), docking (1400), alien movement (1130), and alien attack (1320 / 2940). The tactical weapons screen is a self-contained sub-loop beginning at line 1660 and returning via GO TO 2900.
Function Definitions
Seven DEF FN statements at lines 60–130 centralize all coordinate arithmetic:
FN a(r)— extracts the row from a packed cell index (INT(r/32))FN b(c)— extracts the column (c - FN a(c)*32)FN c(r,c)— packs row/column into a cell index (INT(r*32+c))FN d(x)— converts a cell index to a pixel X coordinateFN e(x)— converts a cell index to a pixel Y coordinateFN f(x)— converts a pixel Y to a character rowFN g(x)— converts a pixel X to a character columnFN h()— reads the system frame counter at addresses23672–23674and converts to seconds
Machine Code Usage
Line 3550 POKEs 24 bytes of Z80 machine code starting at address 61241, just below the CLEAR boundary set at line 3510. Two routines are embedded: one copies 4096 bytes from address 16384 (the display file) to 61265, and the other copies in the reverse direction. These are called via RANDOMIZE USR 61241 and RANDOMIZE USR 61253 at lines 1900, 1920, and 2000 to save and restore the tactical screen background, avoiding a full redraw on every targeting cursor move.
UDG Usage
Twelve UDGs (\a through \m, skipping \l) are defined by the DATA block at line 3590 and POKEd in a loop at lines 3730–3860. Their roles in the game are:
| UDG | Role |
|---|---|
\a | Player ship (facing up) |
\b | Player ship (facing left) |
\c | Player ship (facing down) |
\d | Player ship (facing right) |
\e | Star base |
\f | Enemy ship |
\g | Star |
\h | Top border tile |
\i | Right border tile |
\j | Bottom border tile |
\k | Left border tile |
\m | Targeting cursor |
Coordinate and World Model
The game world is a 22×32 character grid. All object positions are stored in array l() as packed integers using FN c(row,col)+1, making a single integer sufficient to represent any cell. The tactical view remaps world coordinates to a zoomed 19×32 character tactical screen using a scale factor of 3, centered on the player’s position, giving the illusion of a local-area sensor display within a larger galaxy.
Enemy AI and Movement
Enemy ships are divided into two groups of five (indices 1–5 and 6–10), each tracking a different star base target (b2 and b1 respectively). On the navigation screen, movement is interpolated with RND/2 weighting toward the target, creating gradual pursuit. On the tactical screen (lines 3050–3210), each ship pair (1&6, 2&7, 3&8, 4&9, 5&10) has a distinct target screen position, producing flanking and encirclement behavior that scales in aggression with rank.
SOUND Usage
The SOUND keyword is used throughout for audio feedback. Line 230 defines a 14-channel sound event stored in array t() and played as a destruction fanfare. Lines 3970–4000 use SOUND in a loop to produce a descending siren effect for the battle-stations alert. Weapon fire uses BEEP rather than SOUND for the torpedo and phaser shots.
Fuel Bar Display
Lines 270–310 implement a graphical fuel gauge using the block graphic character \:: (solid block) stored in string array f$(). The bar changes INK color based on fuel level: INK 4 (green) for 10+, INK 6 (yellow) for 6–9, and INK 2 (red) for 5 or below, giving the player an immediate visual warning.
Rank and Difficulty Scaling
The player’s rank variable (1–6, corresponding to Captain through Fleet Admiral) affects multiple game parameters: the per-turn time limit (20-rank*2 seconds), the alien attack range (1+rank/6 cells), the alien weapon damage (RND*rank/6), and the targeting timer. Each wave of ten kills triggers a rank promotion and restores equipment stats at the next docking, while also adjusting the active star base range via b1 and b2.
Bugs and Anomalies
- Line
2380uses variablej2which is never initialized or assigned anywhere in the program. This would cause an error or use a zero default when calculating indices intog()for star hits, potentially misidentifying the struck object. - Line
1140computesINT (b(i,2)+0.5)+1without outer parentheses around the full expression, unlike the analogousINT (b(i,1)+0.5)— this is likely a transcription inconsistency that may produce off-by-one position updates for ships 1–5. - At line
3000, aGO SUB 360is called, but line360does not exist; the nearest defined line is350. This may be a typographical error, though the GO TO to a non-existent line resolves to the next line in some interpreters. - The
dockvariable is initialized to1at line3920, but the docking logic at lines1460–1470branches ondock=1for a successful supply anddock<1for refusal, meaning the first dock always succeeds and subsequent ones without a reset do not.
Content
Source Code
1 REM Time Designs Magazine
2 REM archive.org/details/TimeDesigns/Time%20Designs%20v3%20n5
10 REM ***********************
20 REM S T A R F L E E T 2068 AD
30 REM ***********************
40 REM S D Lemke
50 REM ***********************
60 DEF FN a(r)=INT (r/32)
70 DEF FN b(c)=c-FN a(c)*32
80 DEF FN c(r,c)=INT (r*32+c)
90 DEF FN d(x)=FN b(x)*8-4
100 DEF FN e(x)=171-FN a(x)*8
110 DEF FN f(x)=INT ((176-x)/8)
120 DEF FN g(x)=INT (x/8)
130 DEF FN h()=INT ((PEEK 23674*65536+PEEK 23673*256+PEEK 23672)/60)
140 GO TO 3510: REM START
150 REM
160 REM *** Clear Messages ***
170 REM
180 PRINT AT 19,0;TAB 31;" ";TAB 31;" ";TAB 31;" ": RETURN
190 PRINT AT 17,0;TAB 31;" ";TAB 31;" ";TAB 31;" ": RETURN
200 PRINT AT 19,0;TAB 31;" ";TAB 31;" ";TAB 31;" ": PRINT #0;AT 0,0;TAB 31;" ";TAB 31;" ": RETURN
210 PRINT AT 0,10;"Time = ";FN h(): RETURN
220 PRINT AT 16,10;"Time = ";FN h();TAB 31;" ": RETURN
230 SOUND 0,t(1);1,t(2);2,t(3);3,t(4);4,t(5);5,t(6);6,t(7);7,t(8);8,t(9);9,t(10);10,t(11);11,t(12);12,t(13);13,t(14): PAUSE 15: SOUND 8,0;9,0;10,0: RETURN
240 REM
250 REM *** Fuel Status ***
260 REM
270 LET i=INT (fuel+.99): IF fuel<0 THEN CLS : PRINT "******************************** You have run out of fuel! The Federation is doomed. Your ship is lost. *******************************": GO TO 3940
280 FOR j=1 TO i: GO SUB 210: LET f$(j)="\::": NEXT J: FOR j=(i+1) TO 20: LET f$(j)=" ": NEXT j: PRINT AT 18,0;" "
290 IF i>=10 THEN PRINT AT 18,0;"FUEL = "; INK 4;f$;TAB 28; INK 9;fuel
300 IF i>5 AND i<10 THEN PRINT AT 18,0;"FUEL = "; INK 6;f$;TAB 28; INK 9;fuel
310 IF i<=5 THEN PRINT AT 18,0;"FUEL = "; INK 2;f$;TAB 26; INK 9;fuel
320 REM
330 REM *** Weapons Status ***
340 REM
350 PRINT #0;AT 0,0;"Torpedo= ";pt;TAB 18;"Phaser= ";ph;TAB 31;" "
360 PRINT #0;AT 1,0;"Shields = ";INT (sh*10)/10;TAB 18;"Sensors = ";INT (sn*10)/10;TAB 31;" ": RETURN
370 REM
380 REM
390 FOR i=1 TO 10: GO SUB 210: LET b(i,1)=FN a(l(i)): LET b(i,2)=FN b(l(i))-1: NEXT i: FOR i=1 TO 9: LET c(i,1)=FN a(l(i+10)): LET c(i,2)=FN b(l(i+10))-1: NEXT i: LET d(1)=FN a(l(31)): LET d(2)=FN b(l(31))-1: LET c(21,1)=d(1): LET c(21,2)=d(2)
400 PRINT AT 0,0; INK ik7;a$
410 LET je=0: FOR i=1 TO 10: GO SUB 210: IF l(i)>0 AND l(i)<704 THEN PRINT AT b(i,1),b(i,2); INK ik5;"\f": LET je=je+1: LET g(je)=i
420 NEXT i
430 FOR i=1 TO 9: GO SUB 210: IF l(i+10)>0 AND l(i+10)<704 THEN PRINT AT c(i,1),c(i,2); INK ik1;"\e"
440 NEXT i
450 PRINT AT d(1),d(2); INK ik0;"\a"
460 GO TO 270
470 REM
480 REM ******* Read Joystix ****
490 REM
500 OUT 245,14: LET stk=IN 5110: IF stk<128 THEN LET b$=CHR$ 13: LET stk=0: RETURN
510 LET stk=255-stk: RETURN
520 REM
530 REM *** Target Lock ***
540 REM
550 LET dlx=(x2-x1)/20: LET dly=(y2-y1)/20: IF ABS dlx<=1 AND ABS dly<=1 THEN RETURN
560 PRINT AT 18,0;TAB 31;" ";TAB 6; FLASH 1;"Locking onto Target!"; FLASH 0;TAB 31;" "
570 FOR k=5 TO 20: GO SUB 220: LET xp=x1+INT (dlx*k): LET yp=y1+INT (dly*k): IF POINT (xp,yp) THEN GO TO 590
580 NEXT k: GO SUB 180: RETURN
590 IF ABS (x2-xp)<=4 AND ABS (y2-yp)<=4 THEN GO SUB 180: RETURN
600 LET x2=xp: LET y2=yp: LET rx=FN f(y2): LET cx=FN g(x2): GO SUB 180: RETURN
610 REM
620 REM **** Nav Menu ****
630 REM
640 LET move=0: GO SUB 390: LET tim0=FN h()
650 GO SUB 180
660 LET timer=FN h()+20-rank*2: PRINT AT 21,0; FLASH 1;"NAVIGATION"; FLASH 0;" WEAPONS DOCK"
670 GO SUB 210
680 LET b$=INKEY$
690 IF FN h()>timer THEN GO TO 1130
700 IF b$="w" OR b$="W" THEN GO TO 1580
710 IF b$="d" OR b$="D" THEN GO TO 1400
720 IF b$="n" OR b$="N" THEN GO TO 750
730 GO SUB 500: IF stk<>0 THEN GO TO 750
740 IF b$<>CHR$ 13 THEN GO TO 670
750 REM
760 REM *** Navigation ***
770 REM
780 IF wf>mwf THEN LET wf=mwf
790 GO SUB 180
800 LET tim0=FN h(): PRINT AT 20,0; FLASH 1;" Helm at your command ";AT 19,8; FLASH 0;"Warp Factor = ";wf: LET ist=0
810 GO SUB 210: LET b$=INKEY$: GO SUB 500: IF b$="0" OR stk<>0 THEN LET ist=1: PRINT AT d(1),d(2); PAPER ik3;" ": IF s(1)<>0 AND s(2)<>0 THEN PRINT AT s(1),s(2); INK ik1;"\e": LET s(1)=0: LET s(2)=0
820 IF b$>="1" AND b$<="3" THEN LET wf=(CODE b$)-48: PRINT AT 19,8;"Warp Factor = ";wf: GO TO 810
830 IF b$="w" OR b$="W" THEN GO TO 1580
840 IF b$="d" OR b$="D" THEN GO TO 1400
850 IF FN h()-tim0>=20-rank*2 THEN GO TO 1130
860 IF b$=CHR$ 13 THEN GO TO 650
870 IF ist=0 THEN GO TO 810
880 GO SUB 180
890 REM
900 REM *** Your move ***
910 REM
920 IF stk>=4 AND stk<=6 THEN LET d(2)=d(2)-(d(2)>0)*wf: LET qd=1
930 IF stk=6 OR stk=2 OR stk=10 THEN LET d(1)=d(1)+(d(1)<17)*wf: LET qd=2
940 IF stk=1 OR stk=5 OR stk=9 THEN LET d(1)=d(1)-(d(1)>0)*wf: LET qd=3
950 IF stk>=8 AND stk<=10 THEN LET d(2)=d(2)+(d(2)<31)*wf: LET qd=4
960 IF qd=4 THEN PRINT AT d(1),d(2); INK ik0;"\d"
970 IF qd=3 THEN PRINT AT d(1),d(2); INK ik0;"\a"
980 IF qd=2 THEN PRINT AT d(1),d(2); INK ik0;"\c"
990 IF qd=1 THEN PRINT AT d(1),d(2); INK ik0;"\b"
1000 GO SUB 210: LET c(21,1)=d(1): LET c(21,2)=d(2): LET move=0: LET fuel=fuel-wf*wf: GO SUB 270
1010 LET l(31)=FN c(d(1),d(2))+1
1020 REM
1030 REM *** ck collision ***
1040 REM
1050 FOR i=20 TO 30: GO SUB 210: IF l(31)=l(i) THEN CLS : PRINT "******************************** You have just run into a Star and were Vaporized! The Federation is doomed. ********************************": GO TO 3940
1060 NEXT i
1070 FOR j=1 TO je: LET i=g(j): IF l(31)=l(i) THEN GO TO 1090
1080 NEXT j: GO TO 1130
1090 GO SUB 2620: LET je=je-1: FOR k=i TO je: LET g(k)=g(k+1): NEXT k
1100 REM
1110 REM *** move aliens ***
1120 REM
1130 GO SUB 180: FOR j=1 TO je: LET i=g(j): IF i>=6 AND i<=10 THEN GO SUB 210: IF l(i)>0 THEN PRINT AT b(i,1),b(i,2); INK ik3;"\f": LET b(i,1)=b(i,1)+(c(b1,1)-b(i,1))*RND/2: LET b(i,2)=b(i,2)+(c(b1,2)-b(i,2))*RND/2: PRINT AT b(i,1),b(i,2); INK ik5;"\f": LET l(i)=FN c(INT (b(i,1)+0.5),INT b(i,2)+0.5)+1
1140 IF i>=1 AND i<=5 THEN GO SUB 210: IF l(i)>0 THEN PRINT AT b(i,1),b(i,2); INK ik3;"\f": LET b(i,1)=b(i,1)+(c(b2,1)-b(i,1))*RND/2: LET b(i,2)=b(i,2)+(c(b2,2)-b(i,2))*RND/2: PRINT AT b(i,1),b(i,2); INK ik5;"\f": LET l(i)=FN c(INT (b(i,1)+0.5),INT (b(i,2)+0.5)+1)
1150 REM
1160 REM *** ck collision
1170 REM
1180 IF l(i)=l(31) THEN GO SUB 2620: PRINT AT d(1),d(2); INK ik0;"\a": LET je=je-1: FOR k=i TO je: LET g(k)=g(k+1): NEXT k
1190 REM
1200 REM ** Star Base Stats ***
1210 REM
1220 IF i>=6 AND i<=10 THEN GO SUB 210: IF l(i)=l(b1+10) THEN LET l(b1+10)=0: PRINT AT 20,0;"Star Base ";b1;" has been destroyed.": PAUSE 60: LET b1=b1+1: LET s(1)=0: LET s(2)=0
1230 IF i>=1 AND i<=5 THEN GO SUB 210: IF l(i)=l(b2+10) THEN LET l(b2+10)=0: PRINT AT 20,0;"Star Base ";b2;" has been destroyed.": PAUSE 60: LET b2=b2-1: LET s(1)=0: LET s(2)=0
1240 NEXT j
1250 IF l(19)=0 THEN LET b1=21: LET b2=21
1260 IF b2<b1 AND b1<>10 THEN LET b2=9: LET b1=9
1270 IF b1=10 THEN LET b2=21: LET b1=21
1280 IF b2=8 AND b1>=9 THEN LET b1=21: LET b2=21
1290 REM
1300 REM *** Alien Attack ***
1310 REM
1320 LET x2=FN d(l(31)): LET y2=FN e(l(31)): LET hit=0: LET dmg=0: FOR j=1 TO je: LET i=g(j): GO SUB 210: IF ABS (b(i,1)-d(1))<=(1+rank/6) AND ABS (b(i,2)-d(2))<=(1+rank/6) THEN LET hit=hit+1: LET dmg=dmg+RND*.5*hit: LET x1=FN d(l(i)): LET y1=FN e(l(i)): PLOT INK ik5;x1,y1: DRAW INK ik5;(x2-x1),(y2-y1): BEEP .3,45: PLOT INK ik3;x1,y1: DRAW INK ik3;(x2-x1),(y2-y1): PRINT AT b(i,1),b(i,2); INK ik5;"\f": PRINT AT d(1),d(2); INK ik0;"\a"
1330 NEXT j: IF hit>0 THEN GO SUB 180: PRINT AT 20,0;"Damage Control: ";hit;" hits on shield"
1340 LET sh=sh-dmg: IF sh<=0 THEN CLS : PRINT "******************************** Your shields have gone down. Emergency procedures are in effect. Abandon Ship !!! ********************************";''';"You successfully destroyed ";score;"enemy ships. Thankyou for a goodgame!";''';"********************************Total mission time: ";FN h();" seconds";';"********************************": PAUSE 0: GO TO 3510
1350 IF hit>0 AND sh<5 THEN LET sn=sh*.6
1360 IF hit>0 AND sh<5 THEN LET mwf=INT (sh*.4+1)
1370 GO SUB 350: IF hit>0 THEN PAUSE 200
1380 IF move THEN GO TO 650
1390 GO TO 750
1400 REM
1410 REM *** Star Base Dock ***
1420 REM
1430 GO SUB 180: LET move=1: GO SUB 210: FOR i=11 TO 19: IF l(31)=l(i) THEN GO TO 1450
1440 NEXT i: GO SUB 200: PRINT AT 20,0;"You are not in a Star Base orbit"; FLASH 1;AT 21,4;"Docking is not possible!": GO SUB 210: PAUSE 90: GO SUB 210: PAUSE 90: GO SUB 210: GO SUB 180: GO SUB 350: GO TO 1130
1450 GO SUB 210: LET s(1)=d(1): LET s(2)=d(2): FOR j=1 TO je: LET i=g(j): GO SUB 210: IF (ABS (b(i,1)-d(1))+ABS (b(i,2)-d(2)))<=(2+rank-1) THEN GO SUB 200: PRINT AT 20,0;"Star Base will not lower their shields because there are enemy": PRINT #0;AT 0,0;" ships in the quadrant !": GO SUB 210: PAUSE 90: GO SUB 210: PAUSE 90: GO SUB 200: GO SUB 350: GO TO 1130
1460 NEXT j: IF dock=1 THEN GO SUB 200: PRINT AT 20,3;"Docking orbit is verified.";TAB 6;"Supply is initiated.": LET fuel=fuel+INT (RND*40): LET sh=sh+INT (RND*20): LET sn=sn+INT (RND*6): LET pt=pt+INT (RND*10): LET ph=ph+INT (RND*10): GO SUB 210: GO SUB 1510: GO SUB 210: PAUSE 60: GO SUB 200: GO SUB 270: LET s(1)=d(1): LET s(2)=d(2): GO TO 1130
1470 IF dock<1 THEN LET dock=dock+1: GO SUB 200: PRINT AT 20,0;"Docking orbit is verified. Star Base refuses to lower its": PRINT #0;AT 0,0;"shields. Supply is impossible. ": GO SUB 210: PAUSE 60: GO SUB 210: PAUSE 60: GO SUB 210: GO SUB 180: GO SUB 350: GO TO 1130
1480 REM
1490 REM *** ck max load ***
1500 REM
1510 IF fuel>20 THEN LET fuel=20
1520 LET mwf=3
1530 IF sh>msh THEN LET sh=msh
1540 IF sn>msn THEN LET sn=msn
1550 IF pt>mpt THEN LET pt=mpt
1560 IF ph>mph THEN LET ph=mph
1570 RETURN
1580 REM
1590 REM *** Weapons ***
1600 REM
1610 GO SUB 200: GO SUB 210: PRINT AT 20,8;"Weapon Control:";TAB 1;"Prepare to select your target."
1620 LET wpn=1: IF ph>pt THEN LET wpn=2
1630 REM
1640 REM ** Tactical Scrn ***
1650 REM
1660 LET loc=FN c(9,16)+1: LET x1=FN d(loc): LET y1=FN e(loc): LET x2=x1: LET y2=y1
1670 LET js=0: LET d$=c$: FOR i=20 TO 30: GO SUB 210: LET f(i,1)=INT ((FN a(l(i))-d(1))*3+9): LET f(i,2)=INT ((FN b(l(i))-1-d(2))*3+16): IF f(i,1)>=0 AND f(i,1)<=18 AND f(i,2)>=0 AND f(i,2)<=30 THEN LET locs=FN c(f(i,1),f(i,2))+1: IF locs>0 AND locs<512 THEN LET d$(locs)="\g": IF js<10 THEN LET js=js+1: LET g(js+10)=i
1680 NEXT i
1690 PRINT AT 0,0; INK ik7;d$(1 TO 512);TAB 31;" ";TAB 31;" ";TAB 31;" "
1700 PRINT AT 9,16; INK ik0;"\a": LET rng=24*sn: CIRCLE INK 9;x1,y1,rng: GO SUB 190: PRINT AT 21,12; FLASH 1;"Working!": GO SUB 220
1710 REM
1720 REM *** count aliens ***
1730 REM
1740 LET move=1: LET irng=0: FOR i=1 TO 10: GO SUB 220: LET f(i,1)=INT ((FN a(l(i))-d(1))*3+9): LET f(i,2)=INT ((FN b(l(i))-1-d(2))*3+16): IF f(i,1)>0 AND f(i,1)<18 AND f(i,2)>0 AND f(i,2)<32 THEN LET irng=irng+1: LET g(irng)=i
1750 NEXT i
1760 REM
1770 REM *** Bases & Stars ***
1780 REM
1790 LET jb=0: FOR i=11 TO 19: GO SUB 220: LET f(i,1)=INT ((FN a(l(i))-d(1))*3+9): LET f(i,2)=INT ((FN b(l(i))-1-d(2))*3+16)-1: IF f(i,1)>0 AND f(i,1)<18 AND f(i,2)>0 AND f(i,2)<32 THEN LET jb=jb+1: LET g(jb+20)=i
1800 NEXT i
1810 LET loc=FN c(9,16)+1
1820 LET x1=FN d(loc): LET y1=FN e(loc): LET x2=x1: LET y2=y1: PRINT AT 9,16; INK ik0;"\a"
1830 GO SUB 220: GO SUB 190: PRINT AT 17,1;"Tactical: ";irng;" ships on screen.": GO SUB 350: LET tim0=FN h(): GO SUB 2090
1840 CIRCLE INK ik0;x2,y2,1: LET rx=FN f(y2): LET cx=FN g(x2): PRINT AT rx,cx; PAPER ik3;" ": PRINT AT 9,16; INK ik0;"\a": IF FN h()-tim0>=20-rank*2 THEN GO SUB 2940: GO TO 2900
1850 FOR j=1 TO irng: GO SUB 220: PRINT AT f(g(j),1),f(g(j),2); INK ik5;"\f": NEXT j: FOR j=1 TO js: GO SUB 220: PRINT AT f(g(j+10),1),f(g(j+10),2); INK ik7;"\g": NEXT j: FOR j=1 TO jb: GO SUB 220: PRINT AT f(g(j+20),1),f(g(j+20),2); INK ik1;"\e": NEXT j
1860 REM
1870 REM *** Select Target ***
1880 REM
1890 LET timer=FN h()+20-2*rank
1900 RANDOMIZE USR 61241: PRINT AT FN f(y2),FN g(x2); OVER 1;"\m"
1910 GO SUB 220: IF FN h()>timer THEN LET b$="N": GO TO 2070
1920 RANDOMIZE USR 61253: LET b$=INKEY$: IF b$<>CHR$ 32 THEN GO SUB 2050: GO SUB 2090: GO TO 1920
1930 GO SUB 500: IF b$<>CHR$ 32 AND stk=0 THEN PRINT AT FN f(y2),FN g(x2); OVER 1;"\m": PAUSE 10: GO TO 1910
1940 IF stk>=4 AND stk<=5 THEN LET x2=x2-8*(x2>4)
1950 IF stk=2 OR stk=6 OR stk=10 THEN LET y2=y2-8*(y2>57)
1960 IF stk=1 OR stk=5 OR stk=9 THEN LET y2=y2+8*(y2<171)
1970 IF stk>=8 AND stk<=10 THEN LET x2=x2+8*(x2<250)
1980 PRINT AT FN f(y2),FN g(x2); OVER 1;"\m"
1990 IF b$<>CHR$ 13 THEN GO TO 1920
2000 RANDOMIZE USR 61253: LET rx=FN f(y2): LET cx=FN g(x2): IF x1=x2 AND y1=y2 THEN GO SUB 180: GO SUB 2940: GO TO 2900
2010 GO SUB 200: GO SUB 550: GO TO 2150
2020 REM
2030 REM *** Select Weapon ***
2040 REM
2050 IF b$="T" OR b$="t" THEN LET wpn=1
2060 IF b$="P" OR b$="p" THEN LET wpn=2
2070 IF b$="N" OR b$="n" THEN GO SUB 190: PRINT AT 19,0;"Engineering: Prepare Warp Drive": GO SUB 390: GO TO 750
2080 RETURN
2090 IF wpn=1 THEN PRINT AT 18,5; INVERSE 1;"Arming Photon Torpedo "
2100 IF wpn=2 THEN PRINT AT 18,5; INVERSE 1;"Charging Phaser Weapon"; INVERSE 0;TAB 31;" "
2110 RETURN
2120 REM
2130 REM *** fire weapon ***
2140 REM
2150 LET fuel=fuel-.2: IF fuel<=0 THEN GO TO 270
2160 LET range=SQR ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/24-RND*.5
2170 GO SUB 220: IF range>sn THEN GO SUB 190: PRINT AT 19,0;"Weapons can not lock onto target Target is out of range.": GO SUB 220: PAUSE 90: GO SUB 220: PAUSE 60: GO SUB 2940: GO TO 2900
2180 IF wpn=2 THEN GO TO 2260
2190 REM
2200 REM *** photon torpedo
2210 REM
2220 GO SUB 220: LET rx0=2*RND: IF pt<=0 THEN GO SUB 190: PRINT AT 18,4;"Torpedo bank is expended!": GO SUB 220: PAUSE 60: GO SUB 220: GO SUB 2940: GO TO 2900
2230 LET pt=pt-1: LET npts=INT (range*5): IF npts<=0 THEN LET npts=1
2240 GO SUB 190: LET ptr=1/npts: LET dlx=(x2-x1)/npts: LET dly=(y2-y1)/npts: FOR i=1 TO npts: GO SUB 220: LET px=x1+INT (dlx*i): LET py=INT (dly*i): PLOT INK 9;px,py: BEEP .02,50-i*2: INVERSE 1: PLOT px,py: INVERSE 0: PRINT AT 9,16; INK ik0;"\a": NEXT i
2250 GO TO 2370
2260 REM
2270 REM *** Phaser Weapon ***
2280 REM
2290 GO SUB 220: LET rx0=1: IF ph<=0 THEN GO SUB 190: PRINT AT 18,5;"Phaser bank expended!": GO SUB 220: PAUSE 60: GO SUB 220: GO SUB 2940: GO TO 2900
2300 LET ph=ph-1
2310 GO SUB 190: PLOT INK ik0;x1,y1: DRAW INK 9;(x2-x1),(y2-y1): BEEP 1,30
2320 GO SUB 220: INVERSE 1: PLOT x1,y1: DRAW (x2-x1),(y2-y1): INVERSE 0
2330 PRINT AT 9,16; INK ik0;"\a"
2340 REM
2350 REM *** hit something? ***
2360 REM
2370 LET rx=FN f(y2): LET cx=FN g(x2): LET dmg=0: LET hit=0: FOR j=1 TO (irng+js+jb): GO SUB 220: LET i=g(j): IF j>irng THEN LET i=g(10+j-irng)
2380 IF j>(irng+js) THEN LET i=g(20+j-irng-j2)
2390 IF ABS (rx-f(i,1))<1 AND ABS (cx-f(i,2))<1 THEN LET hit=1: GO TO 2410
2400 NEXT j
2410 GO SUB 190: IF hit=0 THEN PRINT AT 18,8;"Target was missed!": GO SUB 220: PAUSE 60: GO SUB 220: PAUSE 60: GO SUB 2940: GO TO 2900
2420 IF i<=10 THEN PRINT AT 18,8;"Target was hit!": LET dmg=15+200*RND-(range-rx0*RND)*30-score/2: IF dmg<0 THEN LET dmg=0
2430 IF dmg>=100 THEN LET dmg=100
2440 LET f(i,3)=f(i,3)+dmg: IF f(i,3)<100 THEN GO TO 2510
2450 PRINT AT f(i,1),f(i,2); PAPER ik3;" ": LET f(i,3)=100: GO SUB 230: IF score=9 OR score=19 OR score=29 OR score=39 OR score=49 OR score=59 THEN GO TO 2710
2460 LET score=score+1: LET b(i,1)=0: LET b(i,2)=0: LET l(i)=0: IF i<=10 THEN LET j1=1: FOR j=1 TO irng: IF g(j)<>i THEN LET g(j1)=g(j): LET j1=j1+1
2470 GO SUB 220: NEXT j: LET irng=irng-1
2480 REM
2490 REM *** Hit Star Base ***
2500 REM
2510 IF i>=11 AND i<=19 THEN PRINT AT 19,1;" You just shot a Star Base! ": LET dock=-rank: PAUSE 100: LET l(i)=0: LET b(i-10,1)=0: LET b(i-10,2)=0: PRINT AT f(i,1),f(i,2);" ": GO SUB 2940: LET b1=21: LET b2=21: GO TO 2900
2520 REM
2530 REM *** Hit a Star ***
2540 REM
2550 IF i>=20 AND i<=30 THEN PRINT AT f(i,1),f(i,2); INK ik7;"\g": PRINT AT 19,0;"You just shot a star. The solar flare destroyed your sensors! ": GO SUB 220: CIRCLE INVERSE 1;x1,y1,24*sn: PAUSE 60: GO SUB 220: PAUSE 60: LET sn=0: GO SUB 2940: GO TO 2900
2560 REM
2570 REM *** Hit Alien Ship ***
2580 REM
2590 PRINT AT 19,6;"Target Damage: ";INT (f(i,3)*10)/10;" %": IF f(i,3)<100 THEN PRINT AT rx,cx; INK ik5;"\f": PAUSE 120: GO SUB 2940: GO TO 2900
2600 PRINT FLASH 1;AT 20,6;"Target was destroyed. ": LET l(i)=0: LET f(i,1)=0: LET f(i,2)=0: PAUSE 200: GO SUB 200: GO SUB 2940
2610 GO TO 2900
2620 REM
2630 REM *** Collision Dmg ***
2640 REM
2650 GO SUB 180: PRINT AT 19,9; FLASH 1;"Collision!"; FLASH 0;TAB 31;" You were hit by an enemy ship!": PAUSE 120: GO SUB 180: LET sh=sh-10*RND: IF sh<=5 AND sn<>0 THEN LET sn=.6*sh
2660 IF sh<0 THEN LET sh=0
2670 IF sn<0 THEN LET sn=0
2680 GO SUB 350: IF sh<=10 THEN GO TO 3930
2690 IF score=9 OR score=19 OR score=29 OR score=39 OR score=49 OR score=59 THEN GO TO 2710
2700 LET score=score+1: LET b(i,1)=0: LET b(i,2)=0: LET l(i)=0: RETURN
2710 REM
2720 REM *** Got 10 more ***
2730 REM
2740 FOR i=1 TO 10: LET f(i,3)=0: NEXT i: LET rank=rank+1: CLS : IF score>=59 THEN GO TO 2890
2750 CLS : PRINT AT 2,0;"******************************** Congratulations! You have successfully defended the Federation against 10 enemy Star Ships. ";'';" For your great victory over the enemy, the Federation Council has promoted you to the rank of";'';TAB 10;r$(((rank-1)*15+1) TO (rank*15));'';" Keep up the good work! The next wave of ships has already been spotted on the long range sensors. ********************************"
2760 PRINT AT 21,10; PAPER 0; INK 7; FLASH 1;"Press Enter": PAUSE 0: CLS
2770 REM
2780 REM *** Next Wave ***
2790 REM
2800 PRINT AT 5,0;"******************************** The Federation Council would like to inform you that your ship will recieve new shields at your next Star Base stop. The last information received shows that the next wave of invading ships have improved their weapon range. Be Careful! ********************************": PRINT AT 21,10; PAPER 0; INK 7; FLASH 1;"Press Enter": PAUSE 0: CLS
2810 RESTORE 3630: IF b1>10 OR b2>10 THEN LET b1=5: LET b2=5
2820 FOR i=1 TO 19: READ a: LET l(i)=a: NEXT i: LET b1=b1-(rank-1): LET b2=b2+(rank-1): IF b1<1 THEN LET b1=1
2830 IF b2>8 THEN LET b2=8
2840 FOR i=1 TO (b1-1): LET l(i+10)=0: NEXT i: FOR i=(b2+1) TO 8: LET l(i+10)=0: NEXT i: LET msh=10+(rank-1)*2: LET mpt=5+rank-1: LET mph=5+rank-1
2850 LET score=score+1: GO TO 640
2860 REM
2870 REM *** All Done!***
2880 REM
2890 CLS : PRINT AT 2,0;"******************************** Congratulations! You have successfully defended the Federation against all of the invaders! Way to go hot shot! ********************************Total mission time: ";FN h();" seconds";';"********************************": PAUSE 0: GO TO 3510
2900 GO SUB 190: PRINT AT 16,0;TAB 31;" ": GO TO 1790
2910 REM
2920 REM *** Alien Weapons ***
2930 REM
2940 GO SUB 190: LET hit=0: LET dmg=0: FOR j=1 TO irng: GO SUB 220: LET i=g(j): IF ABS (f(i,2)-9)<=(3.85+rank) AND ABS (f(i,2)-16)<=(3.85+rank) THEN LET hit=hit+1: LET dmg=dmg+RND*rank/6+(hit-1)*rank/30: LET locx=FN c(f(i,1),f(i,2))+1: LET x3=FN d(locx): LET y3=FN e(locx): PLOT INK ik5;x3,y3: DRAW INK ik5;(x1-x3),(y1-y3): BEEP .3,45: INVERSE 1: PLOT x3,y3: DRAW (x1-x3),(y1-y3): INVERSE 0: PRINT AT f(i,1),f(i,2); INK ik5;"\f": PRINT AT 9,16; INK ik0;SCREEN$ (9,16)
2950 NEXT j: IF hit>0 THEN GO SUB 180: PRINT AT 19,0;"Damage Control: ";hit;" hits on shield": GO SUB 350
2960 LET sh=sh-dmg: IF sh<=0 THEN CLS : PRINT AT 10,0;"******************************** Your shields have gone down. Emergency procedures are in effect. Abandon ship!!! ********************************": GO TO 3940
2970 REM
2980 REM *** Alien Tactical ***
2990 REM
3000 IF hit>0 AND sh<5 AND sn<>0 THEN CIRCLE INVERSE 1;x1,y1,24*sn: IF sn<>0 THEN LET sn=sh*.6: GO SUB 360: CIRCLE x1,y1,24*sn
3010 LET ir1=1
3020 REM
3030 REM *** Ships 1 & 6
3040 REM
3050 FOR j=ir1 TO irng: GO SUB 220: LET i=g(j): IF l(i)>0 AND (i=1 OR i=6) AND (f(i,1)>=0 AND f(i,1)<=18) AND (f(i,2)>=0 AND f(i,2)<=30) THEN PRINT AT f(i,1),f(i,2); PAPER ik3;" ": LET f(i,1)=INT (f(i,1)+(7-SGN (RND-.5)*1-rank/2-f(i,1))/2): LET f(i,2)=INT (f(i,2)+(14-SGN (RND-.5)*1-rank/2-f(i,2))/2): PRINT AT f(i,1),f(i,2); INK ik5;"\f": LET xr=INT ((f(i,1)-9)/3)+d(1): LET xc=INT ((f(i,2)-16)/3)+d(2): LET l(i)=FN c(xr,xc)+1
3060 REM
3070 REM *** Ships 2 & 7 ***
3080 REM
3090 IF l(i)>0 AND (i=2 OR i=7) AND (f(i,1)>=0 AND f(i,1)<=18) AND (f(i,2)>=0 AND f(i,2)<=30) THEN PRINT AT f(i,1),f(i,2); PAPER ik3;" ": LET f(i,1)=INT (f(i,1)+(7-SGN (RND-.5)*1-rank/2-f(i,1))/2): LET f(i,2)=INT (f(i,2)+(18+SGN (RND-.5)*1+rank/2-f(i,2))/2): PRINT AT f(i,1),f(i,2); INK ik5;"\f": LET xr=INT ((f(i,1)-9)/3)+d(1): LET xc=INT ((f(i,2)-16)/3)+d(2): LET l(i)=FN c(xr,xc)+1
3100 REM
3110 REM *** Ships 3 & 8 ***
3120 REM
3130 IF l(i)>0 AND (i=3 OR i=8) AND (f(i,1)>=0 AND f(i,1)<=18) AND (f(i,2)>=0 AND f(i,2)<=30) THEN PRINT AT f(i,1),f(i,2); PAPER ik3;" ": LET f(i,1)=INT (f(i,1)+(13+SGN (RND-.5)*1+rank/2-f(i,1))/2): LET f(i,2)=INT (f(i,2)+(14+SGN (RND-.5)*1+rank/2-f(i,2))/2): PRINT AT f(i,1),f(i,2); INK ik5;"\f": LET xr=INT ((f(i,1)-9)/3)+d(1): LET xc=INT ((f(i,2)-16)/3)+d(2): LET l(i)=FN c(xr,xc)+1
3140 REM
3150 REM *** Ships 4 & 9 ***
3160 REM
3170 IF l(i)>0 AND (i=4 OR i=9) AND (f(i,1)>=0 AND f(i,1)<=18) AND (f(i,2)>=0 AND f(i,2)<=30) THEN PRINT AT f(i,1),f(i,2); PAPER ik3;" ": LET f(i,1)=INT (f(i,1)+(13+SGN (RND-.5)*1+rank/2-f(i,1))/2): LET f(i,2)=INT (f(i,2)+(18+SGN (RND-.5)*1+rank/2-f(i,2))/2): PRINT AT f(i,1),f(i,2); INK ik5;"\f": LET xr=INT ((f(i,1)-9)/3)+d(1): LET xc=INT ((f(i,2)-16)/3)+d(2): LET l(i)=FN c(xr,xc)+1
3180 REM
3190 REM *** Ships 5 & 10 ***
3200 REM
3210 IF l(i)>0 AND (i=5 OR i=10) AND (f(i,1)>=0 AND f(i,1)<=18) AND (f(i,2)>=0 AND f(i,2)<=30) THEN PRINT AT f(i,1),f(i,2); PAPER ik3;" ": LET f(i,1)=INT (f(i,1)+(9-SGN (RND-.5)*(3+rank/2)*RND-f(i,1))/2): LET f(i,2)=INT (f(i,2)+(16+(3+rank/2)*RND*SGN (RND-.5)-f(i,2))/2): PRINT AT f(i,1),f(i,2); INK ik5;"\f": LET xr=INT ((f(i,1)-9)/3)+d(1): LET xc=INT ((f(i,2)-16)/3)+d(2): LET l(i)=FN c(xr,xc)+1
3220 IF f(i,1)<>9 OR f(i,2)<>16 THEN GO TO 3280
3230 GO SUB 220: GO SUB 2650: LET f(i,1)=0: LET f(i,2)=0: LET f(i,3)=100: PRINT AT 9,16; INK ik0;"\a": LET j1=1: FOR k=1 TO irng: GO SUB 210: IF g(k)<>i THEN LET g(j1)=g(k): LET j1=j1+1
3240 NEXT k: LET irng=irng-1: LET ir1=j+1: GO SUB 180: GO TO 3050
3250 REM
3260 REM *** Ck Collision ***
3270 REM
3280 FOR k=1 TO js: GO SUB 220: LET k10=k+10: IF f(i,1)=f(g(k10),1) AND f(i,2)=f(g(k10),2) THEN GO TO 3350
3290 NEXT k
3300 REM
3310 REM *** Star Base Stats ***
3320 REM
3330 FOR k=1 TO jb: GO SUB 220: LET k10=k+20: IF f(i,1)=f(g(k10),1) AND f(i,2)=f(g(k10),2) THEN GO TO 3370
3340 NEXT k: GO TO 3430
3350 GO SUB 180: PRINT AT 19,0;"An enemy ship just flew into a star and was vaporized!": PRINT AT f(i,1),f(i,2); INK ik7;"\g": GO SUB 230: PAUSE 120: IF score=9 OR score=19 OR score=29 OR score=39 OR score=49 OR score=59 THEN PAUSE 60: GO TO 2710
3360 GO TO 3440
3370 GO SUB 180: IF g(k10)>=11 AND g(k10)<=15 THEN GO SUB 210: LET l(b1+10)=0: PRINT AT 20,0;"Star Base ";b1;" has been destroyed.": LET s(1)=0: LET s(2)=0: PAUSE 60: LET b1=b1+1
3380 IF g(k10)>=16 AND g(k10)<=20 THEN GO SUB 220: LET l(b2+10)=0: PRINT AT 20,0;"Star Base ";b2;" has been destroyed.": LET s(1)=0: LET s(2)=0: PAUSE 60: LET b2=b2-1
3390 LET jb=jb-1: IF l(19)=0 THEN LET b1=21: LET b2=21
3400 IF b2<b1 AND b1<>10 THEN LET b2=9: LET b1=9
3410 IF b1=10 THEN LET b2=21: LET b1=21
3420 IF b2=8 AND b1>=9 THEN LET b1=21: LET b2=21
3430 NEXT j: GO TO 3460
3440 LET score=score+1: LET b(i,1)=0: LET b(i,2)=0: LET f(i,1)=0: LET f(i,2)=0: LET l(i)=0: LET j1=1: FOR k=1 TO irng: IF g(k)<>i THEN LET g(j1)=g(k): LET j1=j1+1
3450 NEXT k: LET irng=irng-1: LET ir1=j+1: GO SUB 180: GO TO 3050
3460 RETURN
3470 STOP
3480 REM
3490 REM *** S T A R T ***
3500 REM
3510 CLEAR 61240: DIM t(15): DIM a$(704): DIM b$(1): DIM b(10,2): DIM c(21,2): DIM c$(512): DIM d(2): DIM d$(512): DIM e(10,2): DIM f$(20): DIM f(30,3): DIM g(30): DIM l(31): DIM p(10): DIM r$(90): DIM s(2): DIM s$(132): RESTORE
3520 REM
3530 REM *** M/C Routines ***
3540 REM
3550 DATA INT 17,81,239,33,0,64,1,0,16,237,176,201,17,0,64,33,81,239,1,0,16,237,176,201: FOR i=61241 TO 61264: READ j: POKE i,j: NEXT i
3560 REM
3570 REM *** UDG Data ***
3580 REM
3590 DATA INT 0,12,0,48,128,66,16,255,1,0,128,0,24,24,0,24,70,126,16,0,1,0,128,0,60,48,129,12,42,126,24,0,1,0,128,66,126,120,219,30,20,90,63,0,1,0,128,129,219,120,126,30,40,90,252,0,1,0,128,129,129,48,60,12,84,24,24,0,1,0,128,66,0,24,24,24,98,24,8,0,1,0,128,0,0,12,0,48,1,0,8,0,1,255,128,0
3600 REM
3610 REM *** Init Position ***
3620 REM
3630 DATA INT 7,7,7,7,7,25,25,25,25,25,80,150,282,406,464,394,262,138,272
3640 RANDOMIZE
3650 REM
3660 REM *** Init Variables ***
3670 REM
3680 LET qd=1: LET score=0: LET ik0=7: LET ik1=6: LET ik2=2: LET ik3=1: LET ik4=4: LET ik5=5: LET ik6=6: LET ik7=7: LET r$(1 TO 90)="Captain Commodore Rear Admiral Vice Admiral Admiral Fleet Admiral ": BORDER 1: PAPER 1: INK 7
3690 CLS : LET t(1)=0: LET t(2)=0: LET t(3)=0: LET t(4)=0: LET t(5)=0: LET t(6)=0: LET t(7)=15: LET t(8)=7: LET t(9)=16: LET t(10)=16: LET t(11)=16: LET t(12)=10: LET t(13)=16: LET t(14)=13
3700 REM
3710 REM *** Poke UDG ***
3720 REM
3730 FOR i=0 TO 7
3740 READ g: POKE USR "a"+i,g
3750 READ g: POKE USR "b"+i,g
3760 READ g: POKE USR "c"+i,g
3770 READ g: POKE USR "d"+i,g
3780 READ g: POKE USR "e"+i,g
3790 READ g: POKE USR "f"+i,g
3800 READ g: POKE USR "g"+i,g
3810 READ g: POKE USR "h"+i,g
3820 READ g: POKE USR "i"+i,g
3830 READ g: POKE USR "j"+i,g
3840 READ g: POKE USR "k"+i,g
3850 READ g: POKE USR "m"+i,g
3860 NEXT i
3870 INK 9: PRINT AT 21,13; PAPER 0; INK 7; FLASH 1;"Working": LET rank=1: PRINT AT 5,0;" Alert! Alert! Alert! Alert! ";''';" Star Cruisers have invaded the Federation's territory. You are Captain of the Star ship Strata-Gem. You must protect all of theFederation Star Bases. You are our last hope!";'';" Good Luck!"
3880 FOR i=1 TO 19: READ a: LET l(i)=a: NEXT i: FOR i=20 TO 30: LET cx=14+22*(RND-.5): LET rx=9+13*(RND-.5): LET l(i)=FN c(rx,cx)+1: NEXT i: LET l(31)=271: LET fuel=20: LET msh=10: LET sh=msh: LET msn=3: LET sn=msn: LET mpt=5: LET pt=mpt: LET mph=5: LET ph=mph: LET mwf=3
3890 LET wf=1: FOR i=11 TO 19: FOR j=20 TO 30: IF l(j)=l(i) THEN LET l(j)=l(j)+1
3900 NEXT j: NEXT i
3910 FOR i=1 TO 32: LET a$(i)="\h": NEXT i: FOR i=545 TO 576: LET a$(i)="\j": NEXT i: FOR i=0 TO 17: LET a$(FN c(i,0)+1)="\k": LET a$(FN c(i,31)+1)="\i": NEXT i: LET c$(1 TO 480)=a$(1 TO 480): FOR i=481 TO 512: LET c$(i)="\j": NEXT i: FOR i=20 TO 30: LET a$(l(i))="\g": NEXT i
3920 FOR i=1 TO 30: LET f(i,1)=0: LET f(i,2)=0: LET f(i,3)=0: NEXT i: LET move=1: LET dock=1: LET s(1)=0: LET s(2)=0: LET b1=1: LET b2=8: BEEP .25,30: POKE 23674,0: POKE 23673,0: POKE 23672,0: GO TO 3960
3930 CLS
3940 PRINT AT 0,0;"******************************** You have successfully destroyed";INT score;" enemy ships!";';"Thankyou for a good game! Press Enter to continue. ********************************Total mission time: ";FN h();" seconds";';"********************************": PAUSE 0: IF INKEY$=CHR$ 13 THEN CLS : GO TO 3510
3950 REM *** get ready ***
3960 CLS : PRINT AT 10,12; PAPER 2; INK 7; FLASH 1;"Alert!"
3970 SOUND 7,62;8,15
3980 FOR j=1 TO 3: FOR i=250 TO 120 STEP -5: SOUND 0,i: NEXT i: PAUSE 4: NEXT j
3990 PRINT AT 13,7; PAPER 2; INK 7; FLASH 1;"Battle Stations!"
4000 FOR j=1 TO 3: FOR i=250 TO 120 STEP -5: SOUND 0,i: NEXT i: PAUSE 4: NEXT j
4010 SOUND 8,0;9,0;10,0
4020 POKE 23674,0: POKE 23673,0: POKE 23672,0
4030 GO TO 640
4040 SAVE "Star Fleet"
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

