PlayMesh/Docs
HomeGitHubnpm

Communication

Event-driven messaging between clients and server — from single sessions to global broadcasts.

Client to server

Emitting from the client

client.emit('move', { x: 100, y: 250 });
client.emit('chat', { message: 'Hello!' });
client.emit('buy-item', { itemId: 'sword-of-doom' });

Handling on the server

Handlers are registered on instances. Events from a session are routed to all instances the session belongs to that have a handler for that event.
city.on('move', async (session, payload) => {
  const { x, y } = payload as { x: number; y: number };
  city.broadcast('player-moved', { userId: session.userId, x, y });
});

city.on('chat', (session, payload) => {
  const { message } = payload as { message: string };
  city.broadcast('chat', { sender: session.userId, message });
});

Server to client (targeted)

city.on('buy-item', async (session, payload) => {
  const result = await economy.processPayment(session.userId, payload);

  if (result.success) {
    session.send('purchase-success', { item: result.item, balance: result.balance });
  } else {
    session.send('purchase-failed', { reason: result.error });
  }
});

Instance broadcast

Broadcast to all sessions in an instance, across all nodes.
city.broadcast('world-event', { event: 'dragon-spawned' });

dungeon.on('boss-killed', async (session, payload) => {
  const loot = await lootService.generate(payload.bossId);
  dungeon.broadcast('loot-dropped', { items: loot, killer: session.userId });
});

Domain broadcast

Send to every session in any instance of a domain.
world.broadcast('server-announcement', { text: 'Maintenance in 10 minutes' });

Global broadcast

Send to every connected session, across all domains and nodes.
mesh.broadcast('global-announcement', { text: 'Double XP weekend starts now!' });

Receiving on the client

client.on('world-event', payload => {
  gameEngine.triggerEvent(payload);
});

const onChat = (payload: unknown) => renderChat(payload);
client.on('chat', onChat);

// Remove when no longer needed
client.off('chat', onChat);

Reserved events

EventDirectionPurpose
playmesh:sessionServer → ClientSent once after auth. Contains sessionId, userId, and initial instances.
playmesh:joinedServer → ClientSent when the session joins an instance.
playmesh:leftServer → ClientSent when the session leaves an instance.
playmesh:errorServer → ClientSent on connection setup or event handling errors.
Do not emit events with the playmesh: prefix from application code. They are filtered on both sides.