A multiplayer game usually means a server, a database and keys in your code. On Hostus it means asking your AI for rooms. hostus.room connects up to 8 players per room, friends join from an invite link, and nobody creates an account. Firebase and your own wss:// server also work from a published page, and this guide says when to use them. Firebase facts come from its docs and pricing page, read on 7 November 2026.
From a prompt to a room in four steps
- Paste the game prompt into the conversation with your AI and say how many players:
Make it a game for 4 players at the same time.The prompt points your AI at the room recipe in runtime.md, with the entry screen, the invite link and reconnection. - Publish it. With the connector, ask your AI to publish on Hostus. Without it, upload the file on hostus.io.
- Make the page public in the dashboard. Rooms run on the published link, and a reader without access gets no room.
- Open the link, tap Play, copy the invite link and paste it in the group. Everyone lands in the same room, with no code to type.
Test alone first: two tabs of the same browser count as two players. Rooms don't run in a draft preview.
What the code looks like
This is the heart of the complete game in runtime.md, trimmed. Your AI writes it, but it helps to know the shape: join with a catch, keep the URL on the invite, check everything other players send, and say hello after joining.
$('play').onclick = async () => {
$('problem').textContent = '';
$('play').disabled = true; // two taps would open two rooms
try {
room = await hostus.room.join(undefined, { max: 8, name: $('name').value });
} catch (err) {
$('problem').textContent = problem(err);
$('play').disabled = false;
return;
}
history.replaceState(null, '', room.inviteUrl); // reloading stays in the room
$('entry').hidden = true;
$('game').hidden = false;
room.on('message', (data, from) => {
// Comes from another player: check it before using it.
if (data?.hello) changed = true; // someone came back: a reload fires no join
if (Number.isFinite(data?.x) && Number.isFinite(data?.y)) {
dots.set(from.id, { x: Math.min(SIZE, Math.max(0, data.x)), y: Math.min(SIZE, Math.max(0, data.y)) });
}
});
room.on('join', () => { changed = true; renderWho(); }); // whoever arrives learns where you are
room.on('leave', (p) => { dots.delete(p.id); renderWho(); });
room.on('close', (err) => {
$('problem').textContent = problem(err);
$('game').hidden = true;
$('entry').hidden = false;
$('play').disabled = false;
});
room.send({ hello: true }); // after a reload, the others have no signal
};A player who drops keeps the seat for 10 seconds and comes back with the same id. room.host is who decides things like a new round, and it moves to another player if that one leaves.
What rooms can and can't do
- 8 players per room, and 1 KB per message.
- A player can cheat. Rooms only pass messages along: the server doesn't run the game. A player can change the code, send a false position or claim any score. Treat it as a game among friends.
- Nothing is stored. A player who joins late only knows what the others send, so the host sends the current state. To keep scores, use
hostus.data. - Each account has a daily limit of playing time, adding up every player on every game. Past it, rooms come back the next day (UTC), and the game should say so.
- Nobody can remove a player. Neither the host nor you can kick someone out of a room.
- A room name is its only lock. Keep the random name: it is reachable only by its link. A fixed name is open to anyone who guesses it.
Which games fit
Messages take a moment to arrive, so ask your AI to ease other players toward their last position instead of jumping. That suits party games, card and board games, co-op, drawing and quiz games, and casual races among friends. Don't count on it for a game decided by split-second reflexes.
Rooms, hostus.data, Firebase or your own server?
| Option | Setup | Good for | Watch out for |
|---|---|---|---|
| hostus.room | None: no account, key or database | Players moving on screen, up to 8 per room | Nothing stored, a player can cheat, daily limit per account |
| hostus.data | None; set the data mode in the dashboard | Leaderboards and turns: it updates every few seconds | Not for movement. In shared mode any reader can write, so it fits friends, not strangers |
| Firebase Realtime Database | A project, a database, security rules and the config in your code | Games that need saved state you control | Spark plan: 100 simultaneous connections. The rules are yours to get right |
| Your own wss:// server | A server you write, run and pay for | Servers that run the game and stop cheating | All of it is yours to keep running |
Pick Firebase if you already use it or need saved state a room doesn't keep. Firebase says its API keys are fine to include in code and that rules protect your data, so Hostus warns about the web config and lets you publish. Its start guide warns that test mode lets anyone read and overwrite your data. The pricing page gives the no-cost plan 100 simultaneous connections, 1 GB stored and 10 GB of downloads a month.
Pick your own server if the game has to be fair between strangers, because only a server that runs the game can check it. A published page connects to any secure WebSocket address.
Play one first
Flipdot is a one-tap arcade game published on Hostus, with a leaderboard and no backend. Open it on your phone: this is what your friends get when you send the link.
Good to know before you publish
Every page shows a small Hostus badge, and you pick the corner. The link is yourgame.hostus.page, and you can't point a domain of yours at it. The page does not appear in Google, so people reach it from your link. A new page starts private: making it public is a switch in the dashboard. The free plan covers 20 pages and 2 MB, media included, and Hostus keeps the last 20 versions of each page. If the file has a secret key in it, the upload stops and warns you. A Firebase web config also raises a warning, and it is public by design, so you can go on. Only publish games that are yours. The HTML has to mention hostus.room itself: code loaded from a separate file doesn't count.