State update and onJoin timing

Hi everyone!

Hope to find you all well.
I'm having a few issues trying to integrate Colyseus with Phaser 3, so maybe someone can give me an idea here...

The flow I have is like:
1 - You hit the main page with the login form.
2 - The user and password are validated in the DB on the Colyseus.Room.onAuth method (using a Promise, not the async method / wait).
3 - On success this returns all the user data and last state (scene and position).
4 - On client side, in Colyseus.Room.onJoin I made visible the Phaser3 game container > the main player is created, an Scene is started and the player is assigned to that Scene in Phaser3.


  • The first issue is on #3 from the flow.
  • On the client-side I need to get that scene and position from the server and if I use the Colyseus.Room.onJoin at that point I still don't have the user data available for the client. If I put a console.log like room.state, at that point state is an empty object, but if I run that same log later "manually" the data is available, so basically I need to delay the onJoin in the client side until I can access the data.
  • Could I be missing something on the onAuth Promise or it will be better to just use async/wait?
  • Maybe there's a way that I could be missing to access the player data?
    I don't know, something like: room.onJoin.add(function(dataFromJoinedUser){
  • Maybe I could return a Promise on onJoin in the server side to wait for the client creation and delay the onJoin event on client side until the state and server were created to be able to get them in the client side after that?

This is actually a probably bad practice or hack to make it work as I need.
Ok... That said and since I wasn't able to make it work, I made a "delayed" action, basically in the Server Room, I put something like:

    onJoin(client, options, auth)
        // player creation:
        this.state.createPlayer(client.sessionId, auth);
        // client creation:
        this.send(client, {act: share.CREATE_PLAYER, id: client.sessionId, player: this.state.players[client.sessionId], players: this.state.players});
        this.broadcast({act: share.ADD_PLAYER, id: client.sessionId, player: this.state.players[client.sessionId]});

It works like a charm the player is created, the proper scene is started and everything is in the correct position, BUT neither less to say that's like horrible way avoid most of the Colyseus best stuff (room.onJoin and room.listen for the attribute add, like in the Colyseus examples).

In between issues 1 and 2, I found the following case:

  • You login with the first player, all good on the four steps from the flow.
  • But then you login with another player, and here's the weird stuff: the second player is not created, because the first player logged is tried to be create first.
    So the state changes received by the second-client are been sent before the onJoin happens, like:
  • Player A is logged > onJoin is sent to Player A > other state changes are sent to Player A.
  • Player B is logged > the state from player A is received > the onJoin from Player B happens.

Is this clear for you what's the issue?
I though that it could be because the order of the room.state.players in server-side was probably considered and since I was using state.players[] and the state.players[] I was getting the stuff on the client side in that order, but then I change it to use Object.assign to reorder as needed but it didn't work, I was still getting the PlayerA state update before the PlayerB onJoin.
I know I could probably change the way I'm creating and assigning the players on Phaser to avoid the issues and create the playerA in the scene anyway even if playerB is not "present", but in terms of application this could be an actually issue on synchronization?
The way I see it looks like an issue, if I'm clientB I would expect to get my information onJoin before the other players states updates for the first time, or I'm wrong?

I will try to publish my last updates on which is where I'm having all the issues so you can check the updated code.

As always thanks in advance for your help and this great platform!


FYI: just updated with the last code changes I made.