Files
regress/README.md
T
ssmithx f0d437b60f Enforce Ingress-style link-crossing prevention
A new link can no longer cross any existing link from either team —
segmentsIntersect() does a standard orientation-based segment test,
and routes/links.ts excludes shared-endpoint pairs (fanning multiple
links out of the same portal is fine, that's not a crossing). 6 new
tests; 37 total passing.
2026-08-05 13:33:06 +00:00

2.2 KiB

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