Waving Hands: a browser duel after Bartle's 1977 game

SvelteKit 5 single-player version against a heuristic bot. The engine
resolves all forty spells simultaneously as the rules describe, the
ledger of gestures is the interface, and the duel is saved in the
browser. Tester feedback rounds added per-hand planning, threat
evidence, a result strip with one-time rule explanations, a phone
layout and a structured rules page. Deploys as a static site behind
Caddy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-09-22 15:33:29 -04:00
co-authored by Claude Fable 5.1
commit 865555e911
38 changed files with 8112 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
# One-time droplet setup. Run ON the droplet as root:
# bash setup-droplet.sh waving-hands.<droplet-ip>.sslip.io
# Waving Hands is a static site: Caddy serves the built files and terminates
# TLS. There is no application process, so nothing but Caddy and rsync is
# installed.
set -euo pipefail
HOST="${1:?usage: setup-droplet.sh <hostname>}"
apt-get update -q
apt-get install -qy curl rsync
# Caddy (auto-HTTPS)
apt-get install -qy debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| tee /etc/apt/sources.list.d/caddy-stable.list
apt-get update -q && apt-get install -qy caddy
# Site directory, readable by Caddy.
mkdir -p /opt/waving-hands/build
chown -R root:caddy /opt/waving-hands
chmod -R g+rX /opt/waving-hands
# Caddy vhost: auto-TLS, security headers, static files. SvelteKit writes
# each route as <route>.html, so /rules is tried as /rules.html before
# falling back to the app shell. Hashed assets under _app/immutable are
# cached for a year; everything else is revalidated so a deploy shows up
# on the next load.
cat > /etc/caddy/Caddyfile <<CADDY
$HOST
root * /opt/waving-hands/build
encode gzip zstd
header {
Strict-Transport-Security "max-age=31536000"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "no-referrer"
}
header /_app/immutable/* Cache-Control "public, max-age=31536000, immutable"
header /index.html Cache-Control "no-cache"
log {
output file /var/lib/caddy/access.log {
roll_size 10MiB
roll_keep 30
}
}
try_files {path} {path}.html /index.html
file_server
CADDY
systemctl reload caddy
# Firewall: ssh + web only.
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
echo "droplet ready: now run deploy/deploy.sh <ip> from your machine"