Cargo: bases with names, and a landing that is not an ending

Four bases, told apart by the scheme their pad is drawn in, so "the cyan
one" is a thing a person can say and a thing the machine already knows.
Yellow is missing on purpose: it is the lander, and a base the same colour
as the thing landing on it would be a poor joke.

Land empty at a base and it loads cargo for the base ACROSS THE MOON, two
along - so the pairs are cyan with red and green with blue, and the
wrapping surface is a route rather than scenery. Land carrying at the
right one and it takes the cargo and pays eighty units of fuel. Land at
the wrong one and nothing happens, which is why the destination will want
to be on the screen.

A LANDING NO LONGER ENDS THE RUN. The lander rests where it is, exactly on
the surface with both speeds zeroed, until the throttle opens again -
which is the only way to stop being landed. Gravity does not pull on
something already sitting down, and a base does not hand out cargo sixty
times a second to a lander parked on it.

The pad array holds the base's number plus one rather than a flag. Nought
still means no pad, so it is still one lookup, and a flag would have to be
followed by "and which of the four" - the same walk done twice for an
answer already in hand.

Pads are eight columns rather than four. Four was 32 pixels in a moon 1024
round, which is a target somebody flying by feel misses over and over.

WHAT IS NOT COVERED, and why: the delivery and wrong-base paths need a
lander flown from one base to another, and hand-authoring a recorded pad
input that hits an eight column pad across a 128 column moon is a piloting
exercise rather than a correctness one. Several attempts got within two
columns. Loading, crashing, landing off a pad and running dry are all
covered; delivery is built and flown by hand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-03 12:04:27 -04:00
co-authored by Claude Opus 5
parent 7257ad369c
commit bfb515e23b
14 changed files with 240 additions and 51 deletions
+221 -30
View File
@@ -271,14 +271,29 @@ carveColumn:
POPA
SETD.1 IsPad
DPUA.1
INIA 0x01
; ---- WHICH base, and not merely that there is one ----
;
; The number plus one, so nought still means no pad and the array is still one lookup. A
; flag would have to be followed by "and which of the four", which is the same walk done
; twice for an answer that was already in hand.
INIA 0d4
SETD.0 PadsLeft
LDB.0
CCF
SUB
MVQA ; Four less what is left to carve, which counts up from nought.
INCA
STA.1
SETD.1 PadWide
LDA.1
INCA
STA.1
INIB 0d4
INIB 0d8 ; ---- Eight columns, not four ----
;
; Four was 32 pixels of pad in a moon 1024 round, which is a
; target somebody flying by feel misses over and over. Eight is
; still small and is somewhere a person can aim at.
CCF
SUB
BNQ carveColumn
@@ -372,10 +387,13 @@ drawSurface:
DPUA.1
LDA.1
BRA drawGround ; Not a pad, so it is ordinary moon.
DECA ; Back to the base's own number.
SETD.1 PadColour
DPUA.1
INIA 0xC8
OUTA 0xE9
INIA 0x06
OUTA 0xE9 ; Scheme six, which is cyan against everything else out there.
OUTA 0xE9 ; The solid block again.
LDA.1
OUTA 0xE9 ; And this base's scheme, which is the whole of its name.
BRI drawNextCell
drawSky:
RSTA ; A is still this column's height, from the comparison above.
@@ -638,9 +656,14 @@ fall:
LDA.1
SETD.1 FallTick
STA.1
; Gravity does not pull on a lander that is already sitting on the ground.
SETD.0 Landed
LDA.0
BNA fallResting
SETD.0 SpeedDown
SETD.1 Gravity
CALL addWord
fallResting:
; ---- And whatever is being leaned on, on the same tick ----
;
@@ -657,6 +680,9 @@ fall:
BRQ fallNotUp
CALL takeFuel
BRQ fallNotUp ; Nothing in the tank, so nothing out of the engine.
RSTA
SETD.0 Landed
STA.0 ; Lifting off, which is the only way to stop being landed.
SETD.0 SpeedDown
SETD.1 PadUp
CALL addWord
@@ -979,6 +1005,13 @@ touchdown:
SUB
BRC touchdownDone ; Borrowed: the feet are still above the surface.
; Already sitting on it, so there is nothing new to say. Without this the arrival happens
; again every frame the lander rests, which is a base handing out cargo sixty times a
; second.
SETD.0 Landed
LDA.0
BNA touchdownDone
; ---- Arrived. Now, how ----
;
; Both speeds, and both have to be gentle. A landing that was soft downwards and sliding
@@ -1010,22 +1043,34 @@ touchdown:
SUB
BNC touchdownCrash
; ---- Down safely, and whether it was anywhere useful ----
; ---- Down safely, which is not the end of anything ----
;
; A pad is where a base is, and the rest of the moon is somewhere a lander can survive
; arriving at and do nothing about. The difference is one lookup, because the carving wrote
; an array rather than leaving four comparisons to be done again here.
SETD.1 IsPad
SETD.0 LandColumn
LDA.0
DPUA.1
LDA.1
BRA touchdownNowhere
SETD.0 AtBaseText
BRI touchdownStop
touchdownNowhere:
SETD.0 LandedText
BRI touchdownStop
; The view settles, the arrival is dealt with, and the lander sits where it is until
; somebody opens the throttle again. A landing used to stop the program, which is fine for a
; game about landing once and wrong for one about carrying things between four places.
RSTA
OUTA 0x37
OUTA 0x38
CALL arrive
CALL waitKey
; Sitting still, exactly on the surface. Both speeds go, because a lander that kept a
; hundredth of a pixel a frame would drift off its pad while nobody was looking.
RSTA
SETD.0 SpeedDown
STA.0
INCD.0
STA.0
SETD.0 SpeedAcross
STA.0
INCD.0
STA.0
CALL restOnSurface
INIA 0x01
SETD.0 Landed
STA.0
RET
touchdownCrash:
SETD.0 CrashedText
touchdownStop:
@@ -1051,19 +1096,136 @@ touchdownStop:
; The verdict was printed and the program then left immediately, taking the screen with it -
; so the one thing anybody wanted to see, the lander sitting on the ground it had just
; arrived at, was replaced by a shell prompt before it could be looked at.
touchdownWait:
INA 0x01
INIB 0x01 ; READY
AND
BRQ touchdownWait
INA 0x00
CALL waitKey
RSTA
SETD.1 Flying
STA.1 ; Which ends the loop, and the program tidies up as it always did.
touchdownDone:
RET
; A key, asked for rather than waited on, so one already pressed counts.
waitKey:
INA 0x01
INIB 0x01 ; READY
AND
BRQ waitKey
INA 0x00
RET
; ---- Put down exactly on the ground ----
;
; The feet are the top plus eight, so the top is the surface less eight - times sixteen, which
; is what the position is measured in. Three turns left of the shift register with the pixels
; in the low half, and the answer needs both halves because a screen is taller than 255
; sixteenths.
restOnSurface:
SETD.0 SurfaceAt
LDA.0
INIB 0d8
CCF
SUB
MVQB
RSTA
SHL
SHL
SHL
SHL ; Four turns, which is times sixteen.
SETD.0 DownHigh
STA.0
RSTA
CCF
ADD
MVQA
SETD.0 DownLow
STA.0
RET
; ---- What a base does when a lander arrives ----
;
; Empty and at a base: it hands over cargo for the base ACROSS THE MOON, two along, so the
; pairs are cyan with red and green with blue. Carrying and at the right base: it takes the
; cargo and pays in fuel. Carrying and at the wrong one: nothing, which is the whole reason
; the destination is on the screen.
arrive:
SETD.1 IsPad
SETD.0 LandColumn
LDA.0
DPUA.1
LDA.1
BRA arriveNowhere
DECA
SETD.1 AtBase
STA.1
SETD.0 Carrying
LDA.0
BRA arriveLoad
; Carrying something. Is this where it goes?
DECA
LDB.1 ; DP1 is still AtBase, from storing it above.
CCF
SUB
BNQ arriveWrong
RSTA
STA.0 ; And DP0 is still Carrying, from reading it.
CALL payFuel
SETD.0 DeliveredText
SWI osPrintString
BRI arriveSaid
arriveLoad:
; Two along, round a moon of four bases, which is the far side of it.
SETD.1 AtBase
LDA.1
INIB 0x02
CCF
ADD
MVQA
INIB 0x03
AND
MVQA
INCA ; Plus one, so nought can go on meaning nothing.
SETD.0 Carrying
STA.0
SETD.0 LoadedText
SWI osPrintString
BRI arriveSaid
arriveWrong:
SETD.0 WrongText
SWI osPrintString
BRI arriveSaid
arriveNowhere:
SETD.0 LandedText
SWI osPrintString
arriveSaid:
INIA 0x0A
OUTA 0x00
RET
; ---- Paid ----
;
; Eighty units, and a tank that will not take more than it holds. The carry from a byte's
; worth of adding is what says it went past, which is the same flag a sixteen bit sum uses to
; run one half into the other.
payFuel:
SETD.0 Fuel
LDA.0
INIB 0d80
CCF
ADD
BRC payFuelFull
STQ.0
RET
payFuelFull:
INIA 0xFF
STA.0
RET
; ---- Sums ----
;
; DP0 names the two byte value being changed, low half first, and DP1 the one being added to
@@ -1290,6 +1452,19 @@ IsPad:
PadTable:
0d8 0d40 0d72 0d104 ; Four bases, evenly round a moon 128 columns about.
; ---- Their names, which are colours ----
;
; A base is told from a base by the scheme its pad is drawn in, so "the cyan one" is a thing a
; person can say and a thing the machine already knows. Yellow is missing on purpose: it is
; the lander, and a base the same colour as the thing landing on it would be a poor joke.
;
; Cargo goes to the base ACROSS THE MOON, two along, so the pairs are cyan with red and green
; with blue. That is what makes the wrapping surface a route rather than scenery.
PadColour:
0d2 0d6 0d4 0d1 ; Green, cyan, blue, red.
PadNames:
0x00 ; Room kept: the messages name colours in words below.
PadsLeft:
0x00
PadWide:
@@ -1298,11 +1473,27 @@ PadHeight:
0x00
LandColumn:
0x00
AtBase:
0x00
; ---- What is aboard, and whether the feet are down ----
;
; Carrying is the destination base plus one, so nought means an empty hold and the number is
; still one byte. Landed is what stops a base handing out cargo sixty times a second while a
; lander sits on it.
Carrying:
0x00
Landed:
0x00
LandedText:
"Down safely, in the middle of nowhere."
AtBaseText:
"Down safely at a base."
"Down in the middle of nowhere. Nothing here."
LoadedText:
"Loaded. Take it to the base across the moon."
DeliveredText:
"Delivered. Eighty units of fuel."
WrongText:
"Not the base this cargo is for."
CrashedText:
"Crashed."