#!/usr/bin/env bash # Headless Pitchwell smoke — no Godot GUI. docs/GAMEPLAY.md: 20 Hz sim, seep +0.4/s. set -euo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)" N_TICKS="${1:-40}" HZ=20 # GAMEPLAY.md Economy: Sump Wells slow seep (+0.4/s while claimed) SEEP_PER_S=0.4 # GAMEPLAY.md Match open: HQ + 4 workers, 500 Pitch start START_PITCH=500 DT="$(python3 -c "print(1.0/${HZ})")" STUB="${ROOT}/assets/cinematics/first-contact/out/first-contact-stub.mp4" fail() { echo "SMOKE FAIL $*" >&2 exit 1 } # Optional cinematic probe (GAMEPLAY.md: briefings ≥1280×720) if [[ -f "${STUB}" ]]; then if command -v ffprobe >/dev/null 2>&1; then wh="$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "${STUB}" || true)" w="${wh%%,*}"; h="${wh##*,}" if [[ "${w}" != "1280" || "${h}" != "720" ]]; then fail "stub ${STUB} size ${w}x${h} want 1280x720" fi else echo "SMOKE WARN ffprobe missing; skip stub size check" >&2 fi fi # Pure-Python 20 Hz tick loop: match open — HQ exists, claimed well seeps Pitch OUT="$( N_TICKS="${N_TICKS}" HZ="${HZ}" SEEP_PER_S="${SEEP_PER_S}" START_PITCH="${START_PITCH}" DT="${DT}" python3 - <<'PY' import os, sys n = int(os.environ["N_TICKS"]) hz = int(os.environ["HZ"]) seep = float(os.environ["SEEP_PER_S"]) pitch = float(os.environ["START_PITCH"]) dt = float(os.environ["DT"]) hq_alive = True well_claimed = True # conceptual: refinery radius holds seep (GAMEPLAY.md) if n < 1: print("bad N_TICKS", n, file=sys.stderr) sys.exit(2) for t in range(n): if not hq_alive: print("HQ dead mid-sim", file=sys.stderr) sys.exit(1) if well_claimed: pitch += seep * dt # +0.4 Pitch/s → +0.02/tick at 20 Hz # Expect: start 500 + N*(0.4/20) expect = float(os.environ["START_PITCH"]) + n * (seep / hz) # float tolerance if abs(pitch - expect) > 1e-6: print(f"pitch {pitch} != expect {expect}", file=sys.stderr) sys.exit(1) if not hq_alive: print("HQ missing", file=sys.stderr) sys.exit(1) print(f"ticks={n} hz={hz} pitch={pitch:.4f} hq=1 seep={seep}/s") PY )" || fail "sim ${OUT}" echo "SMOKE PASS headless ${OUT}" exit 0