Agent8 Server SDK
Agent8 hosts a game server for you. You write one Server class; your game’s clients call its methods, and it reads and writes data that the platform stores and pushes back to every client in real time. This page is the map: how the pieces connect, how your code runs, and where each kind of data belongs.
Architecture
The client keeps one connection to the game server (connected) and, after joinRoom(roomId), a second one to that room’s Room Server (rsConnected). Both run the same Server class; code running for a room can also use $room. Every store below pushes its changes to subscribed clients, throttled to at most one update per 30 ms.
How Your Code Runs
- Every method is a remote function — and a public endpoint. Clients call
server.remoteFunction(name, args)(Remote Function), and any client can call any method with any arguments, so take identity from$senderand decide amounts on the server (Execution Model). - Nothing survives a call except the stores. Each request gets a fresh
Serverinstance, and there are no timers — recurring work goes in$roomTick, which runs every 200 ms per active room. - Calls run concurrently. Two requests, or two room hooks, can interleave; make a read-modify-write exclusive with
$lock. - Rooms have a lifecycle. A room exists while someone is in it, and
onRoomCreate…onRoomDestroyfire as players join and leave, with a 30 s grace period for dropped connections (Room System). - Messages are not stored. Broadcasts and direct messages reach whoever is subscribed at that moment — anything a player must not miss belongs in a store.
Where Data Lives
| Store | Scope | Lives until | Durability | Client hook | Use for |
|---|---|---|---|---|---|
| Global state | One document for the verse | Forever | Persisted in the background | useGlobalState | Game-wide settings, status, shared counters |
| User state | One document per player | Forever | Persisted in the background | useGlobalMyState | Profile, progression, inventory |
| Global collection | Queryable list of items | Forever | Committed after a ~2 s buffer | useGlobalCollection (first 100) | History, logs, rankings |
| Asset | Balances per player | Forever | Atomic per call, persisted within ~5 s | useAsset | Currencies, resources, consumables |
| Room state | One document per room | The last player leaves | Never persisted | useRoomState | Match phase, round timer |
| Room user state | One document per player in a room | The room ends | Never persisted | useRoomMyState | Position, HP, per-match score |
| Room collection | Queryable list per room | The room ends | Never persisted | useRoomCollection | Per-match events, room scoreboard |
Anything a player must never lose — currency, items, rewards — goes in $asset or user state, never only in a collection or a room.
Start Building
Getting Started takes you from an empty Vite project to a tested server function, deployed and called from React.
These pages describe SDK 2.0. Moving an existing 1.x project across? Read Upgrading to 2.0 first.