Files
Syplheed-Reborn/tools/re-capture/mission_run.sh
Claude (auto-RE) f4d59c5783 re: Stage 02 is lost at ~11 minutes, and the pilot's survival rule is what guarantees it
First session whose deliverable was the mission's ENDING rather than a
measurement (mission_run.sh, 500 s, hull of every entity at 2 Hz). The ACROPOLIS
is untouched to t=170 s then falls at ~53 HP/s with no let-up, reaching zero at
t=640-720 s — so "no mission completed" is not an artifact of the 240 s
time-boxes, and not of the 600 s cap on a blocking tool call. A longer session
would only watch the loss arrive.

Attributing the damage by co-presence, exactly two classes are ever near the
asset: e007 turrets (8483) and e010 bombers (8334). pilot.py treats turrets as
keep-out zones at 2500 units and never as targets — the rule that made it
survive — so roughly half the escort damage comes from the one class it is
designed to avoid. Survival and the objective are in direct conflict and the
pilot resolves it entirely for survival: WARSHIPS 0000, WARPLANES 0009,
REMAINING OB rising 004 -> 008, our hull untouched at 1500/1500 with 120
missiles spent. That is unspent risk budget, not a good run.

Also corrects launch_mission.sh: a harness-tracked BACKGROUND task does not keep
the display alive (lost 11 s in, at the turn boundary) — the
one-blocking-foreground-call rule stands.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 20:57:43 +00:00

61 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Attempt to COMPLETE a mission and record how it ends.
#
# Every previous flight session was time-boxed to 240 s to measure something
# (escort hull, lethality, ship placement) and none ever reached a mission
# outcome — "no mission completed" has been the standing open item. Unit
# definitions are instantiated per stage, so story progress is the only thing
# that grows unit coverage past 21/110, and that needs a WIN, not a survival.
#
# So this run is deliberately long and its only deliverable is the ENDING:
# screenshots throughout, every entity's hull sampled, and the pilot log kept
# whole (never tail-piped — a frozen log tail is what mission-end looks like
# from outside, and tailing throws away the transition).
#
# Runs as ONE tracked background task with Xvfb/openbox/xenia as plain nohup
# children — see docs/re/session-lifetime notes; do NOT setsid anything.
#
# Usage: mission_run.sh [flight_seconds] [tag]
set -u
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98
export PYTHONPATH=/sylph-home/.local/lib/python3.12/site-packages
SD="$(cd "$(dirname "$0")" && pwd)"
SECS="${1:-900}"
TAG="${2:-mission}"
SHOTS=/sylph-home/re/shots
OUT="/sylph-home/re/$TAG"
mkdir -p "$SHOTS" "$OUT"
"$SD/launch_mission.sh" fly || { echo "BOOT FAILED"; exit 1; }
python3 "$SD/entities2.py" self 0x130 "$OUT/cfg.json" || { echo "BIND FAILED"; exit 1; }
echo "=== initial entity table ==="
python3 "$SD/mission_state.py" scan "$OUT/cfg.json"
# A screenshot every 30 s for the WHOLE run: the outcome card (MISSION COMPLETE
# / GAME OVER) is on screen only briefly, so sampling must not stop early.
( n=$(( SECS / 30 + 4 ))
for i in $(seq 1 "$n"); do
printf '%s SHOT %03d\n' "$(date +%s)" "$i" >> "$OUT/shots.log"
screenshot "$SHOTS/$TAG-$(printf %03d "$i").png" >/dev/null 2>&1
sleep 30
done ) &
SHOTTER=$!
date +%s > "$OUT/t0"
python3 "$SD/mission_state.py" watch "$OUT/cfg.json" "$SECS" 2 "$OUT/mission.jsonl" \
> "$OUT/mission.log" 2>&1 &
WATCHER=$!
python3 "$SD/pilot.py" "$OUT/cfg.json" "$SECS" > "$OUT/pilot.log" 2>&1
PILOT_RC=$?
wait $WATCHER 2>/dev/null
kill $SHOTTER 2>/dev/null
screenshot "$SHOTS/$TAG-end.png" >/dev/null 2>&1
cp -f "$SHOTS/$TAG-end.png" "$OUT/end.png" 2>/dev/null
echo "PILOT_RC=$PILOT_RC"
echo "--- last 5 pilot lines ---"; tail -5 "$OUT/pilot.log"
echo "--- shots: $(ls "$SHOTS/$TAG-"*.png 2>/dev/null | wc -l) ---"
echo "MISSION RUN DONE ($TAG, ${SECS}s)"