#!/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=$! SYLPH_KILL_TURRETS="${SYLPH_KILL_TURRETS:-0}" 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)"