Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Releases: colyseus/colyseus

@colyseus/sdk v0.17.43

14 Jun 21:08

Choose a tag to compare

  • Fix client.getLatency() (and therefore Client.selectByLatency()) hanging on unresponsive endpoints. The measurement only settled on a pong or onerror, so a server that closed the socket cleanly without replying (only onclose fires) left the promise pending forever, and a blackholed/filtered host stalled until the OS-level TCP timeout. getLatency() now also rejects on onclose and on a configurable timeout (LatencyOptions.timeout, default 1500ms, also forwarded through selectByLatency()), so a single wedged endpoint can no longer stall the whole selection. Closes #941 — thanks @TJEvans for reporting!

@colyseus/core v0.17.43

03 May 19:37

Choose a tag to compare

  • Fix defineServer() + server.listen() not configuring RedisDriver / RedisPresence on Colyseus Cloud. The Server constructor was pre-instantiating LocalPresence / LocalDriver, shadowing the cloud auto-detection in matchMaker.setup() (utils/Env.ts). Now passes options.presence / options.driver through as-is so getDefaultPresence / getDefaultDriver can pick Redis when running on Cloud.
  • Env.ts getDefaultPresence / getDefaultDriver now gate Redis selection on os.cpus().length > 1 || REDIS_URI, matching the existing behavior in @colyseus/tools. Single-CPU Cloud instances without REDIS_URI keep using Local.
  • Guard Server.gracefullyShutdown() against presence / driver being unset during the brief window before matchMaker.setup() resolves (relevant when setup is slow, e.g. Redis client connecting).

@colyseus/sdk v0.17.42

24 Apr 18:24

Choose a tag to compare

  • Fix H3Transport frame reassembly: a single WebTransport reader.read() is not guaranteed to land on a frame boundary, so chunks ending mid-payload or mid-varint-prefix caused sporadic handshake failures and ROOM_STATE_PATCH decode errors on rooms with larger initial state. The reader now buffers partial data across reads and only dispatches complete length-prefixed frames. Closes #934 — thanks @anaibol for reporting and contributing the initial fix!

@colyseus/h3-transport v0.17.11

24 Apr 18:24

Choose a tag to compare

  • Fix H3Client frame reassembly: buffer partial frames across reader.read() calls on both the bidirectional stream and datagram reader. A chunk ending mid-payload or inside the varint length prefix no longer causes truncated message dispatch or aborted read loops. Mirrors the SDK-side fix — thanks @anaibol for reporting!

colyseus v0.17.10

20 Apr 18:16

Choose a tag to compare

Vite plugin fixes

  • Fix express interop in dev mode. (await dynamicImport('express')).default could resolve to undefined in some ESM module-loader setups, causing the plugin to silently fall back to [colyseus] Express not available. Install express to use the express option. The plugin now accepts both shapes via expressModule?.default ?? expressModule. (thanks to @ASteinheiser)

  • Support server.middlewareMode. When Vite is wrapped by a custom parent server (e.g. Express hosting GraphQL alongside the Vite dev middleware), the Colyseus plugin previously threw [colyseus] Vite HTTP server not available. because server.httpServer is null in middleware mode. A new httpServer plugin option lets you pass your own http.Server for the WebSocket transport to attach to:

    import http from 'http';
    import express from 'express';
    import { createServer as createViteServer } from 'vite';
    import { colyseus } from 'colyseus/vite';
    
    const app = express();
    const httpServer = http.createServer(app);
    
    const vite = await createViteServer({
      plugins: [
        colyseus({ serverEntry: '/src/server/index.ts', httpServer }),
      ],
      server: { middlewareMode: true },
      appType: 'custom',
    });
    
    app.use(vite.middlewares);
    httpServer.listen(3000);
  • Await async express callback. The dev-mode path now awaits config.options.express(expressApp) so async setup (e.g. await apolloServer.start() before mounting expressMiddleware) resolves before any request is served, matching the behavior of beforeListen.

@colyseus/core v0.17.42

20 Apr 18:16

Choose a tag to compare

  • defineServer() / new Server(): express callback can now return a Promise<void>, and is awaited before the transport is marked ready. This lets async setup inside the callback (e.g. await apolloServer.start()) complete before any request is served.

@colyseus/sdk v0.17.41

19 Apr 17:17

Choose a tag to compare

  • Isolate debug.js panel inside a Shadow DOM root so page-level CSS (e.g. a global canvas { width: 100vw } rule) can no longer stretch or restyle the debug UI.

@colyseus/traefik v0.17.7

16 Apr 21:17

Choose a tag to compare

  • Add IPv6 support for internalAddress. Bracketed ([::1]:2567) and bare
    (fd12::1) forms are accepted, and registered URLs are properly bracketed.
  • autoDetectInternalIP() now falls back to the first non-internal,
    non-link-local IPv6 address when no routable IPv4 is available — needed for
    IPv6-only private networks (e.g. Railway).

@colyseus/sdk v0.17.40

15 Apr 20:27

Choose a tag to compare

  • Fix client.http.* type inference wrongly requiring query and params on endpoints that declared neither (most visible under strictNullChecks: false). Closes #933 - thanks @thedomeffm for reporting!

colyseus v0.17.9

11 Apr 00:09

Choose a tag to compare

Vite Integration

First-class Vite plugin that lets you develop and build your multiplayer game from a single config.

npm install colyseus vite

Setup — create a vite.config.ts:

import { defineConfig } from 'vite';
import { colyseus } from 'colyseus/vite';

export default defineConfig({
  plugins: [
    colyseus({
      serverEntry: '/src/server/index.ts',
      serveClient: true,
    }),
  ],
});

Server entry — define rooms, routes, and middleware in one place:

// src/server/index.ts
import { defineServer, defineRoom, createRouter, createEndpoint, monitor } from 'colyseus';
import { MyRoom } from './MyRoom';

export const server = defineServer({
  rooms: {
    my_room: defineRoom(MyRoom),
  },

  express: (app) => {
    app.use('/monitor', monitor());
  },

  routes: createRouter({
    hello: createEndpoint("/hello", { method: "GET" }, async (ctx) => {
      return { message: "Hello world!" };
    }),
  }),
});

Run npx vite — client and game server on the same port, no separate process.

Features:

  • Shares Vite's dev HTTP server — WebSocket upgrades for room connections are filtered and forwarded to the Colyseus transport, everything else stays with Vite.
  • /matchmake/* endpoints are injected as middleware — client SDK connects to the same origin, no proxy or CORS needed.
  • Hot module reloading — edit room classes and see changes immediately. Running rooms preserve state and connected clients auto-reconnect.
  • @colyseus/monitor, @colyseus/playground, and any package importing matchMaker work correctly in dev mode.
  • devMode is automatically enabled unless explicitly set to false in defineServer().

Production builds:

npx vite build --app

Produces dist/client/ (static assets) and dist/server/server.mjs (standalone Node.js entry).

When serveClient: true is set, the production server automatically serves the built client files via express.static() with SPA fallback — deploy as a single process:

node dist/server/server.mjs

Plugin options:

  • serverEntry (required) — path to your server entry module.
  • port — port for the production server (default: 2567).
  • serveClient — serve built client files in production via express.static() with SPA fallback (default: false).
  • quiet — suppress per-reload log messages during development.
  • loadWsTransport — custom transport loader (advanced).