ssmithx 0bf9b8997c Document archy-x250-dev3 deployment
Dedicated nginx server block on :8543 (not proxied under the dashboard's
80/443) because the dashboard sets Permissions-Policy: geolocation=()
server-wide, which would silently break Regress's core claim/link
mechanic. Also documents a found-but-not-fixed gap: the dashboard's
app iframe has no allow="geolocation", so the in-dashboard launch path
won't get location access either until that shared component is patched.
2026-08-05 13:41:38 +00:00
2026-08-05 13:41:38 +00:00

Regress

A location-based capture game in the spirit of Ingress, built as a nostr-native web app. Real Bitcoin-accepting businesses from BTC Map stand in for Ingress's portals — players physically visit them to claim them for their team (orange or green), then link claimed places into triangular control fields. First scope: Madeira, Portugal.

See DESIGN.md for the full research/design writeup.

Stack

  • server/ — Fastify + better-sqlite3 + nostr-tools (TypeScript), same pattern as podsteadr.
  • frontend/ — Vue 3 + Vite + Pinia + Tailwind + Leaflet.
  • Auth is NIP-98 (signed-event login → session cookie), same as podsteadr. frontend/public/nostr-provider.js is vendored so the app can also be launched identity-aware from inside an Archipelago dashboard, the same way as podsteadr — see that repo's README for how the registration side works.

Running locally

# server
cd server
npm install
npm run dev        # http://localhost:8096

# frontend (separate terminal)
cd frontend
npm install
npm run dev         # http://localhost:5173, proxies /api to :8096

On first run, the places table is empty — call POST /api/sync (or click "Sync from BTC Map" in the UI) to pull the current Madeira dataset from BTC Map's public API.

Game rules (v0)

  • Claiming or linking from a place requires being within CLAIM_RADIUS_METERS (default 40m) of it, via browser geolocation — no claiming from the couch.
  • Claiming an enemy-held place captures it for your team and tears down any links running through it.
  • A link can be created between any two places your team currently holds, as long as you're standing at the origin place — no maximum link distance.
  • A new link can't cross any existing link (either team) — same as Ingress. Links sharing an endpoint don't count as crossing. See services/geo.ts#segmentsIntersect and routes/links.ts.
  • Three mutually-linked, same-team places form a field (computed live, not stored) — see server/src/services/fields.ts.
  • Team choice is one-way once made.

Tests

cd server
npm test

Deployment

Live at https://archy-x250-dev3.tail08d8f2.ts.net:8543 (Tailscale-only — this node has no public IP, so it isn't reachable from the open internet like podsteadr is; anyone playing needs to be on the same tailnet).

  • Single container (Dockerfile, server + built frontend in one image), podman run --restart unless-stopped, data on a bind-mounted volume at /var/lib/archipelago/regress-data on the node.

  • Fronted by a dedicated nginx server block, deploy/nginx-archy-node.conf, on its own port (8543) rather than being proxied under the node's main dashboard (80/443).

    Why a dedicated port, not /app/regress/ like other installed apps: archipelago's own nginx config sets Permissions-Policy: geolocation=() server-wide on its 80/443 blocks — inherited by every location under them that doesn't set its own add_headers. Regress's entire claim/link mechanic depends on navigator.geolocation, so being proxied under those blocks would silently break the core game with no clear error. A separate server block sidesteps this entirely and sets Permissions-Policy: geolocation=(self) explicitly.

    Also found, not yet fixed: the Archipelago dashboard's own app-iframe element (neode-ui/src/views/appSession/AppSessionFrame.vue) has no allow="geolocation" attribute, so even a geolocation-permitting app would have geolocation blocked by the browser's default iframe permission delegation if launched inside the dashboard iframe. This isn't Regress-specific — it'd affect any app needing geolocation. Until that's patched (a shared-component change, out of scope for this deploy), players should open Regress directly (the URL above, or "open in new tab" from the dashboard) rather than through the in-dashboard iframe.

  • Non-standard port gotcha: nginx's $host variable strips the port before forwarding, which breaks NIP-98 login (u tag URL won't match). Use proxy_set_header Host $http_host; (preserves the original port) — already set correctly in deploy/nginx-archy-node.conf.

  • PUBLIC_URL passed to the container must include the :8543 for the same reason.

To redeploy after a code change: git pull in /var/lib/archipelago/regress-src on the node, podman build -t localhost/regress:latest ., then podman run -d --name regress-app --replace --restart unless-stopped -p 127.0.0.1:8199:8199 -v /var/lib/archipelago/regress-data:/data -e PUBLIC_URL=https://archy-x250-dev3.tail08d8f2.ts.net:8543 localhost/regress:latest.

S
Description
Nostr-based location game on Archipelago — recreates BTC Maps unclaimed businesses as capturable portals, starting with Madeira
Readme
357 KiB
Languages
TypeScript 70.7%
Vue 17.6%
JavaScript 7.5%
CSS 2.6%
Dockerfile 0.8%
Other 0.8%