Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Unity Multiplayer HLAPI MatchMaker Lobby Workflow - Unofficial Documentation. Please contribute!

Discussion in 'Connected Games' started by MrLucid72, Dec 16, 2016.

  1. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    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~).

    <rage style="passiveAggressive">
    While Unity isn't updating any docs/demos/videos/tutorials on
    UNET/Lobby/HLAPI/MatchMaker/HostMigration or anything pre-game
    (hint, hint)
    </rage>



    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:

    1. Create a new empty scene - save it as Game.
    2. Create a new scene. Save it as Lobby. Stay here.
    3. Build settings >> Set Lobby as 0, Game as 1.
    4. Create LobbyMgr gameObj.
    5. Throw on a NetworkLobbyMgr derived script on LobbyMgr gameObj. I called it lobbyMgr.
    6. Throw on a Mono derived script on LobbyMgr gameObj (because NetworkLobbyMgr destroys on match d/c, so need something static). I called it lobbyUI.
    7. StartMMBtn to click - 1 single button to rule it all.
    8. 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.
    9. Create LobbyPlayer gameObj.
    10. 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.
    11. Create GamePlayer gameObj.
    12. Throw on a NetworkLobbyPlayer derived script on GamePlayer. I called it lobbyPlayerScript. This will automatically add a Network Identity. Save as prefab, then delete.
    13. 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
      ___________________________________



    14. Open your lobbyMgr script and make a void MMStart(). Inside that, add: this.StartMatchMaker(). This will enable this.MatchMaker.<thingsToDo>
    15. Below StartMatchMaker, add: this.ListMatches(parameters....., OnMatchList)
    16. 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)
    17. 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.
    18. Create a: override void OnMatchCreate(p1, p2, p3) -- Pretty much, good to go.
    19. 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.
    20. 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<lobbyPlayer> 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
    21. 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
      ___________________________________



    22. Now, we need to handle disconnection from server/client. PLEASE HELP ;) 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 :) 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!
     
    Last edited: Dec 24, 2016
    Gekigengar, Mikael-H, Artaani and 5 others like this.
  2. kira419

    kira419

    Joined:
    Dec 16, 2016
    Posts:
    3
  3. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    • NetworkHUD (outdated and not HLAPI, but still a good ref) src: BitBucket
    • SyncList example: Unity Post
     
    pKallv likes this.
  4. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    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:
    • OnClientExitLobby()
      Now's the chance to do something before you lose your instance.

    • OnNetworkDestroy()
      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?)
     
  5. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
  6. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    OOP after creating a match (why isn't this in docs?) // Joining will be similar, but not exact:
    1. [NetworkLobbyManager-SERVER] OnStartHost
    2. [NetworkLobbyManager-SERVER] OnLobbyStartHost
    3. [NetworkLobbyManager-SERVER] OnStartServer
    4. [NetworkLobbyManager-SERVER] OnLobbyStartServer
    5. [NetworkLobbyManager-SERVER] OnServerConnect
    6. [NetworkLobbyManager-SERVER] OnLobbyServerConnect
    7. [NetworkLobbyManager-Client] OnStartClient
    8. [NetworkLobbyManager-Client] OnLobbyStartClient
    9. [NetworkLobbyManager-CreateMatch-Callback] OnMatchCreate
    10. [NetworkLobbyManager-Client] OnClientConnect
    11. [NetworkLobbyManager-Client] OnLobbyClientConnect
    12. [NetworkLobbyManager-Client] OnLobbyClientEnter
    13. [NetworkLobbyManager-SERVER] OnServerReady
    14. [NetworkLobbyManager-SERVER] OnServerAddPlayer
    15. [NetworkLobbyPlayer] Awake
    16. [NetworkLobbyPlayer] OnStartServer
    17. [NetworkLobbyPlayer] PreStartClient
    18. [NetworkLobbyPlayer] OnStartClient
    19. [NetworkLobbyPlayer] OnClientEnterLobby
    20. [NetworkLobbyPlayer] OnStartAuthority
    21. [NetworkLobbyPlayer] OnStartLocalPlayer
    22. [NetworkLobbyPlayer] Start
    23. [NetworkLobbyPlayer] OnSetLocalVisibility
    OOP after cancelling a created match:
    1. [NetworkLobbyManager-SERVER] OnDestroyMatch
    2. [NetworkLobbyManager-SERVER] OnStopHost
    3. [NetworkLobbyManager-SERVER] OnLobbyStopHost
    4. [NetworkLobbyManager-SERVER] OnStopServer
    5. [NetworkLobbyManager-SERVER] ServerChangeScene
    6. [NetworkLobbyManager-Client] OnStopClient
    7. [NetworkLobbyManager-Client] OnLobbyStopClient
    8. [NetworkLobbyManager-Client] OnLobbyClientExit
    9. [NetworkLobbyPlayer] OnClientExitLobby // playerController is gone by now, maybe earlier
    10. <Everything is now @ Awake as scene resets>
     
  7. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    Last edited: Dec 23, 2016
  8. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    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:
    1. 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()
    2. 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.
    3. 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.
    _______________________________________________
    Unans
    wered questions:
    1. < What is the best way to manually disconnect >?
    2. What is the best way to handle your script since the scene is destroyed, but you re-enter the same script?
    3. What is the best way for the server to handle a disconnect via a connection issue (NOT manually)?
    4. When the SERVER disconnects, how can you migrate the host so your other clients don't just crash?
    5. 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.
     
    Last edited: Dec 23, 2016
  9. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    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.
     
  10. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
  11. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    Workarounds/Known Bugs for UNET:
    https://forum.unity3d.com/threads/u...ion-errors-workarounds-best-practices.395952/

    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.
     
  12. definite

    definite

    Joined:
    Aug 23, 2016
    Posts:
    3
    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?

    @dylanh7244
     
    Last edited: Jan 5, 2017
  13. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    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.
     
    akuno and definite like this.
  14. definite

    definite

    Joined:
    Aug 23, 2016
    Posts:
    3
    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? :(

    PS. Thanks for the reply
     
    Last edited: Jan 5, 2017
  15. SweatyChair

    SweatyChair

    Joined:
    Feb 15, 2016
    Posts:
    116
    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.
     
  16. LK84

    LK84

    Joined:
    Aug 10, 2015
    Posts:
    9
    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?
     
    MrLucid72 likes this.
  17. lejean

    lejean

    Joined:
    Jul 4, 2013
    Posts:
    200
    Host migration works only for direct connection (if it works at all). If you're using the matchmaker f.e. it won't work.
     
    MrLucid72, LK84 and SweatyChair like this.
  18. pertz

    pertz

    Joined:
    Jan 8, 2015
    Posts:
    66
    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.
     
  19. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    664
    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.
     
    Last edited: Apr 6, 2017
    Artaani likes this.