Colyseus Multiplayer Framework
Colyseus is an open-source Node.js framework for building authoritative game servers, with real-time state synchronization, matchmaking, and effortless integration into any game engine or frontend. Authentication, database services, an admin panel, and dev tooling are all included.
Key Features
From a single Room definition, clients are matched into multiple room instances, with visibility flags, lobbies, and ranked queues.
Define your state on the server; clients receive binary delta patches automatically.
Built-in client prediction, rollback, interpolation, and lag compensation, new in 0.18.
Share your server’s types with the SDK: typed messages, typed join options, typed state.
Official SDKs for the Web, Unity, Godot, Defold, GameMaker, Construct, Haxe, and more.
Horizontal scaling across processes. Self-host for free, or use Colyseus Cloud for managed hosting.
What does it look like?
Create a server
Create and start a new Colyseus server using the following commands:
# Create a new Colyseus project
npm create colyseus-app@latest ./my-server
# Enter the project directory
cd my-server
# Run the server
npm startDefine your Room State
The Room state is the data structure that will be synchronized between the server and the connected clients:
import { schema, t } from "@colyseus/schema";
export const Player = schema({
x: t.number().default(0),
y: t.number().default(0),
}, "Player");
export const MyState = schema({
players: t.map(Player),
}, "MyState");Create your Room code
Define the game logic and client interactions with the game state within your Room code.
import { Room, Client } from "colyseus";
import { MyState, Player } from "./MyState";
export class MyRoom extends Room {
maxClients = 4;
state = new MyState();
messages = {
doSomething: (client, payload) => {
// handle client's "doSomething" message
}
}
// Called when the room is created
onCreate(options) { }
// Called when a client joins the room
onJoin(client: Client, options: any) {
this.state.players.set(client.sessionId, new Player());
}
// Called when a client leaves the room
onLeave(client: Client, code: number) {
this.state.players.delete(client.sessionId);
}
// Called when the room is disposed
onDispose() { }
}Expose the Room identifier
Exposing the room type allows clients to connect to the server and dynamically create instances of it.
import { defineServer, defineRoom } from "colyseus";
import { MyRoom } from "./MyRoom";
const server = defineServer({
rooms: {
my_room: defineRoom(MyRoom),
},
});Join the Room from the client SDK
Communication between the client and server occurs through room connections. Below are examples for each SDK showing how to join a room and listen for state changes:
import { Client, Callbacks } from "@colyseus/sdk";
async function connect() {
const client = new Client('http://localhost:2567');
const room = await client.joinOrCreate('my_room', {
/* custom join options */
});
const callbacks = Callbacks.get(room);
// Listen to 'player' instance additions
callbacks.onAdd("players", (player, sessionId) => {
console.log('Player joined:', player);
});
// Listen to 'player' instance removals
callbacks.onRemove("players", (player, sessionId) => {
console.log('Player left:', player);
});
// Send messages to the server
room.send("doSomething", {/* ... */});
return room;
}
connect();Explore more
Explore more about Colyseus by following the tutorials and example projects: