Questions about using Groups for a pre-Match lobby

Hello everyone,

Me and my friends are making a competitive game where you play by matches (not like a MMO, where the game is always happening, more like a MOBA).
We are using the Match api everything is looking good so far.

For the sake of private testing we want to have a “pre game lobby” to make custom games, where people can join and set their roles as players or spectators before the game start. Anyone who ever played a competitive game like League of Legends or CS:GO will see what i mean.

For now, i implemented the pre game lobby with the match api. Basically when the macth is created it is in “lobby mode”, players can join and leave, then we have an opcode to start the game and the state changes to “game mode”.
Looking back at it i really don’t like having the lobby along with the game logic in the match and i want to change that.

My first idea was to make another match that would serve as a lobby but it still felt wrong.

By digging into the documentation i found this page that speaks about using groups to make long term matchs with no real time functionalities.
Naturally i thought about using groups to make my pre match lobby and i think this is the best answer to my needs.

So here are my questions:

  1. Are groups indeed the best answer to this problem ? I’m pretty sure it is but still i’d appreciate if someone have better suggestions.

  2. By digging the client libraries documentation (.NET) i realized that you can create groups and do basic operation without additionnal backend code (like the client.CreateGroupAsync() function for example).
    While this looks very convenient i don’t really like the idea of clients being able to create groups without the possibility to prevent potential abuse. Also, since i’m going to need RPCs to update group metadata i’d rather have every group functionnalities as RPCs i think.
    So the question is: Can you add control over these features in some way ? (some kind of middleware)
    Maybe i’m just bad at digging the doc but i didn’t find much info on this topic.

(also sorry if bad english)

I think your original solution to using the existing match as a lobby is the best approach. While it does potentially overload the responsibility of the match if you aren’t careful, if you design the states properly you should be okay. Is there a particular reason why you don’t like your current solution?


Sorry for bumping the topic but i wanted to answer the question.
There is a few reason as to why i didn’t like lobbies being managed in the match:

  • I’m not too fond of excessive encapsulation but idk it just feels wrong to have both the lobby and the match itself in the same place. For example later into the development we will want players to play the game via matchmaking (making lobbies would just be for custom games), by separating the lobby and the match itself i don’t have to touch the match code at all i just reuse it as is(or with minor adjustments) when adding the matchmaking.
    If i have the lobby features in the match it starts being messy and look like bad design (even if it would be probably manageable somehow).
  • You can’t manage a match from outside the match (there are workarounds i guess but still…).
  • Error management imo is cleaner with RPCs, if something goes wrong while doing something in the lobby you get an exception and handling is much much easier than with match states. With rpc, on the client code, i just await the rpc call and the error handling fits in a single function. With match states, the problem is that there is no responses to match states, so if i try to do something that needs a validation from the server i would need to wait for another match state from the server, and linking a ‘request’ to a ‘response’ with match state is doable but would require some work and be potentially messy.

I’ve stuck to the idea of using groups for our lobby and reworked the whole thing by now. Honestly i’m very happy overall, everything goes well and is much cleaner imho.

There is only one thing that i would rant about if you don’t mind (should i create another topic for this matter ?):

  • The fact that group metadata has to be a map[string]interface{}, i know that it is the way of representing an json object but i just prefer using structs with json tags and then marshal them if necessary. Here i’m forced to use a map which is potentially messier and harder to maintain. Also when getting a group, the metadata is given as a string anyway, why not just use an interface{} for metadata when creating/updating a group ? Or even a string ? (i guess there is a good reason why but i don’t see it). Also i have the same opinion on the MatchCreate() function for the params parameter and the payload of the notification system.

Once again sorry for bumping. Also sorry if bad english.

Hi @Nellousan,

Thanks for the update. I’m glad to hear you were able to come up with a solution that works for your project. We’ve just released a guide on implementing a lobby system using the same match handler if you would like to check it out. To your point about using the handler without a matchmaker that can also be handled via match params which we dive into a little in the linked guide for making private/public matches. Nakama: Creating a Lobby System | Heroic Labs Documentation

For your second question, please create a new thread and we can discuss this further there.


1 Like