Enforce room ID uniqueness
Author: jldinhCreated Oct 29, 2021Updated Apr 5, 2026
Labels:rocket: feature🏟 matchmaking
Steps to Reproduce (for bugs)
- Setup a colyseus cluster with 2 servers and a colyseus proxy (Redis presence and Mongo driver)
- Create a room with a filter, inspired by step 1 of https://docs.colyseus.io/colyseus/how-to/password-protect-room/
gameServer
.define("battle", BattleRoom)
.filterBy(['password'])- In the
onCreateofBattleRoom, assign a customroomId
async onCreate(options: any) {
this.roomId = options.password;
}- Use
joinOrCreatesimultaneously from many clients, with the samepassword - Multiple rooms with the same ID get created, which is at least a problem for the client method
joinBy. It seems clients still get split into multiple rooms even if I sort the rooms by ascending creation date.
Context
I was trying to create rooms with a fixed ID matching an ID provided by another service, but this seems to break joinOrCreate.
This seems to be due to a race condition in the finding of a suitable room, which checks there is no room available, then creates one. If two requests are processed simultaneously, two rooms will be created.
I tried making the roomId index in MongoDB unique, but as the colyseus server did not handle the database errors appropriately, I did not investigate this further.
It seems to me we either need:
- to query the DB again for the best available room after creating one
- to make roomIds unique in the DB, and re-query the DB if room creation fails
Your Environment
- Colyseus Version: 0.14.20
- Node.js Version: 14.17.4
- Operating System and version: Ubuntu 20.04
Source: colyseus/colyseus