--- title: "Moon Base" id: 57353 type: "computer_media" slug: "moon-base" url: "http://localhost/computer_media/moon-base/" markdown_url: "http://localhost/computer_media/moon-base.md" published_at: "2024-10-04T08:46:54+00:00" modified_at: "2026-03-30T21:18:19+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/201_MB.png" excerpt: "Guide a lunar lander to a precise touchdown using thrust and drift inputs — fuel, velocity, height, and a random landing zone keep every descent unique." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Tim Hartnell" slug: "tim-hartnell" taxonomy: "indiv" url: "http://localhost/indiv/tim-hartnell/" - name: "Tony Willing" slug: "tony-willing" taxonomy: "indiv" url: "http://localhost/indiv/tony-willing/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56735 title: "Timex Sinclair Public Domain Library Tape 1004" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1004/" media_type: "Program" programmers: - name: "Tim Hartnell" slug: "tim-hartnell" taxonomy: "indiv" url: "http://localhost/indiv/tim-hartnell/" - name: "Tony Willing" slug: "tony-willing" taxonomy: "indiv" url: "http://localhost/indiv/tony-willing/" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/201_MB.png" media_type_tags: "Game" --- # Moon Base Moonbase is a lunar-lander simulation in which the player guides a spacecraft to a safe touchdown on the Moon’s surface by entering thrust and drift values each turn. The program tracks velocity, fuel, height, and elapsed time, updating a text-mode display that uses block-graphic characters to draw the lunar terrain and a small lander sprite. A random landing-zone marker (variable M) is placed on the surface each game, and the player must bring the craft down within five units of it horizontally while meeting speed and altitude constraints defined in line 20. Inverse-video characters are used extensively for crash, crater, and success messages, and an infinite PRINT/GOTO loop at lines 362–363 and 402–410 locks the screen on the terminal message after each outcome. *** ## Program Analysis ### Program Structure The program initialises variables at lines 420–510 and then jumps to the main flight loop at line 60 via `GOTO 700`. The flight loop (lines 50–340) processes one turn per iteration: it scales thrust input, updates velocity and height physics, draws the scene, prints the instrument panel, and solicits new `A` (thrust) and `B` (drift) values before looping back to line 50. 1. **Initialisation** – lines 420–510: sets height `H`, fuel `F`, time `T`, lander position `Z`, thrust `A`, drift `B`, landing-zone marker `M`, velocity `V`, and previous sprite position `W`/`X`. 2. **Physics update** – lines 50–90: thrust is scaled, time advances, velocity and height are recalculated, and fuel is consumed. 3. **Condition check** – lines 20–40 (called as a GOSUB at line 100): tests for successful landing or escape velocity. 4. **Display** – lines 160–210: erases the old sprite, draws the new lander at the computed screen position, and renders the terrain strip. 5. **Instrument panel & input** – lines 280–340: prints velocity, fuel, time, and height, then waits for thrust and drift inputs. 6. **Outcome screens** – lines 350–410: separate branches for crash, successful landing, and escape velocity, each ending in an infinite loop. ### Physics Model The physics are simplified but functional. Thrust input `A` is first divided by 7 (line 50), then used in a cubic expression `A**3` to modify velocity (line 70), producing non-linear sensitivity to large thrust values. Horizontal position `H` is updated by adding the current velocity plus a random perturbation (line 80). Fuel consumption (line 90) depends on both thrust magnitude `ABS(A)` and drift magnitude `ABS(B/5)` scaled by a random factor, making aggressive maneuvering costly. ### Landing Condition The subroutine starting at line 20 checks four simultaneous conditions for a successful landing: - `H < 50` — low enough altitude - `V < 20` — downward velocity not excessive - `V > -15` — not moving upward too fast - `ABS(Z-M) < 5` — horizontal position within 5 units of the random landing marker `M` If `H > 1750` (line 30), the craft has reached escape velocity and branches to line 400. Otherwise the subroutine returns normally (line 40). ### Display Techniques The lander sprite is a four-character string printed using `PRINT AT`. The previous position is erased by printing spaces at the stored coordinates `W`,`X` before drawing the new position (lines 160–190). Screen row is derived from `16-U` where `U=H/100`, mapping height to a row index. The lunar terrain at line 210 is a single long `PRINT AT 16,0` statement containing a dense sequence of block-graphic escape sequences (`\.:, \::, \''`, etc.). A `TO M-1` substring expression trims the string to end just before the landing-zone marker column, providing a visual gap at the target. ### Key Variables | Variable | Role | | --- | --- | | `H` | Height (initialised at 1450) | | `V` | Vertical velocity | | `F` | Fuel remaining | | `T` | Elapsed time | | `A` | Thrust input (player-supplied each turn) | | `B` | Drift input (player-supplied each turn) | | `Z` | Horizontal screen position of lander | | `M` | Random landing-zone column marker | | `W`,`X` | Previous sprite row and column for erase | | `U` | Derived screen row (`H/100`) | ### Notable Techniques and Idioms - **Absolute-value input guard** – line 302 converts any negative thrust input to positive with `LET A=A*-1`, preventing the player from exploiting negative thrust. - **Delay loops** – lines 332–333 and 352–353 use `FOR/NEXT` loops with no body as busy-wait delays, giving the player time to read crash or success information before the screen changes. - **Infinite outcome loops** – lines 362–363 and 402–410 use `PRINT` followed by `GOTO` back to the same `PRINT` line, continuously scrolling the terminal message to fill the screen and prevent further input. - **Substring for terrain** – the `( TO M-1)` slice on the terrain string at line 210 is an elegant way to create a variable-width gap at the landing-zone position without conditional branching. - **Landing rating formula** – line 380 computes a score as `100*(30-INT ABS V)+INT V`, rewarding a slow touchdown with a higher rating. ### Bugs and Anomalies - Lines 140 and 150 are absent from the listing, suggesting they were deleted during revision; the jump from line 130 to 160 is harmless but leaves a visible gap. - The `GOSUB 20` at line 100 calls code that begins with an `IF` at line 20; if neither condition triggers, execution falls through to line 30, then 40 (`RETURN`). This works correctly but relies on the fall-through behaviour rather than an explicit jump. - Lines 710–740 (`STOP`, `CLEAR`, `SAVE`, `RUN`) are never reachable during normal play because all outcome branches enter infinite loops; they appear to be housekeeping lines intended to be run manually from the editor. - The escape-velocity branch (line 400) prints a message and then falls into the infinite loop at lines 402–410 via natural fall-through, which is intentional but unconventional. ## Source Code ``` 0 REM "MOONBASE" BY TIM HARTNELL REVISIONS BY TONY WILLING 5 CLS 10 GOTO 420 20 IF H<50 AND V<20 AND V>-15 AND ABS (Z-M)<5 THEN GOTO 370 30 IF H>1750 THEN GOTO 400 40 RETURN 50 LET A=A/7 60 LET T=T+4+INT (RND*2+1) 70 LET V=V+A**3-12-3*RND 80 LET H=H+V-20+10*RND 90 LET F=F-(ABS (A)+ABS (B/5)*6*RND) 100 GOSUB 20 110 IF H<20 OR F<5 THEN GOTO 350 120 LET U=H/100 130 LET Z=Z+B/2+2-RND*3 160 PRINT AT W,X;" " 170 PRINT AT 16-U,Z+1;"\ .\''\. " 180 LET W=16-U 190 LET X=Z+1 210 PRINT AT 16,0;"\..\;;\!!\. \.'\.'\'.\..% \:'\:.\.:\:'\:'\.'\':\!!\;;\:.\.:\.:"( TO M-1);"\.'\..\,,\..\'." 280 PRINT AT 17,0;"VEL: ";INT V;" ","FUEL: ";INT F;" ","TIME: ";INT T;" ","HEIGHT: ";INT H;" " 290 PRINT "THRUST? "; 300 INPUT A 302 IF A<0 THEN LET A=A*-1 310 PRINT A;" ","DRIFT? "; 320 INPUT B 330 PRINT B 332 FOR K=1 TO 85 333 NEXT K 335 PRINT AT 19,23;" " 340 GOTO 50 350 PRINT "%C%R%A%S%H\ '\ '%S%P%E%E%D ";ABS V," "; 352 FOR K=1 TO 90 353 NEXT K 354 CLS 360 PRINT "%A% %C%R%A%T%E%R% ";INT (ABS V*(RND+1));"% %F%E%E%T% %D%E%E%P% %W%I%L%L% %B%E% % %N%A%M%E%D% %I%N% %Y%O%U%R% %H%O%N%O%R% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % " 361 PRINT "%T%H%E% %N%E%X%T%-%O%F%-%K%I%N% %W%I%L%L% %B%E% %N%O%T%I%F%I%E%D" 362 PRINT " " 363 GOTO 362 380 PRINT "%S%U%C%C%E%S%S%F%U%L% %L%A%N%D%I%N%G\@@%R%A%T%I%N%G ";100*(30-INT ABS V)+INT V;"\##"; 390 GOTO 402 400 PRINT "%Y%O%U% %H%A%V%E% %R%E%A%C%H%E%D% %E%S%C%A%P%E% %V%E%L%O%C%I%T%Y" 402 PRINT " " 410 GOTO 402 420 LET H=1450 430 LET F=827+50*RND 440 LET T=0 450 LET Z=15*RND 460 LET A=1 470 LET B=0 480 LET M=19*RND 490 LET V=0 500 LET W=0 510 LET X=0 700 GOTO 60 710 STOP 720 CLEAR 730 SAVE "1020%1" 740 RUN ```