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:
- Load into main menu (splash).
- Press create game, which causes the code in
splash.gui_script
to run. - The room object is created and stored globally in
room.lua
. splash.gui_script
sends a message toloader.script
to tell it to unload the splash and load the level.- The level calls
add_callbacks
to add the callbacks to room. This ostensibly works correctly, because I seeAdded 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:
- 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. - 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!