GitHub Documentation

[Defold] ERROR:WEBSOCKET: Failed to setup callback when player joins room



  • Hi all,

    I have code that functionally looks like this:

    splash.gui_script

    -- When the user presses Create Game
    function create_game()
        client:join_or_create("lobby", {}, function(err, _room)
            if err then
                print("Failed to create the lobby:", err)
                return
            end
            room_module:set_room(_room)
        end)
    end
    
    create_game()
    r = room_module:get_room()
    if r and r.state.players and r.state.players[r.sessionId] then
        msg.post("main:/loader", "load_level")
    end
    

    room.lua

    local M = {}
    
    function M.set_room(the_state, r)
        the_state.room = r
    end
    
    function M.get_room(the_state)
        return the_state.room
    end
    
    function M.add_callbacks(the_state)
        add_callbacks(the_state.room)
        print("Added room callbacks")
    end
    
    function M.new(r)
        local state = {
    	room = r
        }
        return state
    end
    
    function add_callbacks(room)
        room.state.players.on_add = function(player, sessionId)
    	print("new player", sessionId, player)
        end
    end
    

    loader.script

    local function load_level(self)
        msg.post("#level", "load")
    end
    
    function on_message(self, message_id, message, sender)
        if message_id == hash("load_level") then
            unload_splash(self)
    	load_level(self)
        end
    end
    

    level.script

    local room_module = require "room"
    
    function init(self)
        room_module:add_callbacks()
    end
    

    Functionally this is how it works:

    1. Load into main menu (splash).
    2. Press create game, which causes the code in splash.gui_script to run.
    3. The room object is created and stored globally in room.lua.
    4. splash.gui_script sends a message to loader.script to tell it to unload the splash and load the level.
    5. The level calls add_callbacks to add the callbacks to room. This ostensibly works correctly, because I see Added room callbacks after this point.

    What I expect to happen is, after this point, if someone joins the game, I should see a message like this:

    new player <session_id> <player>
    

    However instead I see this:

    ERROR:WEBSOCKET: Failed to setup callback
    

    Importantly, I only see this error when the second player joins the room, not when I add the callbacks.

    My schema pretty much looks like this:

    export class MyLobbyRoomState extends Schema {
      @type({ map: Player })
      players = new MapSchema<Player>();
    }
    

    Player itself just has 3 fields in it: x: number, y: number, and name: string.

    As far as I can tell, everything looks fine in the backend. I have logging that shows the two players connect:

    onCreate: Created room: KRafbAeo9
    onJoin: Joined: KRafbAeo9
    onJoin: Options: []
    Connected clients: [ 'kQITKomRu' ]
    onJoin: Joined: KRafbAeo9
    onJoin: Options: []
    Connected clients: [ 'kQITKomRu', 'CHaf_yUQm' ]
    

    If I add the callbacks immediately in set_room in room.lua, the callback works at first (it gets called for my own player joining). Later however, when the second player joins, I see the same websocket error, instead of the callback being called for the second player, which is very strange.

    Furthermore, even if I could get that approach to work, it is too early to register the callbacks because at that point, the level has not loaded yet, since I join the room first and then load the level. I also feel like this is still a race, since the state change may happen before I assign the callback. The current approach, where I add the callbacks later, has the same problem. It seems to imply that I have to process the initial state first before relying on the callbacks on state change. Instead, I would love most of all to have all the callbacks get called retroactively based on the initial state. For example, if there are 2 players when someone joins, the callbacks for state.players.on_add gets called twice, but only after I have assigned the callback.

    So two questions:

    1. How do I get more details about this error, ERROR:WEBSOCKET: Failed to setup callback. Currently it is very opaque, it doesn't tell me what specifically failed in setting up the callback.
    2. What is the best way to get it that I only have to write callbacks for state changes, instead of that and an additional function that processes the initial state. When I look at examples like this or this by @endel they seem to just set the callbacks without doing any initial state processing, so I feel this must be possible.

    Any help would be very much appreciated!


  • administrator

    Thanks for reporting @banool, I've replied to your post on the Defold forums as it might involve their WebSocket extension: https://forum.defold.com/t/colyseus-error-failed-to-setup-callback-when-player-joins-room/68165


 

© 2021 Lucid Sight, Inc