Landing pads, carved rather than looked for

A random walk does not leave flat ground and a lander wants some. Four
pads are cut into the moon after it is generated, each four columns
levelled to whatever height its first column happened to have - so they
sit in the landscape rather than on a shelf above it. The moon decides
where they are; this only decides that they are flat.

Searching for flat spots was the alternative and it can fail, which means
a fallback that carves anyway - the carving, plus a search nobody needed.

They are marked by an ATTRIBUTE and not a tile of their own, which costs
no art at all: a nibble is added to every index in a tile, so one solid
block is grey moon or a cyan pad depending on the byte beside it.

Which columns are pads is an array, because asking has to be one lookup.
Four comparisons per column per row is 12,800 of them for one screen, and
the landing verdict asks the same question again.

THE LANDER STARTS ABOVE ONE, because that is where a porter's day begins.
Starting in the middle of nowhere meant a straight descent landed in the
middle of nowhere, which is a fine thing to be able to do and a poor thing
to have to.

That change cost the crash test its teeth, and the way it did is worth
keeping. It held nothing at all and let the lander fall - and a short drop
onto the high ground of the base you started above is survivable, which is
correct, and left the test saying nothing. It holds Right now: lateral
speed has no limit and nothing slows it, so a slide always ends badly
however the rest is tuned.

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 11:45:30 -04:00
co-authored by Claude Opus 5
parent 6073086584
commit 7257ad369c
18 changed files with 171 additions and 22 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -15,7 +15,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -32,7 +32,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -22,7 +22,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -22,7 +22,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -1,6 +1,6 @@
CosmOS
> Lander
Down safely.
Down safely at a base.
finished
> exit
halted
+1 -1
View File
@@ -1,6 +1,6 @@
CosmOS
> Lander
Down safely.
Down safely at a base.
finished
> exit
halted
+1 -1
View File
@@ -108,7 +108,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -27,7 +27,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -15,7 +15,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -13,7 +13,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
+1 -1
View File
@@ -22,7 +22,7 @@ Mode.sbx 48
Flip.sbx 173
Sprite.sbx 442
Depth.sbx 672
Lander.sbx 1756
Lander.sbx 2108
Pad.sbx 264
Crash.sbx 632
vars.script 50
Binary file not shown.
+1
View File
@@ -0,0 +1 @@

+11 -6
View File
@@ -1014,14 +1014,19 @@ cosmosSprite | CosmOS/Source/cosmos.asm | run | -
padTest | testPrograms/padTest.asm | run | - | - | - | - | padTest.pad
# ---- Lunar Porter, arriving ----
#
# The same program, the same keys, and two different controllers. One holds nothing at all and
# the lander falls the whole way; the other pulses the thruster six frames in sixteen and
# brings it down slowly enough to survive.
# The same program, the same keys, and two different controllers. One holds Right and never
# stops, so it arrives sliding; the other pulses the thruster six frames in sixteen and comes
# down slowly enough to survive.
#
# WHAT SAYS WHICH IS THE SPEED AT THE MOMENT IT ARRIVES, and nothing else - the terrain is the
# same terrain, from the same fixed seed, so the two runs differ only in what was held. That
# is the whole of the game's difficulty in two fixtures.
cosmosLanderCrash | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerFall.pad
# same terrain, from the same fixed seed, so the two runs differ only in what was held.
#
# SLIDING RATHER THAN FALLING, and the difference matters. The crash fixture used to hold
# nothing at all, and stopped crashing the day the lander began its day above a base: a short
# drop onto high ground is survivable, which is correct and made the test say nothing. Lateral
# speed has no limit and nothing slows it, so a slide always ends badly however the rest is
# tuned.
cosmosLanderCrash | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerSlide.pad
cosmosLanderSoft | CosmOS/Source/cosmos.asm | run | - | 60000000 | disks/cosmos.img | lander.keys | landerSoft.pad
# ---- And the same landing, flown from the second controller ----
#
+15
View File
@@ -1707,6 +1707,21 @@ EOT
&& result ok "a held thruster keeps lifting" "row $EARLY early, row $LATE later" \
|| result no "a held thruster keeps lifting" "row $EARLY early, row $LATE later"
# ---- The landing pads, carved and coloured ----
#
# A random walk does not leave flat ground and a lander wants some, so four pads are carved
# after the moon is made. They are marked in the picture by an ATTRIBUTE rather than a tile of
# their own: the same solid block in scheme six, which costs no art at all, because a nibble
# is added to every index in the tile and one block is grey moon or cyan pad depending on the
# byte beside it.
#
# Checked as a multiple of thirty two pixels, because a pad is four cells wide and one row
# tall - so whatever is visible of them, it comes in whole cells.
PADS="$(countColour "$BUILD/lander.ppm" 50c0c8)"
[ "$PADS" -gt 0 ] && [ $(( PADS % 8 )) = 0 ] \
&& result ok "the moon has pads carved into it" "$PADS pixels of them, in whole cells" \
|| result no "the moon has pads carved into it" "$PADS pixels, which is not whole cells of pad"
# ---- The fuel gauge, in the window ----
#
# A bar in the window layer, which is at a SCREEN position - so the moon turning underneath it