# `scripts/` — repo automation Everything in this directory is either sourced by `./run` or invoked directly over SSH on a remote host (apricot, plum). Every `*.sh` is idempotent and safe to re-run. ## Layout ``` scripts/ run/ — ./run dispatch modules; one file per concern common.sh — colors, dotenv loader, $GAME_DIR/$SIMULATOR_DIR/$GUIDE_DIR build.sh — cmd_build, cmd_build_wasm, cmd_build_gdext, cmd_build_info build-info.sh — git-state → src/game/build_info.json generator dev.sh — lint/format/test/verify/autoplay subcommands export.sh — Godot export one-target dispatch remote.sh — install:/start:/stop:/smoke: over SSH tools.sh — setup + spritegen + misc one-offs dev-setup/ — one-shot env bootstrap scripts, per-OS osx.sh — macOS (Homebrew + Godot + Rust + --with-runner) linux.sh — generic Linux (dnf/apt + Rust + --with-runner) bluefin.sh — rpm-ostree Bluefin layer (weston, vulkan-tools) lib/ — helpers shared across the per-OS scripts runner.sh — forgejo-runner install/register/verify autoplay/ — runs ON a linux host (apricot) for headless batches run_ap3.sh — weston-headless flatpak Godot invocation run_seeded.sh — single-seed AUTO_PLAY wrapper test_save_resume.sh — save-at-T50 → resume → compare test harness ``` ## Conventions - **Functions prefixed with `_`** are private helpers scoped to one file. Functions without the prefix are callable from other modules. - **`cmd__`** functions are dispatched by `./run` via name-matching — `./run verb:target` runs `cmd_verb_target`. No need to edit the top-level `run` case block to add a new subcommand. - **Direct execution works too** — every `scripts/run/*.sh` and `scripts/dev-setup/*.sh` has a working shebang and `if [[ "${BASH_SOURCE[0]}" == "$0" ]]` guard where relevant. - **Remote scripts** under `autoplay/` are *meant* to be SSH-invoked from the EDIT host (typically plum) running on the RUN host (typically apricot). Never invoke them on the EDIT host directly. - **Env files** — `.env` (tracked base) → `.env.local` (user secrets, gitignored) → `.env.` → `.env..local`. Loaded automatically by `common.sh` at source time. See `.env.example` for documented keys. ## Export staging (p2-06) `tools/export-single.sh` rsyncs the project to `.local/export-staging-/` before running `godot --export-release`, excluding `node_modules`, `.local`, `target`, `.git`, and `dist`. Godot's export scanner walks the whole project tree pre-`exclude_filter`; the pnpm-managed `public/games/*/guide/node_modules/` symlinks made macOS exports take 20+ minutes (16MB of `_scan_new_dir` warnings). Staging drops that to under 10s of scan time. - **Default**: on for `macos`, off elsewhere. - **Force on**: `EXPORT_STAGED=1 ./run export:linux`. - **Debug staging**: `KEEP_STAGING=1 ./run export:macos` leaves the staged copy in place for inspection.