Lobby in Fish Game

I’m trying to implement a simple lobby inside the Unity fish game used in the tutorial. What I’m trying to understand is the right sequence to use for ReceivedMatchmakerMatched, ReceivedMatchPresence and JoinMatchAsync.
I would like for the lobby to behave like this:

  • Waiting for 4 users (fixed number) to login and join the lobby
  • Get the current number of players waiting in the lobby (to show in the UI)
  • Start the game automatically ONLY when all 4 players have joined the lobby

Thank you


Hi devnull,

Sure I can guide you. I also recommend looking at the following resources:

The correct flow is to first setup a matchmaker listener and add the client to the matchmaker.

Then handle the ReceivedMatchmakerMatched event and join the match JoinMatchAsync with the matchmaker matched token matchmakerMatched:

socket.ReceivedMatchmakerMatched += async matchmakerMatched => {

var match = await socket.JoinMatchAsync(matchmakerMatched);


var matchmakingTicket = await socket.AddMatchmakerAsync(query, minPlayers, maxPlayers);

You can alternatively join a match via an id or name if the match is being shared amongst friends. See Joining matches for more examples.

Once you have joined a match, listen to ReceivedMatchPresence events for people joining and leaving the match.

The rest of the logic like, checking player numbers and changing match state (lobby, playing) is up to you to implement.

You could elect one client to do the logic, communicate by sending data messages and store game specifc match state on the client.

Alternatively you can do it on the server by writing your logic in various events as server runtime code in TypeScript/JavaScript Go, or Lua.

Note: Fish Game uses client relayed multiplayer.

Kind regards,

Hi Sean,
first of all thank you for your answer.

Thank you for the links.
In the first one I noticed that there’s no link to the source code for the Among Us-like game, is it generally available? I think it could be really useful (I’ve already saw the code for the other demos).


Good to know

Ok, know I’ve got some questions:

  1. if I understand correctly ReceivedMatchmakerMatched is raised when Nakama creates a match after finding all the players with the right properties. If that’s the case, is it possible to get how many players are waiting in a matchmaking state BEFORE the match is created?

  2. About ReceivedMatchPresence, I don’t want to let players join after the match is started (only re-join in case of network errors) but I saw in the Fish Game that Presences are stored inside IEnumerable<IUserPresence> Presences and I can count them.
    So, can I “twist” the original Presences behaviour and use them not for joins/leaves but for counting the players in the lobby?

Sounds clear

Thank you again for your help and sorry for the long post, I hope it’s clear enough.


Hey @devnull

1. Matchmaking

Matchmaking is an asynchronous request which either returns a successful matchmaking ticket (not the actual Match) or times out based on your server matchmaking timeout configuration. Matchmaking is for finding users based on criteria and is not tied to matches, it is not match listing (searching).

If you adjust the matchmaking criteria to a minimum and maximum of 4 players, when 4 matchmaking players are found they will all receive the ReceivedMatchmakerMatched event at roughly the same time and they they can each call JoinMatchAsync with the same matchmaker ticket.

The first player to call join will have the actual Match created on the server, the rest will join it. After joining the match, the match will have 1-4 presences in it as players joining asynchronously. You can check when there are 4, or communicate via sending messages, to trigger game specific logic.

See how the Matchmaker event and Match creation/joining are separate. This is intentional so matchmaking could also be used to form a group, party, chat, etc.

2. Preventing players joining active matches

Since Matchmaking never returns actual Matches only players looking to create/join a match together, players won’t be able to join active matches using matchmaking.

In your game client you will Matchmake to find 3 other players, join a Match, and when the Match ends Matchmake again or perhaps create a Match with the same players.

If a player dropped out during a match, they could rejoin using the match id. Other players won’t be able to find the match without you explicitly developing the feature to list, filter and join matches.

Game lobby

I wouldn’t associate Matchmaking with what you are thinking of as a pre-game lobby.

  1. Matchmaking looks for other players
  2. While players are matchmaking show a progress screen with a timer
  3. Enough players are found and they create/join a match
  4. Your game elects a player to be the leader, or use some other system like player voting
  5. Your game puts players into a “lobby” state first where they can chat and set match specific settings etc
  6. The leader, or by voting, progresses the match from the “lobby” state to the “playing” state

How you handle states, lobbies, rounds etc within a match is up to you.

Let me know if you have any further questions.

Kind regards,

Hi Sean,
sorry for the delayed response, it was a busy week.

Ok I got it now, thank you

Ok, all clear now

Ok, so in the fish game I still need this

NakamaConnection.Socket.ReceivedMatchPresence += m => mainThread.Enqueue(() => OnReceivedMatchPresence(m));

or can I avoid to listen to the event (and delete the respective callback)?

I think that it was really helpful, thank you again for your support


Hi Sean,
another question, can you explain to me why the 3rd party UnityMainThreadDispatcher is present in the fish game but not in the pirate panic demo?

Thank you


Hi @devnull,

The reason for this is simply due to the fact that the useMainThread argument of the client.NewSocket function didn’t exist when Fish Game was originally developed. Instead of using a third-party solution for this you should instead create a socket like so:

var socket = client.NewSocket(true);

All socket event callbacks will now run on the main thread.

Kind regards,

Hi Tom
thank you so much for you answer.
I tried your solution and It’s working, now I can remove the third-party solution.

Before I asked why there’s no link to the source code for the Among Us-like game example, can you help me with that? Because I think it would be useful as a reference.

Thanks again for all the huge help so far.


I’m glad you were able to get it working.

With regards to your question about the source code for the Among Us game; as it stands the client guides are designed around a hypothetical game so that we could document the full spectrum of functionality within each client SDK in a meaningful and contextually relevant way. Therefore there is no source code beyond that already available in the client guides that we can share.

That’s ok, thank you for your reply.