GitHub Documentation Patreon donate button

SchemaSerializer error



  • I'm trying to migrate an existing project to version 0.11 so I resolved to start from scratch because it was yielding an error but the error remains. Here's the code:

    index.ts

    import http from 'http';
    import express from 'express';
    import { Server } from 'colyseus';
    import cors from 'cors';
    
    import { StateHandlerRoom } from './rooms/room';
    
    const port = Number(process.env.PORT || 2567);
    const app = express();
    
    app.use(cors());
    app.use(express.json());
    
    const server = http.createServer(app);
    const gameServer = new Server({ server });
    
    gameServer.define('room', StateHandlerRoom);
    
    gameServer.listen(port);
    console.log(`Listening on ws://localhost:${ port }`);
    

    room.ts

    import { Room, Client } from 'colyseus';
    import { Schema, type, MapSchema } from '@colyseus/schema';
    
    export class Player extends Schema {
        @type("number")
        x = Math.floor(Math.random() * 400);
    
        @type("number")
        y = Math.floor(Math.random() * 400);
    }
    
    export class State extends Schema {
        @type({ map: Player })
        players = new MapSchema<Player>();
    
        something = "This attribute won't be sent to the client-side";
    
        createPlayer (id: string) {
            this.players[ id ] = new Player();
        }
    
        removePlayer (id: string) {
            delete this.players[ id ];
        }
    
        movePlayer (id: string, movement: any) {
            if (movement.x) {
                this.players[ id ].x += movement.x * 10;
    
            } else if (movement.y) {
                this.players[ id ].y += movement.y * 10;
            }
        }
    }
    
    export class StateHandlerRoom extends Room<State> {
        maxClients = 4;
    
        onCreate (options) {
            console.log("StateHandlerRoom created!", options);
    
            this.setState(new State());
        }
    
        onJoin (client: Client) {
            this.state.createPlayer(client.sessionId);
        }
    
        onLeave (client) {
            this.state.removePlayer(client.sessionId);
        }
    
        onMessage (client, data) {
            console.log("StateHandlerRoom received message from", client.sessionId, ":", data);
            this.state.movePlayer(client.sessionId, data);
        }
    
        onDispose () {
            console.log("Dispose StateHandlerRoom");
        }
    
    }
    

    and in React I'm doing:

    this.client = new Client("ws://localhost:2567");
    this.room = this.client.joinOrCreate('room').then(room => {
        console.log('---> JOIN BATTLE: ', this.room);
    }).catch(e => {
        console.log('---> JOIN BATTLE FAILED!!!: ', e);
    });
    

    can't seem to get past this error:

    Error: SchemaSerializer error. See: https://docs.colyseus.io/migrating/0.10/#new-default-serializer
        at SchemaSerializer.reset (/SERVER/node_modules/colyseus/lib/serializer/SchemaSerializer.js:13:19)
        at StateHandlerRoom.setState (/SERVER/node_modules/colyseus/lib/Room.js:109:26)
        at StateHandlerRoom.onCreate (/SERVER/rooms/room.ts:42:14)
        at /SERVER/node_modules/colyseus/lib/MatchMaker.js:215:28
    

  • administrator

    Hi @hlarcher, this error is most likely to happen when having a previous version of @colyseus/schema listed under your package-lock.json. Please remove your package-lock.json + node_modules, and run npm install again. It should get rid of this error. Cheers!



  • Great, that was exactly it!

    However after migrating now every joinOrCreate creates a new room, I have this:

    gameServer.define('room', BattleRoom);
    

    and this:

    onJoin(client: Client, options: any) {
        console.log('onJoin', Object.keys(this.state.teams).length);
        if (Object.keys(this.state.teams).length === 2) {
            this.lock();
        }
    }
    

    debug is always "onJoin 0".



  • it seems it is not a server side problem but rather a client one.

    the server is implemented like this:

    onJoin(client: Client, options: any) {
        if (Object.keys(this.state.teams).length === 2) {
            this.lock();
        } else {
            // add team
            this.state.addTeam(client.sessionId, options.team);
    
            // start if we have both teams
            if (this.state.teamCount === 2) {
                this.state.startBattle();
    
                // broadcast new team
                this.broadcast({
                    type: 'STARTED',
                    state: this.state,
                });
            }
        }
    }
    

    and the client is implemented like this:

    this.room = this.client.joinOrCreate('battle', {team}).then(room => {
        room.onJoin(() => this.onRoomJoin(team));
        room.onStateChange((state) => this.onRoomStateChange(state));
        room.onMessage((message) => this.onRoomMessage(message));
        room.onError(() => this.onRoomError());
        room.onLeave(() => this.onRoomLeave());
    }).catch(e => {
        console.log('---> JOIN BATTLE FAILED!!!: ', e);
    });
    
    onRoomMessage = message => {
            console.log('---> ON MESSAGE: ', this.client.id, this.room.name, message);
    }
    

    but the onRoomMessage method is never called


  • administrator

    Hi @hlarcher,

    Here's a modified version to work on v0.11:

    // no assignment, as the return value is Promise
    this.client.joinOrCreate('battle', {team}).then(room => {
        this.room = room; // here's the room instance!
    
        // on join has been successful already!
        this.onRoomJoin(team)
        // room.onJoin(() => this.onRoomJoin(team));
    
        room.onStateChange((state) => this.onRoomStateChange(state));
        room.onMessage((message) => this.onRoomMessage(message));
        room.onError(() => this.onRoomError());
        room.onLeave(() => this.onRoomLeave());
    }).catch(e => {
        console.log('---> JOIN BATTLE FAILED!!!: ', e);
    });
    


  • Awesome, thanks :)


 

GitHub Documentation Patreon donate button

© 2020 Endel Dreyer