# neon-grid
Tron-style p2p light-cycle arena for up to 16 riders — live at
**[game1.ardegazu.ro](https://game1.ardegazu.ro)**, repo published at
**[git.ardegazu.ro/game1](https://git.ardegazu.ro/game1)**.
Last rider alive wins the round; first to 5 rounds takes the match. Installable
PWA (works saved to the iOS home screen), safe-area aware, touch + keyboard.
## Architecture
- **No game server.** Browsers are [js-libp2p](https://libp2p.io) peers: they
meet through a circuit-relay-v2 node (gossipsub peer discovery), upgrade to
direct WebRTC, and speak a room-scoped protocol under
[`client/src/game1/net/`](client/src/game1/net/). Rooms are keyed by a secret
in the URL fragment — membership is proved pairwise with a sealed hello, and
every frame is end-to-end encrypted by libp2p's noise layer. The game only
adds a typed wire protocol and its own logic in
[`client/src/game1/game/`](client/src/game1/game/).
- **One peer referees.** The lowest peer id runs the authoritative 12 Hz grid
simulation ([`game/game.cljs`](client/src/game1/game/game.cljs)) and
broadcasts compact per-tick head deltas; clients render from them
(interpolated). Host loss voids the round and the next-lowest id takes over.
Late joiners get an RLE grid snapshot and spectate until the next round.
- **ClojureScript client** (shadow-cljs + deps.edn; the suite's CLJS app
canon). The wire protocol, room crypto and referee semantics are identical
to the original TypeScript client — golden-vector tested in
[`client/test/`](client/test/) — so mixed TS/CLJS rooms just work.
- **Hosting without an origin server.** `client/dist/` is pinned to IPFS,
named by IPNS and served straight from the gateway on the app's own domain
(DNSLink). The published repo works the same way (`deploy/publish-repo.sh`
+ the shared `git.ardegazu.ro` source root).
## Develop
Needs node ≥ 22, a JVM ≥ 17 and the `clojure` CLI (shadow-cljs).
```bash
cd client && npm install && npm run dev # watch build → http://localhost:5173
```
Open two tabs on the same `#room` URL to play against yourself. While the
shadow server runs, port 4173 serves the last release build from
`client/dist`. `npm test` compiles the pure game/net namespaces and runs the
golden vectors (extracted from the TS implementation while it was canon).
## Deploy
```bash
cd client && npm run build # → client/dist
# then: ird ipfs add client/dist → ird ipfs ipns publish game1.ardegazu.ro <cid>
deploy/publish-repo.sh # → deploy/.site (landing page + clonable bare mirror)
# then: ../git/assemble.sh game1 (updates git.ardegazu.ro)
```
MIT — see [LICENSE](LICENSE).