Tags: colyseus/colyseus
Tags
fix(core): defineServer() now configures Redis on Colyseus Cloud The Server constructor was pre-instantiating LocalPresence/LocalDriver, shadowing the cloud auto-detection in matchMaker.setup() via utils/Env.ts. Pass options.presence/driver through as-is so getDefaultPresence / getDefaultDriver can pick Redis when COLYSEUS_CLOUD is set. Gate Redis selection on `os.cpus().length > 1 || REDIS_URI` to match the existing @colyseus/tools behavior. Single-CPU instances without REDIS_URI keep using Local. Also guard gracefullyShutdown() against presence/driver being unset during the brief window before matchMaker.setup() resolves (relevant when setup is slow, e.g. Redis client connecting on Cloud). Includes a regression test in GracefulShutdown.test.ts. Bumps @colyseus/core to 0.17.43. Assisted-by: Claude Opus 4.7
fix(h3): reassemble frames across reads on SDK and server A single WebTransport reader.read() is not guaranteed to land on a frame boundary. Chunks ending mid-payload or inside the varint length prefix caused sporadic handshake failures and ROOM_STATE_PATCH decode errors on rooms with larger initial state. Buffer partial data across reads with a FrameReassembler and dispatch only complete length-prefixed frames. Applied symmetrically to the SDK (H3Transport) and server (H3Client) bidi + datagram readers. Closes #934 — thanks @anaibol for reporting and the initial fix. Assisted-by: Claude Opus 4.7
fix(h3): reassemble frames across reads on SDK and server A single WebTransport reader.read() is not guaranteed to land on a frame boundary. Chunks ending mid-payload or inside the varint length prefix caused sporadic handshake failures and ROOM_STATE_PATCH decode errors on rooms with larger initial state. Buffer partial data across reads with a FrameReassembler and dispatch only complete length-prefixed frames. Applied symmetrically to the SDK (H3Transport) and server (H3Client) bidi + datagram readers. Closes #934 — thanks @anaibol for reporting and the initial fix. Assisted-by: Claude Opus 4.7
fix(vite): express interop, middlewareMode support, async express cal…
…lback
- Express ESM/CJS interop: (await dynamicImport('express')).default could
resolve to undefined in some module-loader setups, silently warning
'Express not available'. Accept both shapes via expressModule?.default
?? expressModule.
- Support Vite in middlewareMode: new httpServer plugin option lets users
hosting Vite inside a parent HTTP server (e.g. Express + GraphQL)
supply their own http.Server for the WS transport to attach to.
Replaces the misleading 'Vite HTTP server not available' error.
- Await config.options.express(app) so async setup (e.g. apolloServer
.start() before mounting expressMiddleware) resolves before the
server begins serving.
- core: type express callback as () => Promise<void> | void, match
beforeListen; await options.express(app) in Server.attach() for the
same async-correctness fix in the non-Vite path.
bundles/colyseus 0.17.9 -> 0.17.10
@colyseus/core 0.17.41 -> 0.17.42
fix(vite): express interop, middlewareMode support, async express cal…
…lback
- Express ESM/CJS interop: (await dynamicImport('express')).default could
resolve to undefined in some module-loader setups, silently warning
'Express not available'. Accept both shapes via expressModule?.default
?? expressModule.
- Support Vite in middlewareMode: new httpServer plugin option lets users
hosting Vite inside a parent HTTP server (e.g. Express + GraphQL)
supply their own http.Server for the WS transport to attach to.
Replaces the misleading 'Vite HTTP server not available' error.
- Await config.options.express(app) so async setup (e.g. apolloServer
.start() before mounting expressMiddleware) resolves before the
server begins serving.
- core: type express callback as () => Promise<void> | void, match
beforeListen; await options.express(app) in Server.attach() for the
same async-correctness fix in the non-Vite path.
bundles/colyseus 0.17.9 -> 0.17.10
@colyseus/core 0.17.41 -> 0.17.42
fix(sdk): isolate debug.js panel in Shadow DOM
Mount all debug UI (logo, menu, panels, modals, injected <style>s) inside
a single open shadow root so page-level CSS like `canvas { width: 100vw }`
cannot reach in and stretch the sparkline graphs or restyle the panel.
Outside-click detection uses event.composedPath() since e.target is
retargeted to the host for document-level listeners.
fix(traefik): support IPv6 internalAddress - parseHostPort() handles bare IPv4, host:port, bare IPv6, and bracketed IPv6 ([::1]:2567) per RFC 3986 - buildInternalUrl() brackets IPv6 hosts when constructing the registered URL - autoDetectInternalIP() falls back to non-link-local IPv6 when no routable IPv4 is available (Railway, IPv6-only private nets) - Add 7 test cases covering IPv4/IPv6 parsing variants - Bump @colyseus/traefik to 0.17.7
fix(sdk): correct client.http.* type inference when query/params unde…
…clared
RequiredOptionKeys guarded branches with `extends object`, which is `true`
for `undefined` under `strictNullChecks: false`. Combined with better-call's
`Record<string, any> | undefined` default for undeclared query/params, the
guard let HasRequiredKeys run against an index signature and flag the slot
as required — forcing users to pass `{ query: {}, params: {} }` on every
call. Replace the guards with checks immune to null-check mode:
IsAny for body (undeclared body = `any`), and `string extends keyof
NonNullable<…>` for query/params to detect the fallback index signature.
Closes #933 — thanks @thedomeffm for reporting.
feat(vite): first-class Vite plugin with HMR and production builds Colyseus Vite plugin integrating game server into Vite's dev server and build pipeline via the Environment API. Dev mode: - Shares Vite's HTTP server — all routes on the same origin - HMR with room state preservation and automatic client reconnection - matchMaker.hotReload() for lightweight room cycling without infrastructure teardown - Module isolation fix: externalize all deps so matchMaker singleton is shared — monitor, playground, and user code see real room data Production: - Virtual server entry generates standalone dist/server/server.mjs - serveClient option serves built client via express.static() with SPA fallback Core changes: - defineServer() returns config-only object in dev mode - Add matchMaker.hotReload() export - Export setDevMode from @colyseus/core
feat(vite): first-class Vite plugin with HMR and production builds Colyseus Vite plugin integrating game server into Vite's dev server and build pipeline via the Environment API. Dev mode: - Shares Vite's HTTP server — all routes on the same origin - HMR with room state preservation and automatic client reconnection - matchMaker.hotReload() for lightweight room cycling without infrastructure teardown - Module isolation fix: externalize all deps so matchMaker singleton is shared — monitor, playground, and user code see real room data Production: - Virtual server entry generates standalone dist/server/server.mjs - serveClient option serves built client via express.static() with SPA fallback Core changes: - defineServer() returns config-only object in dev mode - Add matchMaker.hotReload() export - Export setDevMode from @colyseus/core
PreviousNext