
Security News
Ruby's Bundler 4.0.18 Extends Cooldown to bundle lock and bundle cache
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.
@martini-kit/transport-colyseus
Advanced tools
Colyseus transport adapter for martini-kit multiplayer SDK
Colyseus room adapter for martini-kit multiplayer SDK. Use Colyseus for matchmaking, rooms, and server infrastructure while using martini-kit's declarative API for game logic.
Best of Both Worlds:
Perfect For:
pnpm add @martini-kit/core @martini-kit/transport-colyseus colyseus.js
import { Client } from 'colyseus.js';
import { defineGame, GameRuntime } from '@martini-kit/core';
import { ColyseusTransport } from '@martini-kit/transport-colyseus';
// Define your game logic with martini-kit
const game = defineGame({
minPlayers: 2,
maxPlayers: 4,
setup: () => ({
players: {},
score: {}
}),
actions: {
move: (state, playerId, input) => {
state.players[playerId] = input.position;
},
updateScore: (state, playerId, points) => {
state.score[playerId] = (state.score[playerId] || 0) + points;
}
}
});
// Connect to Colyseus
const client = new Client('ws://localhost:2567');
const room = await client.joinOrCreate('my_game_room');
// Create martini-kit transport from Colyseus room
const transport = new ColyseusTransport(room);
// Create game runtime
const runtime = new GameRuntime(game, transport, {
isHost: room.sessionId === '...' // Determine host via Colyseus
});
// Use martini-kit's clean API
runtime.submitAction('move', { position: { x: 10, y: 20 } });
Create a Colyseus room that relays martini-kit messages:
import { Room, Client } from '@colyseus/core';
export class martini-kitGameRoom extends Room {
private hostId: string | null = null;
onCreate(options: any) {
console.log('martini-kitGameRoom created');
// Handle martini-kit messages
this.onMessage('martini-kit', (client, message) => {
// Relay to all clients or targeted client
if (message.targetId) {
const targetClient = Array.from(this.clients).find(
c => c.sessionId === message.targetId
);
targetClient?.send('martini-kit', message);
} else {
// Broadcast to all except sender
this.broadcast('martini-kit', message, { except: client });
}
});
}
onJoin(client: Client, options: any) {
console.log(client.sessionId, 'joined');
// Elect first player as host
if (!this.hostId) {
this.hostId = client.sessionId;
this.broadcast('martini-kit', {
type: 'host_announce',
hostId: this.hostId,
senderId: 'server'
});
}
// Notify all clients of new player
this.broadcast('martini-kit', {
type: 'player_join',
payload: { playerId: client.sessionId },
senderId: 'server'
});
// Send current peers list to new player
const peers = Array.from(this.clients).map(c => c.sessionId);
client.send('martini-kit', {
type: 'peers_list',
payload: { peers },
senderId: 'server'
});
}
onLeave(client: Client, consented: boolean) {
console.log(client.sessionId, 'left');
// Notify remaining clients
this.broadcast('martini-kit', {
type: 'player_leave',
payload: { playerId: client.sessionId },
senderId: 'server'
});
// Elect new host if needed
if (client.sessionId === this.hostId && this.clients.length > 0) {
this.hostId = Array.from(this.clients)[0].sessionId;
this.broadcast('martini-kit', {
type: 'host_announce',
hostId: this.hostId,
senderId: 'server'
});
}
}
}
new ColyseusTransport(room: Room)Create a martini-kit transport from a Colyseus room.
Parameters:
room: A connected Colyseus room instanceExample:
const room = await client.joinOrCreate('game_room');
const transport = new ColyseusTransport(room);
All standard martini-kit Transport methods are supported:
send(message: WireMessage, targetId?: string): voidSend a message through the Colyseus room.
transport.send({
type: 'action',
payload: { action: 'move', x: 10, y: 20 }
});
// Send to specific player
transport.send({
type: 'state_sync',
payload: { state: {...} }
}, 'player-123');
onMessage(handler: (message, senderId) => void): () => voidListen for messages from other players.
const unsubscribe = transport.onMessage((message, senderId) => {
console.log('Received message from:', senderId, message);
});
// Stop listening
unsubscribe();
onPeerJoin(handler: (peerId: string) => void): () => voidListen for players joining.
transport.onPeerJoin((peerId) => {
console.log('Player joined:', peerId);
});
onPeerLeave(handler: (peerId: string) => void): () => voidListen for players leaving.
transport.onPeerLeave((peerId) => {
console.log('Player left:', peerId);
});
getPlayerId(): stringGet your player ID (same as room.sessionId).
const myId = transport.getPlayerId();
getPeerIds(): string[]Get list of all connected players (excluding yourself).
const peers = transport.getPeerIds();
console.log('Connected players:', peers);
isHost(): booleanCheck if you are the current host.
if (transport.isHost()) {
console.log('I am the host');
}
onError(handler: (error: Error) => void): () => voidListen for connection errors.
transport.onError((error) => {
console.error('Transport error:', error);
});
disconnect(): voidLeave the Colyseus room and clean up.
transport.disconnect();
getRoom(): RoomGet the underlying Colyseus room (for advanced use cases).
const room = transport.getRoom();
console.log('Room ID:', room.id);
console.log('Room state:', room.state);
The transport uses a 'martini-kit' message type on the Colyseus room. All martini-kit messages are wrapped in this format:
{
type: 'action' | 'state_sync' | 'player_join' | 'player_leave' | 'host_announce' | ...,
payload?: any,
senderId: string,
targetId?: string // For targeted messages
}
The server should send these control messages:
player_join{
type: 'player_join',
payload: { playerId: string },
senderId: 'server'
}
player_leave{
type: 'player_leave',
payload: { playerId: string },
senderId: 'server'
}
host_announce{
type: 'host_announce',
hostId: string,
senderId: 'server'
}
peers_list{
type: 'peers_list',
payload: { peers: string[] },
senderId: 'server'
}
See examples/colyseus-game for a full working example with:
// ❌ Imperative, verbose
room.onMessage('move', (message) => {
const player = players.get(message.playerId);
player.x = message.x;
player.y = message.y;
// Sync to other clients...
// Handle edge cases...
// Validate input...
});
// ✅ Declarative, concise
const game = defineGame({
actions: {
move: (state, playerId, input) => {
state.players[playerId] = input.position;
}
}
});
Use Colyseus for Infrastructure
Use martini-kit for Game Logic
Host Election
host_announce messagesError Handling
'martini-kit' messagesonMessage('martini-kit', ...) is set up on the serversenderIdhost_announce messageshostId matches a client's sessionIdplayer_join/player_leave messagespeers_list message on joincolyseus.js is installedimport type { Room } from 'colyseus.js'MIT
FAQs
Colyseus transport adapter for martini-kit multiplayer SDK
The npm package @martini-kit/transport-colyseus receives a total of 0 weekly downloads. As such, @martini-kit/transport-colyseus popularity was classified as not popular.
We found that @martini-kit/transport-colyseus demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.