What is ARRR?
ARRR, Agentic Real-time Relay Routing, is a relay network for real-time apps with no backend of their own: chat, voice, collaborative tools, games, live data. Clients join a room and send; the network puts everything in one order and delivers the same stream to everyone. Same messages, same order, same state on every device. Voice rides alongside on its own channel.
You write the app. The network keeps the clients agreeing.
The three parts
Nodes are the machines that hold rooms. A room is created on one node, its authority, and replicated to other nodes, its replicas. Clients connect to whichever node is best for them; messages travel to the authority, get numbered, and come back to every client on every node. Nodes are run by node providers, each with a token that ties the node to their account.
The cloud service at cloud.arrr.fun is the directory. It knows which nodes are up, tells a client which node to connect to for a room, keeps accounts, apps and API keys, and shows the live network to its operators. It does not touch your app's traffic.
The SDK is what your app talks to. connect(roomId, { appId, apiKey, ... }) gets you a room and send(data) puts a message into the stream. Read the stream one message at a time with onMessage(data, seq), or a tick at a time with onTick(frame, inputs) when every client runs the same simulation. sendVoice and onVoice carry audio. NPCs are characters that talk: an app gives one a personality and a voice, and its players hold a conversation with it.
import { connect } from 'arrr-network';
const room = await connect('duel-42', {
appId: 'my-app',
apiKey: 'arrr_…', // from the console → Apps
onTick(frame, inputs) { // the same inputs, in the same order, on every client
for (const input of inputs) world.apply(input);
world.step();
}
});
room.send({ move: { x: 1, y: 0 } });How ordering works
- A client sends a message, stamped with its own local frame.
- The room's authority numbers messages in the order they arrive.
- Messages that arrive during one tick are batched, stamped with the tick's frame, and broadcast to every client on every node as one message.
- Every client applies the batch. Because the numbering happens once, at the authority, no two clients can ever see a different order.
Arrival order is not something a client can forge, which is why it is the order that ships. The trade-off is that in a contested tick the lowest-ping client wins; the client's own frame rides along for your app's use but does not decide ordering.
What the network gives you
- One total order of messages per room, identical on every client, verified every run by a multi-client browser suite.
- Server-authoritative join and leave events, so presence cannot be spoofed by a client.
- Snapshots for late joiners. A client that arrives mid-session receives a snapshot and the messages since, and lands on the current frame.
- Reconnection. A dropped client asks the cloud service for a node again, restores the snapshot and replays the history it missed.
- Voice, as a second channel on the same socket: encoded audio frames relayed to the nearest listeners by position, never into the ordered stream. Each talker uploads once and each listener downloads a bounded number of streams, whatever the room size.
- A binary protocol sized for high-rate traffic: small frames, batched ticks, and payloads passed through untouched, JSON or raw bytes.
What it does not do
- It does not run your code. There is no server-side logic, so anything that needs a single truth (a shared simulation, a document) gets it by being deterministic: same messages, same result, on every machine.
- It does not hide latency. Prediction, interpolation and rollback are yours to add on top of the ordered stream if your app needs them.
- It does not keep secrets in the browser. An API key identifies your app and lets you revoke it; it is not a password.
Two ways to take part
- Build an app. Sign up at cloud.arrr.fun, create an app, generate its API key, and pass both to
connect(). See API Keys. - Provide a node. Sign up, mint a node token on the Nodes page, and run arrr-node with it. Your node joins the mesh and hosts rooms. See Run a Node.
Next: Getting Started builds a working chat in one file, and the live demos show a first-person shooter, a top-down shooter and a chat room sharing state across tabs.
