Nakama Client Realtime Callback Issues

Hello, I’m creating a game using Nakama client and I’m facing a issue that my realtime.on_match_presence_event doesn’t work when I change collection. Has anyone else had this problem?

Detailed information below:

==========

To start, I have a module (nakama_api) to help with Nakama information and handle functions like this one in xoxo example (game-xoxo-nakama-client/main/xoxo_nakama.lua at main · defold/game-xoxo-nakama-client · GitHub). My environment has 3 collections: Main, Menu and Game. Main collection uses nakama_api to initialize Nakama client and after that loads the Menu proxy collection. Menu has a button to connect the socket, authenticate the user and create/connect a match using nakama_api module , In the Game I have a list to show all players connected to the match. To simplify, I put a debug message in realtime.on_match_presence_event inside my nakama_api module.

realtime.on_match_presence_event(socket, function(message)
logger.debug(“NakamaClient”, “Match presence update for match: %s”, message.match_presence_event.match_id)
end

I tested it 2 different ways, in the first one (where I don’t change collections) everything works fine. I login with the first client and can see all debug messages about the connection and the on_match_presence_event callback function. After this I login with a second client, and the first one receives the on_match_presence_event of the second client as I expected. I checked the information on Nakama Server Console, and I see there are two players connected in the match as desired.

The second test is the test with problem. In this, I login with the first player as before, but change from the menu collection to the game collection before logging in the second player. When I login the second client, the first one doesn’t receive the on_match_presence_event of the second client as expected. However, checking Nakama server console and logs I can see that are 2 players connected in the same match, and the server processed the player 2 presence events and broadcast it to player 1 as I expected. But the player 1 client didn’t process the callback.

I don’t understand why only unloading the menu collection proxy and loading the game collection proxy would disable the on_match_presence_event callback, since I’m using a module and can check that some information like the stored client, socket, match_id are propagated properly.

I put a small part of the client and server log of each test below.

Here is the player 1 client log of my first test case, we can see that it process presence events 2 times, 1 for each player.
DEBUG:SCRIPT: [18:01:57] [INFO] [NakamaClient] Session context updated: 1 players in match
DEBUG:SCRIPT: [18:01:59] [INFO] [NakamaClient] Session context updated: 2 players in match

Here is the server log my first test case, we can see that it process presence events 2 times.
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:01:57.236Z”,“caller”:“server/session_ws.go:412”,“msg”:“Sending *rtapi.Envelope_Match message”,“uid”:“26717e63-455e-417a-812f-ea40f0a12aaf”,“sid”:“e1b296ec-90e4-11f0-bb60-30bf2c4c5d91”,“envelope”:“cid:"1" match:{match_id:"02783dc7-a172-47d7-b0d9-e05e44101cae.ponder_nakama" authoritative:true label:{value:"{\"created_at\":1757775882426,\"current_players\":0,\"game_id\":\"tech-stack-test-defold-game\",\"last_updated\":1757797310493,\"max_players\":90,\"status\":\"waiting\",\"world_id:1757775882426,\"current_players\":0,\"game_id\":\"tech-stack-test-defold-game\",\"last_updated\":1757797310493,\"max_players\":90,\"status\":\"waiting\",\"world_id\":\"world_001\"}"} self:{user_id:"26717e63-455e-417a-812f-ea40f0a12aaf" session_id:"e1b296ec-90e4-11f0-bb60-30bf2c4c5d91" username:"emVjchGviE"}}”}
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:01:57.237Z”,“caller”:“server/tracker.go:912”,“msg”:“Processing presence event”,“joins”:1,“leaves”:0}
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:01:59.204Z”,“caller”:“server/session_ws.go:412”,“msg”:“Sending *rtapi.Envelope_Match message”,“uid”:“f73d8bf7-118d-4497-b22f-6d3b8ff58ec9”,“sid”:“e2dee8be-90e4-11f0-bb60-30bf2c4c5d91”,“envelope”:“cid:"1" match:{match_id:"02783dc7-a172-47d7-b0d9-e05e44101cae.ponder_nakama" authoritative:true label:{value:"{\"created_at\":1757775882426,\"current_players\":1,\"game_id\":\"tech-stack-test-defold-game\",\"last_updated\":1757797317235,\"max_players\":90,\"status\":\"waiting\",\"world_id\":\"world_001\"}"} size:1 presences:{user_id:"26717e63-455e-417a-812f-ea40f0a12aaf" session_id:"e1b296ec-90e4-11f0-bb60-30bf2c4c5d91" username:"emVjchGviE"} self:{user_id:"f73d8bf7-118d-4497-b22f-6d3b8ff58ec9" session_id:"e2dee8be-90e4-11f0-bb60-30bf2c4c5d91" username:"amlqXDaVwW"}}”}
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:01:59.204Z”,“caller”:“server/tracker.go:912”,“msg”:“Processing presence event”,“joins”:1,“leaves”:0}

And here is the player 1 client log of my second test case, we can see that it didn’t process presence events 2 times.
DEBUG:SCRIPT: [18:07:31] [INFO] [NakamaClient] Session context updated: 1 players in match

Here is the server log my second test case, we can see that it process presence events 2 times as expected.
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:07:31.958Z”,“caller”:“server/session_ws.go:412”,“msg”:“Sending *rtapi.Envelope_Match message”,“uid”:“26717e63-455e-417a-812f-ea40f0a12aaf”,“sid”:“a934d594-90e5-11f0-bb60-30bf2c4c5d91”,“envelope”:“cid:"1" match:{match_id:"02783dc7-a172-47d7-b0d9-e05e44101cae.ponder_nakama" authoritative:true label:{value:"{\"created_at\":1757775882426,\"current_players\":0,\"game_id\":\"tech-stack-test-defold-game\",\"last_updated\":1757797623477,\"max_players\":90,\"status\":\"waiting\",\"world_id\":\"world_001\"}"} self:{user_id:"26717e63-455e-417a-812f-ea40f0a12aaf" session_id:"a934d594-90e5-11f0-bb60-30bf2c4c5d91" username:"emVjchGviE"}}”}
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:07:31.958Z”,“caller”:“server/tracker.go:912”,“msg”:“Processing presence event”,“joins”:1,“leaves”:0}
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:07:38.424Z”,“caller”:“server/session_ws.go:412”,“msg”:“Sending *rtapi.Envelope_Match message”,“uid”:“f73d8bf7-118d-4497-b22f-6d3b8ff58ec9”,“sid”:“ad0f6d25-90e5-11f0-bb60-30bf2c4c5d91”,“envelope”:“cid:"1" match:{match_id:"02783dc7-a172-47d7-b0d9-e05e44101cae.ponder_nakama" authoritative:true label:{value:"{\"created_at\":1757775882426,\"current_players\":1,\"game_id\":\"tech-stack-test-defold-game\",\"last_updated\":1757797651957,\"max_players\":90,\"status\":\"waiting\",\"world_id\":\"world_001\"}"} size:1 presences:{user_id:"26717e63-455e-417a-812f-ea40f0a12aaf" session_id:"a934d594-90e5-11f0-bb60-30bf2c4c5d91" username:"emVjchGviE"} self:{user_id:"f73d8bf7-118d-4497-b22f-6d3b8ff58ec9" session_id:"ad0f6d25-90e5-11f0-bb60-30bf2c4c5d91" username:"amlqXDaVwW"}}”}
nakama-local | {“level”:“debug”,“ts”:“2025-09-13T21:07:38.424Z”,“caller”:“server/tracker.go:912”,“msg”:“Processing presence event”,“joins”:1,“leaves”:0}

I’m reacting to “when I change collection”. If you unload the collection from where you set a listener or started a coroutine it will not fire. Is this the case?

2 Likes

Hello @britzl , thank you for the answer. I’m not sure about if it’s my case but could be.

The nakama.sync is called inside my module function, but this module function is triggered by a script inside my menu collection. Does this relationship bound the coroutine with my menu collection? If it’s true, I think it could be problem.

And is the menu collection unloaded? If that is the case then your code will not run correctly as far as I remember. It should be quick for you to validate if this is the case or not.