Files
wizwar6e/deploy
Eric WagonerandClaude Fable 5.1 86070b42a3 The eyes turn to meet magic thrown at them, even after a stride
Springing the Trap never showed its fireball: Rival stepped into the
watched corridor facing the way he walked, and the ambush's fireball
flew in from the mouth behind him while only the caption told of it.
The director now aims at incoming magic and punches — the caster's or
attacker's square, straight or through a mouth — and a stride that
ends with something to watch turns once more after the walk, the
slate holding the outcome until the eyes face it. The fireball comes
through the wormhole at the camera, then the blow lands.

The trap's first beat re-blessed for it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-02 21:28:52 -04:00
..

Deploying Wiz-War

The game runs on a single DigitalOcean droplet: one Node process serves the built client and the websocket on port 8787; Caddy in front terminates TLS with automatic certificates. Room files persist in /var/lib/wizwar/rooms and survive deploys and reboots.

Current production

  • Droplet: wizwar (nyc3, s-1vcpu-1gb, tag wizwar), IP 104.236.96.198
  • URLs: https://wizwar.kestrelsnest.social and https://wizwar.104.236.96.198.sslip.io (always works, zero DNS). Caddy serves both; NOTE: kestrelsnest.social's authoritative DNS is at HOVER (ns1/ns2.hover.com), not DigitalOcean — records must be added there. A matching record also sits in the DO zone in case nameservers ever move.

Everyday deploys

deploy/deploy.sh 104.236.96.198

Builds the client locally, rsyncs the repo (minus node_modules, data/, .git, research), installs dependencies on the droplet, and restarts the service. Games in progress survive: state lives in room files, and clients reconnect automatically.

Before any deploy that touches the engine, run the determinism gate:

deploy/verify-ledgers.sh 104.236.96.198

It fetches every production ledger and strictly replays it against the local engine; a single refused command fails the check. A room whose ledger no longer replays becomes unreachable after restart, so this is not optional.

New droplet from scratch

  1. doctl compute droplet create wizwar --region nyc3 --size s-1vcpu-1gb \ --image ubuntu-24-04-x64 --ssh-keys <your-key-ids> --tag-name wizwar --wait
  2. scp deploy/setup-droplet.sh root@<ip>:/root/ && ssh root@<ip> \ "bash /root/setup-droplet.sh wizwar.<ip>.sslip.io"
  3. deploy/deploy.sh <ip>

Operations

  • Logs: ssh root@<ip> journalctl -u wizwar -f
  • Restart: ssh root@<ip> systemctl restart wizwar
  • Nightly backups: wizwar-backup.sh runs from root's crontab at 07:17 UTC, pushing /var/lib/wizwar to the kestrel-wizwar-backups Space (nyc3) via rclone. It is installed at /usr/local/bin/wizwar-backup.sh on the droplet; setup-droplet.sh does NOT install it — on a fresh droplet, copy the script, configure rclone (the script refuses to run while the config still holds its CHANGE_ME placeholder), and add the cron entry by hand.
  • One-off backup: scp -r root@<ip>:/var/lib/wizwar/rooms ./rooms-backup