HLAPI MatchMaker Lobby Workflow - Unofficial Documentation. Please contribute!

This is an extension/doc of a video guide I made – I am posting this here for the dual purpose that:
1) This may help you!
2) I am hoping others will please add to this (and correct me~).

While Unity isn’t updating any docs/demos/videos/tutorials on
UNET/Lobby/HLAPI/MatchMaker/HostMigration or anything pre-game
(hint, hint)

I’ve been trying to get the workflow down for lobby since November (that link gets ugly, here is the better/updated version) - I feel that I’ve progressed a lot and would like some help filling in the gaps, for the sake of myself and others while the lobby/HLAPI/MatchMaker is extremely undocumented:

  • Create a new empty scene - save it as Game.

  • Create a new scene. Save it as Lobby. Stay here.

  • Build settings >> Set Lobby as 0, Game as 1.

  • Create LobbyMgr gameObj.

  • Throw on a NetworkLobbyMgr derived script on LobbyMgr gameObj. I called it lobbyMgr.

  • Throw on a Mono derived script on LobbyMgr gameObj (because NetworkLobbyMgr destroys on match d/c, so need something static). I called it lobbyUI.

  • StartMMBtn to click - 1 single button to rule it all.

  • Link an event to call MMStart() to start from our lobbyUI script. The UI script will find the non-destroyed version of lobbyMgr and get it to start matchMaker later.

  • Create LobbyPlayer gameObj.

  • Throw on a NetworkLobbyPlayer derived script on LobbyPlayer gameObj. I called it lobbyPlayer. This will automatically add a Network Identity. Save as prefab, then delete.

  • Create GamePlayer gameObj.

  • Throw on a NetworkLobbyPlayer derived script on GamePlayer. I called it lobbyPlayerScript. This will automatically add a Network Identity. Save as prefab, then delete.

  • On lobbyMgr inspector, drag your LobbyPlayer into Lobby Player, GamePlayer into Game Player, Lobby Scene into Lobby Scene, Day scene into Day Scene. Set max players. I put 3.

  • ___________________________________*

  • So, up to this point, we have:*

  • a btn that calls StartMM() from UI (which will find the lobbyMgr instance and call start matchMaker later),

  • a lobbyMgr with 2 scripts inside,

  • a LobbyPlayer prefab deleted,

  • a GamePlayer prefab deleted,

  • and the lobbyMgr component’s serialized fields filled

  • ___________________________________*

  • Open your lobbyMgr script and make a void MMStart(). Inside that, add: this.StartMatchMaker(). This will enable this.MatchMaker.

  • Below StartMatchMaker, add: this.ListMatches(parameters…, OnMatchList)

  • Then outside that void, add public override void ListMatches(p1, p2, p3).
    Inside this, in a nutshell, if success && list.Count > 0, there’s players so, for each the list, if the match has a player and isn’t full, join 1st match: this.JoinMatch(match[0]…OnMatchJoin).

  • ELSE IF no matches found,* then: this.CreateMatch(params…OnMatchCreate)

  • Create a: override void OnMatchJoin(p1, p2, p3) – Pretty much, if (success) then you’re good to go. After that, you need to handle some override events to ready up automatically later.

  • Create a: override void OnMatchCreate(p1, p2, p3) – Pretty much, good to go.

  • In your Start() on lobbyPlayer script we made in #10, if it’s a this.localPlayer and isn’t already this.ReadyToBegin then SendReadyToBeginMessage() to auto-ready up.

  • Throw in your SyncLists, SyncVars (Example), ClientRpc and **Cmd’**s here. Probably to sync a x/y players joined the game and a list of players that joined. It’s hard to find these instances, so you should probably create a List on your lobbyMgr script to keep track of instances. For the index, use this.slot – the slot is super important to remember as it’s most all of your indexes for everything that is UI or instances. Don’t forget TO DO something with the vars when they sync. You need a hook [SyncVar(hook=“someCallbackVoid”)] I think? I forgot … I’m just using a SyncList so far that has it’s own .callback

  • The easiest way to remember ClientRpc vs Cmd is …

  • isServer*? Then [ClientRpc]

  • isClient*? Then [Command] with nothing but the RpcSomething() call.
    Pretty much, what you’re trying to do is saying “I’m a client, so I need to tell the server to tell the other clients to do something”. In comparison, your laptop can’t talk to your desktop directly, BUT you can ask your router to relay a message to your laptop.

___________________________________
So, up to this point since last point, we have:
* lobbyMgr.StartMatchMaker()
* lobbyMgr.Start
* lobbyMgr.ListMatches(…,OnMatchList)

  • override void OnMatchList()

  • @ OnMatchList, if game, join 1st JoinGame(match[0], …, OnMatchJoin)

  • @ MatchList, if NO game, CreateGame(…, OnMatchCreate)

  • Ready up your client

  • ClientRpc, Cmd, SyncStuff
    ___________________________________

  • Now, we need to handle disconnection from server/client. PLEASE HELP :wink: If you guys made it this far and know how to handle d/c, let’s help each other out and let us know what you did and where you did it <3 Or if a UNET dev exists (I heard legends!) in this forum that wants to respond to fill in some gaps, that would rock!

(To start somewhere on disconnection, I created a CancelBtn, but we also need to handle disconnection outside the btn, like loss of connection, directly closing the game, etc. For CancelBtn, I call lobbyMgr.StopHost() which technically works (on both server/client), but bugs out the server for the next 30 seconds)

Hopefully this is a nice win-win guide. Catch up to me, then let me know what to do next :slight_smile: If I can answer my own question, I will update this. Until then, guys, help us all out and update/correct this, add tips, and add unofficial documentation here.

>> Want OFFICIAL doc support/demos/examples/Q+A? Shout out to the devs for help!

8 Likes

nice

  • NetworkHUD (outdated and not HLAPI, but still a good ref) src: BitBucket
  • SyncList example: Unity Post
1 Like

Notable extra callbacks from NetworkLobbyManager:

  • OnServerRemovePlayer(NetworkConnection conn, PlayerController player)
    (Perhaps use this opportunity to remove from player list and deduct player count on UI?)

  • OnServerAddPlayer(NetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader)
    (Same as above, but add?)

Notable NetworkLobbyPlayer extra callbacks:

  1. The slot # is already gone (-1)
  2. You cannnot cmd/rpc – it will fail by this point (maybe it disconnects before it can finish?)

Added link to SyncVar example to OP ( Callbacks for Network Sync? - Unity Engine - Unity Discussions )

OOP after creating a match (why isn’t this in docs?) // Joining will be similar, but not exact:

  • [NetworkLobbyManager-SERVER] OnStartHost

  • [NetworkLobbyManager-SERVER] OnLobbyStartHost

  • [NetworkLobbyManager-SERVER] OnStartServer

  • [NetworkLobbyManager-SERVER] OnLobbyStartServer

  • [NetworkLobbyManager-SERVER] OnServerConnect

  • [NetworkLobbyManager-SERVER] OnLobbyServerConnect

  • [NetworkLobbyManager-Client] OnStartClient

  • [NetworkLobbyManager-Client] OnLobbyStartClient

  • [NetworkLobbyManager-CreateMatch-Callback] OnMatchCreate

  • [NetworkLobbyManager-Client] OnClientConnect

  • [NetworkLobbyManager-Client] OnLobbyClientConnect

  • [NetworkLobbyManager-Client] OnLobbyClientEnter

  • [NetworkLobbyManager-SERVER] OnServerReady

  • [NetworkLobbyManager-SERVER] OnServerAddPlayer

  • [NetworkLobbyPlayer] Awake

  • [NetworkLobbyPlayer] OnStartServer

  • [NetworkLobbyPlayer] PreStartClient

  • [NetworkLobbyPlayer] OnStartClient

  • [NetworkLobbyPlayer] OnClientEnterLobby

  • [NetworkLobbyPlayer] OnStartAuthority

  • [NetworkLobbyPlayer] OnStartLocalPlayer

  • [NetworkLobbyPlayer] Start

  • [NetworkLobbyPlayer] OnSetLocalVisibility

OOP after cancelling a created match:

  • [NetworkLobbyManager-SERVER] OnDestroyMatch

  • [NetworkLobbyManager-SERVER] OnStopHost

  • [NetworkLobbyManager-SERVER] OnLobbyStopHost

  • [NetworkLobbyManager-SERVER] OnStopServer

  • [NetworkLobbyManager-SERVER] ServerChangeScene

  • [NetworkLobbyManager-Client] OnStopClient

  • [NetworkLobbyManager-Client] OnLobbyStopClient

  • [NetworkLobbyManager-Client] OnLobbyClientExit

  • [NetworkLobbyPlayer] OnClientExitLobby // playerController is gone by now, maybe earlier

  • <Everything is now @ Awake as scene resets>

< LobbyGUI BitBucket Src >
^ (Shows lobby player lists, NetworkLobbyPlayer callbacks, ready/unready/remove/add)

< NetworkLobbyManager bitBucket src >

Disconnection tips that you wish you knew earlier:

When you disconnect, the current lobby is destroyed and you re-enter the lobby. This means a few things:

  • When the scene restarts, if your lobbyMgr is DontDestroyOnLoad, then there will be TWO lobbyMgr’s (the same scene reloaded). You’ll have to do a check to delete the new one at Awake()
  • Anything you serialized with [SerializeField] will be wiped out, so you have to setup your UI the tedious way: At Awake(), GameObject.Find all your gameObj’s to assign them. There may be a better way to do this.
  • Even if you do #2’s method, think if you want your UI script to be destroyed or not. If not, you need to call your UI script to get the gameObj instances from #2 above ^ again. Alternately, you can use a bunch of mini scripts and drop them into individual buttons and, for all of them, Find() your single LobbyMgr script to call events. This may be easier.

Unanswered questions:

  • < What is the best way to manually disconnect >?
  • What is the best way to handle your script since the scene is destroyed, but you re-enter the same script?
  • What is the best way for the server to handle a disconnect via a connection issue (NOT manually)?
  • When the SERVER disconnects, how can you migrate the host so your other clients don’t just crash?
  • When the SERVER disconnects, how do you immediately destroy a match (default waits 30 seconds, which is very bad)? Currently when a host leaves, the match still shows 1 player in that lobby and you can still join up, only for the match to crash ~30 seconds later.

Photon Thunder uses 99% of the same code as UNET/HLAPI, except claiming 1/5 the price, Host Migration works, punchthru is attempted before relay (less lag), increased features, and existing support. Check it out if you are also struggling with UNET.

Excellent/simple SyncVar hook (callback) example:

Workarounds/Known Bugs for UNET:

This will be my last contribution and I won’t be maintaining this anymore. Unfortunately, UNET’s lack of support, docs or anything reliable puts us all at risk. The last straw was that Host Migration, reported and reproduced not working in June, is still broken and/or “local only” (even though it’s filed under UNET). This truly breaks our game and makes UNET quite useless without it, crashing everyone if the host quits. Good luck.

Thanks for all of these, quite the documentation. right now our company thinks of using Unity Networking.
were you able to integrate unity networking with photon? or does Unity Networking requires UNET?

@MrLucid72

UNET is Unity’s networking shown above and it uses a relay (3rd party connection). The docs are incomplete and devs haven’t been answering Q+A. Host migration is broken for online games with UNET, so if the host disconnects, all clients crash.

All in all, UNET unusable for now and unsupported. These docs were an attempt but still failed. I recommend Photon. I spent 2 months trying to make a core lobby and failed due to poor docs and support. I switched to Photon, had to ditch all my networking code, learn something new, and got it working in THREE days. That’s the difference.

I bet one day UNET and HLAPI will be great. Not anytime soon, though. It’s just unsupported. And not 1 dev will tell you it IS because this multiplayer section of the forum, unlike other sections, is unmonitored with the exception of 1 reply per month.

2 Likes

is it possible to have the lobby handled by Nodejs or Photon, then the gameroom by UNET?

The game is poker, it is online, we are currently using Nodejs and SocketIO.

We are having problems with recconection that’s why we are researching UNET.

is it really unusable right now? :frowning:

PS. Thanks for the reply

Nice thread. We are also in situation that was using the old master server and wanted to migrate to the new UNet, after all hard work we get it all done EXCEPT the host migration for relay match games. UNet is great over the old networking, but I was very disappointed about Unity couldn’t finish it…

At the end we decided just give up host migration and reconnect the disconnected clients to a new match, since our game is very fast pace (~half minutes) so effect is small.

You mentioned Host migration is broken for UNET Is this really the case. I’m currently changing my single player game into a multiplayer game and host migration is a must-have feature for me. I’ve already put a lot of time and work into it so I really don’t wanna ditch UNET but this would give me no other choice. Could you confirm that please?

1 Like

Host migration works only for direct connection (if it works at all). If you’re using the matchmaker f.e. it won’t work.

3 Likes

So is UNET dead? Is host migration working now for matchmaker? This would kill my game (if not working).

I was starting to implement UNET for my game and the lack of examples/working code is brutal, you can only find very basic stuff around.

We’ll, there’s only 4 people working on enterprise software on one of the most complex features of Unity. They’re working hard, but the man upstairs doesn’t think its worth allocating more resources - not even for documentation. If bossman doesn’t give it any priority, then… Well…

Host migration does not work, yet. We switched to Photon where it does work and is documented, as advertised.

Right - if you make a 90s game with LAN only (who does that outside of testing?), you’re good to go - as long as you don’t care about proper lobby features.

It is, sadly - we dealt with it first-hand in your situation. We had to switch, too, as host migration was our biggest deal breaker.

1 Like