Schema handshake problem between server and unity client

Hi developers,

Did you guys try to use colyseus continuously develop some game? Just like you publish game A and later game B, but use the same server to hold these two games. I meat a problem.

I develop game A and publish, example, a write codes about AGameRoom extends Room and AGameState extends Schema, and then I publish game A.

Then I write codes about BGameRoom extends Room and BGameState extends Schema, i add the code to the same server and restart. The different game player will enter different game room and use different game logic.

Then the game A unity client will crash at the Schema's implicit method 'handshake', because the server side has AGameState and BGameState, but game A client only has AGameState.

How can I solve this?

I read the schema source code, and I found context may help. Did anyone has the same problem like me? Thanks.

Hi @jiabuda, I'm glad you're enjoying it and using it for your second game!

You're right about the Context. By default the @type() annotation is going to use a "global context". By having all structures inside the global context, they're all going to be synched during handshake.

I'm restructuring most of @colyseus/schema lately, and I'm going to add a utility to help with this, as follows:

import { type, Context, DefinitionType } from "@colyseus/schema";

function createContext() {
    const context = new Context();
    return function (definition: DefinitionType) {
        return type(definition, context);
    }
}

You can use this function to generate a special @type() that is going to bind to a specific context, so you can use a different one for each of your games. Example:

// "game1.ts"
export const type = createContext();

// other file
import { type } from "./game1";

class State extends Schema {
  @type("string") // ... your definitions as usual
}

This utility is going to be available as Context.create() on a next version!

Hope this helps. Cheers!

@endel

Thanks endel, I use the same way as you provide above. And the u3d colleague already annotate the code inside handshake to prevent schema check. Cause we check the same code in colyseus.js, we found js type client did not check the schema.

I think the schema should bind with specific room but not a context? How do you think about it.

@endel

And another problem, when A game and B game share the same schema, that would be a problem.

gameA use PlayeInfo Schema in ARoomSchema and gameB use PlayerInfo too in BRoomSchema. That would be a situation, the PlayerInfo could only implement one specific context but not two.