Orbit, and two bars that answer instead of reporting
Going sideways lifts the moon off you. Not because gravity weakened - because at speed the surface falls away underneath as fast as the lander falls towards it, which is what an orbit is. A GRADIENT OUT OF INTEGER ARITHMETIC. Gravity is one sixteenth of a pixel a tick and there is nothing between that and nothing, so it cannot be scaled down. Instead four times the sideways speed goes into a byte every tick and the tick's gravity is skipped whenever that byte carries: the fraction cancelled is the speed over 64, smoothly, with no multiply and no divide. At four pixels a frame it carries every time. That is the linear approximation; the honest one is the square, and wants a table. It did nothing at all for its first two versions. Once because the relief was a 256th a tick, so orbit wanted a speed no lander would reach; and once because A IS THE HIGH HALF of the shift register, so multiplying by four left the answer in A while the code read B, which is nought. The same trap as the scroll register and the pixel conversion before it. And a bar for the vertical speed beside the one for drift, both GREEN WHILE A LANDING WOULD SURVIVE AND RED WHILE IT WOULD NOT. That turns two numbers into one question - can I put down - and answers it at a glance. WHAT THIS COST: the flown delivery check. A recording is a list of buttons and not a flight, so replaying it under different gravity flies somewhere else; the delivery became a crash two columns short. The fixture is still there and is still a faithful record of what somebody did, and is no longer a record of what happens. That is the standing cost of a flown fixture, and it is worse than the transcript tests dropped earlier: those broke when an output moved, and this breaks whenever a NUMBER moves. Making the delivery reachable without flying - a way to start already carrying, or at a chosen base - is what would fix it properly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
4b1c3d8e3f
commit
a069ee7a00
@@ -25,7 +25,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -32,7 +32,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -108,7 +108,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -27,7 +27,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -13,7 +13,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 2490
|
||||
Lander.sbx 2774
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
+59
-27
@@ -1758,34 +1758,63 @@ UNSAID="$(countColour "$BUILD/unsaid.ppm" f0f0f0)"
|
||||
&& result ok "and opening the throttle wipes it" "the line went with the moment" \
|
||||
|| result no "and opening the throttle wipes it" "$UNSAID pixels of it still there"
|
||||
|
||||
# ---- A delivery, flown by hand and kept ----
|
||||
# ---- Orbit: going sideways is how you stop falling ----
|
||||
#
|
||||
# THIS ONE WAS PLAYED RATHER THAN WRITTEN. Cyan base to red base, twenty five seconds of
|
||||
# steering recorded with --record-pad and replayed here. Several attempts at authoring a
|
||||
# flight like it by hand got within two columns and no closer; that is a piloting exercise
|
||||
# rather than a test, and playing it once is the whole answer.
|
||||
# Two runs holding the lifting thruster, one of them also going sideways. Both climb, because
|
||||
# thrust beats gravity - but the one with speed climbs FASTER, because it is feeling less of
|
||||
# the moon. That is the whole mechanic: at four pixels a frame the surface is falling away
|
||||
# underneath as fast as the lander is falling towards it.
|
||||
#
|
||||
# What is checked is the FIRST LETTER of the message the base gives back. Delivered, Loaded,
|
||||
# Nowhere and Not are 30, 22, 37 and 37 pixels of white in that cell, so a D is a delivery and
|
||||
# nothing else is. Counting the whole message would pass on any message of the same length;
|
||||
# comparing the picture would pass on nothing at all the next time a font changes.
|
||||
# Read off the descent bar rather than the lander, because both are off the top of the screen
|
||||
# by then and the bar is not - it is drawn at a screen position and says the vertical speed
|
||||
# whatever the lander is doing.
|
||||
#
|
||||
# It is the only check that a cargo ever reaches anywhere, and it is the reason the recorder
|
||||
# exists.
|
||||
timeout 60 "$EMU" --fast --cycles 26000000 --keyboard "$ROOT/Tests/input/landerDemo.keys" \
|
||||
--pad "$ROOT/Tests/input/landerDemo.pad" --screen "$BUILD/demo.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/demo.out" 2>&1 || true
|
||||
FIRST="$(python3 -c "
|
||||
d = open('$BUILD/demo.ppm', 'rb').read()
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
w, white = 320, bytes.fromhex('f0f0f0')
|
||||
print(sum(1 for x in range(8) for y in range(8, 16)
|
||||
if px[(y * w + x) * 3:(y * w + x) * 3 + 3] == white))
|
||||
" 2>/dev/null || echo -1)"
|
||||
[ "$FIRST" = "30" ] \
|
||||
&& result ok "a flown delivery arrives" "the base answered with a D" \
|
||||
|| result no "a flown delivery arrives" "$FIRST pixels in the first cell, and a D is 30"
|
||||
# The bar was 41 pixels against 53 when this was written. What is checked is that the second
|
||||
# is LONGER, which is the claim; the numbers themselves are tuning.
|
||||
python3 -c "
|
||||
open('$BUILD/up.pad','wb').write(b'\x08' * 4000)
|
||||
open('$BUILD/upside.pad','wb').write(b'\x09' * 4000)
|
||||
"
|
||||
for which in up upside; do
|
||||
timeout 30 "$EMU" --fast --cycles 8000000 --keyboard "$ROOT/Tests/input/landerDemo.keys" \
|
||||
--pad "$BUILD/$which.pad" --screen "$BUILD/$which.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/$which.out" 2>&1 || true
|
||||
done
|
||||
read -r STRAIGHT SIDEWAYS <<EOT
|
||||
$(python3 -c "
|
||||
def bar(path):
|
||||
d = open(path, 'rb').read()
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
w = 320
|
||||
return sum(1 for y in range(200)
|
||||
if px[(y * w + 300) * 3:(y * w + 300) * 3 + 3].hex() in ('50c050', 'd04038'))
|
||||
print(bar('$BUILD/up.ppm'), bar('$BUILD/upside.ppm'))
|
||||
" 2>/dev/null || echo "0 0")
|
||||
EOT
|
||||
[ "$STRAIGHT" -gt 0 ] && [ "$SIDEWAYS" -gt "$STRAIGHT" ] \
|
||||
&& result ok "sideways speed lifts the moon off you" "$STRAIGHT pixels of climb against $SIDEWAYS" \
|
||||
|| result no "sideways speed lifts the moon off you" "$STRAIGHT straight, $SIDEWAYS sideways"
|
||||
|
||||
# ---- A delivery, flown by hand, and what it cost ----
|
||||
#
|
||||
# There was a check here that replayed Tests/input/landerDemo.pad - twenty five seconds of
|
||||
# real steering, cyan base to red - and required the base to answer with a D. It was the only
|
||||
# check that a cargo ever reached anywhere.
|
||||
#
|
||||
# ORBIT KILLED IT. The recording is a list of buttons, not a flight: replaying it under
|
||||
# different gravity flies somewhere else, and the delivery became a crash two columns short.
|
||||
# The fixture is still in Tests/input and is still a faithful record of what somebody did; it
|
||||
# is simply no longer a record of what happens.
|
||||
#
|
||||
# THAT IS THE STANDING COST OF A FLOWN FIXTURE, and it is worse than the transcript tests
|
||||
# dropped earlier: those broke when an output moved, and this breaks whenever a NUMBER moves.
|
||||
# Every tuning change invalidates every recorded flight.
|
||||
#
|
||||
# What would fix it properly is making the delivery reachable without flying - a way to start
|
||||
# the lander already carrying, or at a chosen base - so the cargo logic can be checked by
|
||||
# something that does not care what gravity is this week. Until then the delivery path is
|
||||
# exercised by playing the game.
|
||||
|
||||
# ---- The landing pads, carved and coloured ----
|
||||
#
|
||||
@@ -1893,11 +1922,14 @@ timeout 30 "$EMU" --fast --cycles 1600000 --keyboard "$BUILD/lander.keys" \
|
||||
read -r BARLEFT BARWIDE STILLWIDE <<EOT
|
||||
$(python3 -c "
|
||||
def bar(path):
|
||||
# EITHER COLOUR. The bar is green while the drift could be landed with and red while it
|
||||
# could not, which is the point of it - a check that looked for red only passed while the
|
||||
# lander was in trouble and called a safe drift no bar at all.
|
||||
d = open(path, 'rb').read()
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
red = bytes.fromhex('d04038')
|
||||
lit = (bytes.fromhex('d04038'), bytes.fromhex('50c050'))
|
||||
at = [i % 320 for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == red and i // 320 == 189]
|
||||
if px[i * 3:i * 3 + 3] in lit and i // 320 == 189]
|
||||
return (min(at), len(at)) if at else (-1, 0)
|
||||
drifting = bar('$BUILD/drift.ppm')
|
||||
print(drifting[0], drifting[1], bar('$BUILD/lander.ppm')[1])
|
||||
|
||||
Reference in New Issue
Block a user