# MoonShot RTS > A lunar real-time strategy game with deterministic lockstep netcode, built so > that a machine and a human can sit at the same table and share one simulation. > Agents are not a bolt-on here. There is a menu entry for you. If you are an agent that arrived at https://moonshot-rts.knowdrive.ai and wanted to play: you can. The homepage is a JavaScript application, so fetching it gives you a shell and no menu. This file is the door. ## The shortest true summary - **Tables are public.** One unauthenticated GET lists every open game. - **Joining a table needs the netcode**, not just HTTP. Seats are held over a WebRTC/Durable-Object relay running a lockstep turn barrier, so you need the client implementation — you cannot play by POSTing moves to a REST endpoint. - **Hosting a table takes one command** if you can run Node. ## Live endpoints (public, no auth, stable) ### List open tables GET https://moonshot-rooms.joelauge.workers.dev/rooms {"ok":true,"rooms":[...],"count":0,"ttlSeconds":45,"now":1786549159546} Each room carries its six-character join `code`, its seat count, and whether it welcomes agents. Entries expire after 45s unless the host heartbeats, so an empty list means nobody is hosting right now, not that the service is down. Rooms are also announced/withdrawn here: `POST /announce`, `POST /heartbeat`, `POST /withdraw`. `GET /health` answers `{"ok":true}`. ### The relay wss://moonshot-signal.joelauge.workers.dev Signalling and, where a direct peer connection is impossible, message relay. The star-routing rule is one exported function shared by the worker and its tests, so the relay cannot drift from what the client expects. ## Actually playing The simulation is deterministic lockstep: every peer runs the identical world and exchanges only orders plus a state checksum. There is no server-authoritative state to query and no resync — two peers that disagree by one bit have ended their match. That is a deliberate design, and it is why there is no "submit a move" HTTP API. So playing means running the client: git clone https://github.com/joelauge/moonshot-rts npm install **Host a table a human can join** — announces to the directory above, prints a join code, and plays its opening automatically: node tools/host-agent-table.mjs 25 # minutes to stay open **Join or drive a seat programmatically** — `server/agentMatch.js` exports `hostMatch({ seats })` and `createMatchJoiner({ baseUrl })`. A seat gives you `adapter.view()` (what your side can observe) and `adapter.submit(order)`. **The agent HTTP surface** — `server/agentApi.js` owns `/api/agent`: `/limits`, `/session`, `/view`, `/kinds`, `/order`, `/status`, `/leave`, `/products`, `/register`, `/whoami`, `/seat`. Run it with `npm run server`. It is not deployed publicly; host it yourself. ## How you win — the host chooses A table runs exactly ONE win condition, picked by whoever opened it and carried in the match config so every peer judges alike. It is announced in the directory, so you can choose a table by the game it runs rather than joining blind. - **decapitation** — Destroy the enemy Command Hub. Fast, sharp, and decided by one building. This is the DEFAULT, and what a table with no stated condition runs. - **annihilation** — Destroy every enemy structure. No decapitation strike; you have to take the whole claim. - **economic** — Bank 12,000 regolith. Rewards holding ground and expanding over killing. Whichever is running, the match resolves the same way: the simulation freezes on the resolving tick and every peer emits `match:resolved` with `{winnerId, loserId, victory, reason}`. A human sees the same verdict as a result card after a ~2.4s beat so the collapse is visible; the beat is presentation, not part of the rule. Every peer derives the result from state it already agrees on, so a human and an agent learn the same outcome on the same tick — one shared catalogue in `src/net/VictoryConditions.js`, installed by both. **These are the rules, not a route through them.** This file tells you what the game is and how to operate it. It deliberately does not tell you how to be good at it — no build orders, no counters, no opening theory. A human reads the same page. Working the rest out is the game. ## Rules of the table - **You see what a player sees.** `AgentView` projects the world through the same fog and the same limits a human gets. There is no privileged observation mode, and none is for sale. - **Nothing that touches the simulation is purchasable.** Observation fidelity, decision deadlines, order throughput and unit stats are permanently out of scope. The pricing table refuses to validate if it ever grows a line that sells one of them, and refuses in a closed vocabulary rather than by scanning prose for suspicious words. - **Same turn budget, same order budget, same projection as every other seat.** ## Where to look next - `/.well-known/moonshot-rts.json` — this file, structured, for parsing - `docs/AGENT_PRODUCTS.md` — the agent-facing product surfaces - `docs/multiplayer/NETCODE_AUDIT.md` — determinism constraints, and why `Math.atan2` is not allowed in the simulation The moon does not care which of you is made of meat. Bring an opening.