diff --git a/README.md b/README.md index e4f3f40..7d4e3f8 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,12 @@ world does not pause), wear its body while it decays, burn its weapons, and bail before it blows. Purge every amp and every machine on the floor and the drone resolves to a chord. -## Run it +## Play it -Any static server from the repo root (ES modules won't load off `file://`): +Live: **https://monsterrobot.games/paradramorama/** + +Locally — any static server from the repo root (ES modules won't load off +`file://`): ``` python3 -m http.server 8474 @@ -19,6 +22,23 @@ python3 -m http.server 8474 then open http://localhost:8474 +## Deploy + +``` +./deploy/deploy.sh +``` + +Rsyncs to the games VPS (`humanjing@100.71.119.27`) at +`/home/humanjing/monsterrobot.games/games/paradramorama/` — a **read-only** +bind mount into `forum-nginx`, so deploys write the host path (`docker cp` +fails silently). Needs no nginx change; the apex server block serves any +subdirectory, and a top-level symlink gives the pretty URL. + +Cloudflare serves `.js` with a 4-hour `max-age`, so the deploy stamps a +version query across the whole module chain (`index.html` → `game.js` → +`world.js`/`audio.js`) in a staging copy. Source files are never touched. +Without that you would test stale code for hours after a redeploy. + ## Controls | Key | Action | diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100755 index 0000000..18f1a4b --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Deploy PARADRAMORAMA to monsterrobot.games/paradramorama (botchat/games VPS). +# +# The apex monsterrobot.games is a STATIC LANDING on humanjing@100.71.119.27: +# host /home/humanjing/monsterrobot.games -> forum-nginx +# /usr/share/nginx/html/games-lander (READ-ONLY bind mount) +# `docker cp` into the container FAILS SILENTLY because the mount is RO — +# always write to the host path, nginx serves it live. +# +# Routing needs NO nginx change: the apex server block ends in +# location / { try_files $uri $uri/ /index.html; } +# so any directory under the root is served directly. Games live in +# games// with a top-level symlink for the pretty URL (same as +# mollycool, not-tonight). +# +# CACHE: Cloudflare fronts this domain and serves .js with max-age=14400 (4h). +# Without busting, a redeploy shows STALE CODE for hours. So the deploy stamps +# a version query onto the whole ES-module chain (index.html -> game.js -> +# world.js/audio.js) in a staging copy. Source files are never modified. +# +# Usage: ./deploy/deploy.sh +set -euo pipefail + +VPS="humanjing@100.71.119.27" +LANDER="/home/humanjing/monsterrobot.games" +NAME="paradramorama" +SRC="$(cd "$(dirname "$0")/.." && pwd)" +URL="https://monsterrobot.games/${NAME}/" + +STAMP="$(cd "$SRC" && git rev-parse --short HEAD 2>/dev/null || echo nogit)-$(date +%s)" +BUILD="$(mktemp -d /tmp/paradramorama_build_XXXXXX)" +trap 'rm -rf "$BUILD"' EXIT + +echo "→ staging build ($STAMP)" +rsync -a --exclude '.git' --exclude '.gitignore' --exclude 'deploy' \ + --exclude '.DS_Store' "$SRC/" "$BUILD/" + +# stamp the module chain so Cloudflare + the browser always fetch fresh code +perl -pi -e "s{src=\"src/game\.js\"}{src=\"src/game.js?v=$STAMP\"}g" "$BUILD/index.html" +perl -pi -e "s{from '\./(world|audio)\.js'}{from './\$1.js?v=$STAMP'}g" "$BUILD/src/game.js" +grep -q "game.js?v=$STAMP" "$BUILD/index.html" || { echo "✗ stamp failed (index.html)"; exit 1; } +grep -q "world.js?v=$STAMP" "$BUILD/src/game.js" || { echo "✗ stamp failed (game.js imports)"; exit 1; } + +echo "→ rsync → $VPS:$LANDER/games/$NAME/" +ssh "$VPS" "mkdir -p '$LANDER/games/$NAME'" +rsync -az --delete "$BUILD/" "$VPS:$LANDER/games/$NAME/" + +echo "→ ensure pretty-URL symlink $LANDER/$NAME -> games/$NAME" +ssh "$VPS" "cd '$LANDER' && ln -sfn 'games/$NAME' '$NAME' && ls -ld '$NAME'" + +echo "→ verifying live" +CB="$(date +%s)" +CODE=$(curl -sS -o /dev/null -w '%{http_code}' -L "${URL}?cb=${CB}" --max-time 25) +JS=$(curl -sS -o /dev/null -w '%{http_code}' -L "${URL}src/game.js?v=${STAMP}" --max-time 25) +SERVED=$(curl -sS -L "${URL}?cb=${CB}" --max-time 25 | grep -o "game\.js?v=[^\"]*" | head -1) +echo " index: $CODE game.js: $JS serving: $SERVED" +if [ "$CODE$JS" = "200200" ] && [ "$SERVED" = "game.js?v=$STAMP" ]; then + echo "✓ live at $URL" +else + echo "✗ NOT deployed cleanly (index=$CODE js=$JS served=$SERVED)"; exit 1 +fi