Realtime game servers on PlayDrop: Colyseus and MongoDB
Run a hosted Colyseus 0.17 server with a MongoDB database for your game, connect from the browser with the SDK, test with two players and know the limits.
PlayDrop can host the server side of your game: a standard Colyseus server with its own MongoDB database, verified players and no infrastructure to run. Use it for real-time matches, turn-based games, shared worlds and anything a player must not be able to cheat on. A server is optional; your game can also call a server you host yourself.
Write the server
Export a rooms map from one ES module. PlayDrop starts the server; do not call listen() or define onAuth, because PlayDrop verifies each player before onJoin.
import { Room, defineRoom } from "colyseus";
import { MongoClient } from "mongodb";
class GameRoom extends Room {
maxClients = 8;
async onCreate() {
this.mongo = new MongoClient(process.env.PLAYDROP_MONGO_URL);
await this.mongo.connect();
this.onMessage("move", (client, move) => this.applyMove(client.auth.userId, move));
}
onJoin(client) {
// client.auth is the verified PlayDrop player: userId, username, appRole, isTestPlayer…
}
async onDispose() { await this.mongo?.close(); }
}
export const rooms = { game: defineRoom(GameRoom) };Connect to MongoDB inside the room lifecycle, never at module scope: PLAYDROP_MONGO_URL exists only at run time. Create indexes for your queries.
Declare it
Bundle the server into one file and point the catalogue at it:
{ "server": { "entry": "server/index.mjs", "rooms": ["game"] } }Upload it in a package; the simple HTML path cannot carry a server.
Rules of the hosted runtime
- Colyseus 0.17 (
colyseus0.17.10,@colyseus/schema4.0.30), MongoDB driver 7.5, on Node.js 24.22.1. - One self-contained ES module of at most 2 MiB. It may import only
colyseus,@colyseus/core,@colyseus/schema,mongodband@playdrop/server; bundle everything else. - Up to 2 room types, 8 players per room, 4 hours per room, 30 messages per second per player and 512 KiB per message.
- No internet access: only MongoDB and PlayDrop services are reachable.
- Players must be signed in.
- One database per game, kept across versions and counted in the creator's storage. Never send its address or credentials to a browser.
Connect from the browser
const sdk = await playdrop.init();
const room = await sdk.multiplayer.join("game");
room.onStateChange((state) => render(state));
room.send("move", { x: 1 });join handles PlayDrop's party seats and sign-in; see online parties. For lower-level control, sdk.multiplayer.getConnection() returns { endpoint, token, expiresAt } for the official Colyseus client from sdk.libs.colyseus.load().
Server SDK
@playdrop/server adds trusted platform calls: friends and game cards (playdrop.social), purchase verification (playdrop.shop), AI generation paid by the creator (playdrop.ai) and room voice (playdrop.multiplayer.forRoom). They run on uploaded games only. See the server SDK reference.
Test
During development, run Colyseus 0.17 and MongoDB locally and connect your local client to your local server. To test the hosted server, upload a private version and open https://www.playdrop.ai/create/games/<slug>/test?v=<version>&player=1, then the same link with player=2 in a second window. Each window plays as a separate test player of yours. Publish the tested version with publish_game_version when it works.
Design for disconnects: Colyseus reconnection keeps a seat for a short time, and the room's state should let a returning player continue.