Public: anyone can read this; the crew can change it.
forked from trevato/cs
multiplayer. i need to run this with my friends. surprised it’s not there yet… #300
Split into four issues that a builder can finish one at a time, with the design call made rather than deferred. Nothing here is assigned by me — a person assigns — and this issue stays open as the thing they add up to; it now waits on the last of them.
The call, and why. The truth moves to this process rather than to one player's browser: the simulation is plain TypeScript that already steps headless in the suite (src/client/replay.ts) and ninety-six at a time for training (src/rl/arena.ts), so the server can be the world without a second implementation. A browser then sends input and draws what it is told. That also happens to be the only honest fix for the leaderboard taking a page's word for a result (#168). The cost is CPU and bandwidth on a shared box, which is why the first issue is a measurement and not a feature.
- #302 — What a room costs, measured before anything is built on it. Milliseconds of CPU per simulated second per world, how many worlds a core holds at 64 Hz, and a snapshot's size in three encodings at three rates — landed as a bench plus a ceiling the suite holds. Ready now.
- #303 — A room your friends can join: one WebSocket relay, same-origin, capped, limited, forgotten when it empties. Bun serves sockets itself, so no dependency. The game is deliberately left out: opaque messages relayed to a room's members, every limit a number with a reason, nothing under
FORGE_APP_DATA. This is the security-shaped half. Ready now. - #304 — A room you can watch: the world steps on the server and every member is sent a snapshot (waits for #302 and #303). One refactor carries it —
updatetakes a way to ask for a player's input instead of a single one forworld.me— and the golden digests staying still is how you know the single-player game is untouched. - #305 — Your friend's shots land: a member's input reaches the room's world, and your own body does not wait for the round trip (waits for #304). A slot claimed from a bot, input coalesced per tick, prediction for your movement and nothing else, every field validated on arrival, and the result posted by the server.
What I deliberately left for the next round, so this stays four: the lobby — a room with an address you can send to a friend, a member list, a name and a side, and the invite that makes "run this with my friends" one link rather than one console. It is a page and it is worth doing well; it waits for #303 either way.
What will hurt, said in advance. Two browsers will not stay bit-identical — Math.sin is implementation-defined — so lockstep was not chosen; the server being the only simulation is what makes that a non-problem. Rooms die with the process, so a deploy ends a round, and the page should say so before somebody finds out.
No description.