[Multiplayer] Lobby/Staging/Matchmaking flow: Quickstart using NetworkLobbyManager?

12/5 Ditching this post as it’s getting confusing and it’s more-or-less turned into a journal. QA said “We can’t force the devs to answer”, so I have a feeling no one knows (or maybe 1 busy person) O__o if you find this on Google, look here for a cleaner post with a more-likely answer.

11/29: Still awaiting an answer – trial and error can only go so far :confused:

11/24/2016 Added a question at the bottom (#2: How to access lobbyMgr.OnCallbacks()?). Also added testing results.

11/23/2016 Added TL;DR @ bottom in answers

11/22/2016: Added CreateMatch/OnCreateMatch and JoinMatch/OnJoinMatch.

11/20/2016: I decided to revamp everything based on my research to make this less confusing.

TL;DR: The API docs for staging, matchmaking, lobby, and anything to do with the NetworkLobbyManager component are abysmal (@Unity I know it’s new – and all your other API docs rock, so I know IN TIME, it will be awesome, it’s np – However, for now, hopefully this thread can help clarify some things for myself and others). Here is my flow to create and join a matchmaking match with lobby. Unity Staff: Please let me know where I’m wrong:


STEP I: EDITOR

  1. Create a LobbyMgr gameObj >> add NetworkLobbyManager component >> Add a NetworkManagerHUD (for testing only).
  2. Create a LobbyPlayer gameObj >> add NetworkLobbyPlayer component. Ensure “Show Lobby GUI” is checked (for testing only). Save as prefab. Delete the gameObj.
  3. Drag the LobbyPlayer prefab into NetworkLobbyManager component.
  4. Create a GamePlayer prefab >> add GamePlayer component. Save as prefab. Delete the gameObj.
  5. Drop GamePlayer prefab into NetworkLobbyManager component.
  6. Create arbitrary named LobbyMain.cs and drop it in NetworkLobbyManager component.
  7. Create a btnMM for matchmaking later. We don’t want to use the LobbyGUI by the end of this.

STEP II: SCRIPTING
Open up LobbyMain.cs

public class Lobby2 : MonoBehaviour
....
[SerializeField]
    private NetworkLobbyManager lobbyMgr;

@Unity - QUESTION: If this inherits from MonoBehaviour, how can I possibly override events such as OnMatchList() and OnMatchCreate()?

Go back to editor >> Drop in your NetworkLobbyManager component.

Now let’s add a void for our button click to StartMatchmaker and to list the matches:

public void MMStart()
{
    Debug.Log("@ startMM");
    lobbyMgr.StartMatchMaker();
    MMListMatches();
}

We now have the code to start matchmaker with some TODO’s for later.

Let’s start with listing - MM is faster if you join a game instead of create your own:

public void MMListMatches()
{
    Debug.Log("@ MMListMatches");

    int startPageNumber = 0;
    int resultPageSize = 10;
    string matchNameFilter = "*";
    bool filterOutPrivateMatchesFromResults = true;
    int eloScoreTarget = 0;                        
    int requestDomain = 0;                         

    lobbyMgr.matchMaker.ListMatches(startPageNumber, resultPageSize, matchNameFilter, filterOutPrivateMatchesFromResults, 
                                    eloScoreTarget, requestDomain, OnMatchList);
}

    void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList) 
{
    Debug.Log("@ OnMatchList");
    if (success && matchList.Count > 0)
{
    // Join 1st one found? Is this ordered by relevance? 
    // Is this ordered by players? Is there any order at all?
    MMJoinMatch(matchList[0]);
}
else
    MMCreateMatch();

lobbyMgr.OnMatchList() is recommended to use in the API doc examples, however, we cannot override the void (can’t do override void lobbyMgr.OnMatchList). We also can’t change our lobby script from Mono (our script HAS to be mono - we can’t have 2 LobbyManager classes or they’ll conflict). instead, our own callbacks are used - not sure if this is intended or a workaround (docs are a bit conflicting throughout).

So if there was something in the list, we join then callback:

    public void MMJoinMatch(MatchInfoSnapshot matchToJoin)
    {
        Debug.Log("@ MMJoinMatch");

        NetworkID netId = matchToJoin.networkId;
        string matchPassword = "";
        string publicClientAddress = Network.player.externalIP;
        string privateClientAddress = Network.player.ipAddress;
        int eloScoreForClient = 0;
        int requestDomain = 0;

        lobbyMgr.matchMaker.JoinMatch(netId, matchPassword, publicClientAddress, privateClientAddress, 
                                      eloScoreForClient, requestDomain, OnMatchJoined);
    }

 public void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        Debug.Log("@ OnMatchJoined");

        if (success && matchInfo != null)
        {
            Debug.Log("[Match] First Game Sample: " + matchInfo);
        }
        else
        {
            currentStatus = mmStatus.stopped;
            Debug.Log("[MM] FAILED to join match: " + extendedInfo);
            // TODO: Re-join queue..?
        }
    }

…or if a game wasn’t found, create one:

 public void MMCreateMatch()
    {
        Debug.Log("@ CreateMatch");

        currentStatus = mmStatus.creating;
        string matchName = lobbyMgr.matchName != null ? lobbyMgr.matchName : "MM";
        uint matchSize = lobbyMgr.matchSize != null ? lobbyMgr.matchSize : 15;
        bool matchAdvertise = true;
        string matchPassword = "";
        string publicClientAddress = Network.player.externalIP;
        string privateClientAddress = Network.player.ipAddress;
        int eloScoreForMatch = 0;
        int requestDomain = 1;

        lobbyMgr.matchMaker.CreateMatch(matchName, matchSize, matchAdvertise, matchPassword, publicClientAddress,
                                        privateClientAddress, eloScoreForMatch, requestDomain, OnMatchCreate);
        Debug.Log("[MM] Creating match..");
    }

 public void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        Debug.Log("@ OnMatchCreate");

        if (success && matchInfo != null)
        {
            currentStatus = mmStatus.created;
            Debug.Log("[MM] Created Match!"];
        }
        else
        {
            Debug.Log("[MM] FAILED to create match: " + extendedInfo);
            // TODO: Re-join queue?
        }
    }

What happens when I test this so far?

  1. A clicks matchmaking button
  2. In the background, it lists a match. List callbacks. Nothing there, so create instead of join.
  3. Game is created. Waiting…
  4. B clicks matchmaking button
    5. In the background, it SHOULD list a match and join the first[0] match - however, it detects no games in the list and simply creates a game.
  5. Both A and B awkwardly wait for each other - but both CREATED a game. Nothing happens from here.
  6. In the meantime, PlayersGUI shows nothing (because the other didn’t join - both created).

Questions/Not Clear:

  1. The OnGUI “Show Lobby GUI”, part of the Network Lobby Manager – it’s not even mentioned in the UNetLobby API docs, or anywhere. How can we make our own? I can’t find a template/snippet/bitbucket anywhere. EDIT: Found a bitbucket after all, woot :slight_smile: could use a simplified version in the docs somewhere, though using the new techniques.
  2. [11/24/2016] Even though I keep reading my LobbyScript (attached to the NetworkLobbyManager component) to be Mono, but I still am having trouble with callbacks/sync: For example, it’s recommended that I handle callbacks through the lobbyMgr lobbyMgr.OnMatchList instead of my own, such as OnMatchListCustom – whenever I test it, there’s never a game showed up on the LIST, even though it was definitely created! I have a feeling that using my own callback makes things out-of-sync…

So the big question is: Can my LobbyScript.cs derive from NetworkLobbyManager without causing a ton of conflicts and weirdness? – I tested this and sure, I can now override void OnMatchList() BUT it never gets fired! Probably because it’s on "the other lobby manager (component)?

The bigger question is: HOW can I override the callback of lobbyMgr’s OnMatchList? I can’t do override void lobbyMgr.OnMatchList because it’s a syntax error. I can’t do it with Mono script because it’s out of scope. I can’t do it with NetworkLobbyManager script because, although it’s syntax-free, it’s the wrong instance or something - it doesn’t fire. 100% of the demos just use 1 giant script instead of the NetworkLobbyManager component, so I’m confused :slight_smile:

Hey man, for what it’s worth I have also been struggling with seemingly simple unet things (for the past year…). Part of this is because the unet HLAPI is a general framework and so there is more inherent flexibility, i.e. it’s hard to show someone directly how to use it because there are so many different possible goals. In addition, networking code is inherently more complex as you will have two machines executing Unity logic in separate “threads” (a crude analogy, but still) and latency can be highly variable, depending on your setup and network conditions, making repeatability difficult. Testing takes longer too, just from a compiling and running two apps simultaneously perspective.

I found that reading the source really helped me fill in the gaps in the documantation and examples; be careful though, for whatever reasons the bitbucket source isn’t always up-to-date with the latest release:
https://bitbucket.org/Unity-Technologies/networking/src/e998e3faafcb/Runtime/?at=5.4

For example, you can see at a glance that NetworkLobbyManager inherits from NetworkManager and they both implement a singleton-ish pattern, so you would never need both scripts on the same Lobby object.

Hope this helps, and good luck!

p.s. there is a Slack channel that you may want to join, I find it much more helpful than these forums:
unitydevs.slack.com #network

The answer is … there is no answer (this page eventually became a journal of notes - confusing now). The docs, demos, and even their bitbucket are all outdated and no Unity staff seems to actually know the answer - Direct support tickets don’t even have an answer. The answer is to

  1. Wait for an update, which will eventually come (their docs/demos are all AWESOME… except for matchmaking and lobby). Hell, it could even be a bug – we don’t know because there’s no communication about this :confused:

  2. If you found this from Google hoping for an answer – For a cleaner, more-likely updated Q+A, Look here (I started to pay for an answer): https://forum.unity3d.com/threads/25-bounty-using-the-networklobbymanager-component-how-do-i-create-list-matches.444436/