Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved NetworkManager throws exception when a player disconnects

Discussion in 'Netcode for GameObjects' started by Fornost_Legion, Apr 24, 2023.

  1. Fornost_Legion

    Fornost_Legion

    Joined:
    Jul 21, 2022
    Posts:
    7
    Hi, I'm creating a small multiplayer game with a host-client architecture, using Lobby, Relay and Netcode

    I'm following the scene architecture of Boss Room, with an initial scene that creates the NetworManager object and a then a "Main Menu" scene where the lobby is created/joined, and a 3rd scene for the game itself. When the game ends or you disconnect, you return to the "Main Menu" scene, so I'm reusing the same NetworkManager for every consecutive game. I think I might have misunderstood something and reusing the NetworkManager could be the problem, but anyway...

    My problem comes when I start a 2nd game without closing the program. When finishing the 1st game I'm shutting down with NetworkManager.Singleton.Shutdown() and creating a new Lobby, etc. and everything goes well, even when a client disconnects abruptly. But if I register to the OnClientDisconnectCallback to make the AI take control of that player, I'm getting a weird exception that loops forever:

    KeyNotFoundException: The given key '2' was not present in the dictionary.
    System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <8f06425e63004caf99a79845675f751e>:0)
    Unity.Netcode.NetworkManager.ClientIdToTransportId (System.UInt64 clientId) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.1.0/Runtime/Core/NetworkManager.cs:1745)
    Unity.Netcode.Transports.UTP.UnityTransport.ExtractNetworkMetrics () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.1.0/Runtime/Transports/UTP/UnityTransport.cs:889)
    Unity.Netcode.Transports.UTP.UnityTransport.Update () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.1.0/Runtime/Transports/UTP/UnityTransport.cs:866)

    In the first game the ClientId for the client was 1 and in the second is 2, so I guess the problem lies around that. But the exception comes from the internal code of NetworkManager and UnityTransport, and if I dont register to the OnClientDisconnect event, it doesn't explode.

    Can someone point me to my error, or confirm if this is a possible bug to fill a bug report?
    Thank you very much!
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,321
    Nope. The NetworkManager script lives on an object that is marked DontDestroyOnLoad. It's a singleton that's supposed to have a lifetime from the start of the app until the user exits the app.

    There are forum posts where users wrote code that either destroy or recreate the NetworkManager after shutdown. Don't do this!

    These code fragments originate from other issues caused by incorrect use where the NetworkManager gets added multiple times. For example by loading the same scene where the NetworkManager is instantiated - therefore it is recommended to have such an "init" scene that initializes the NetworkManager and where the game never returns to.

    Without seeing any code it's hard to say what is going on. But I would suspect it's possibly a timing issue, ie starting a new host before the NetworkManager had time to shut everything down. Or initializing things that should only be initialized in OnNetworkSpawn elsewhere, for example in Start or Awake.

    Since you started with Boss Room I would advice to first check whether this issue does occur in the unmodified version. If so, report a bug. If not, try to reconstruct what code you added or changed (if it isn't too much) to see where it starts to fail. If there's already a lot of custom code I would make a copy of the project and start deleting or disabling code and objects until the issue goes away to narrow down the cause.
     
  3. Fornost_Legion

    Fornost_Legion

    Joined:
    Jul 21, 2022
    Posts:
    7
    Thank you so much for your answer CodeSmile. I'm relieved with what you say about how to use NetworkManager, I also found the destroy it solution a bit "creative".

    Actually I'm not using any project as a base, I've picked from here and there, and just checked is architecture and added a "loading" scene when I found out NetworkManager duplicating every time I was returning to the main menu...

    I also thought about the timing issue possibility, so I gave it time between starting new games, and also tinkered with the reuse id and the timer for id refresh, without luck. I read somewhere that even though the id is freed, its not reused until maybe hitting the maxId value or something. But if the client connects with id 2 in the 2nd game, and it's able to communicate with it normally, it's really weird that exception on that private code when player disconnects.

    I'd check the Boss Room solution in deep and see if it might be something initialized in a wrong place.
     
  4. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    612
    Check if you're doing anything network related in your OnClientDisconnectCallback code. That event is called before the client is actually disconnected and it sounds like there's still a reference to it.

    I had a something similar in the same callback doing something network related but unfortunately no longer have the code to check.
     
  5. Fornost_Legion

    Fornost_Legion

    Joined:
    Jul 21, 2022
    Posts:
    7
    Thanks cerestorm!, will check tomorrow. But if that were the case, I guess it would generate the exception when the client quits from the first game, which is not happening, unless there is something not correctly closed or cleaned in my code or in the NetworkManager code :rolleyes:
     
  6. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,321
    As for client IDs they will go up every time you host a new match, this is normal. Reuse may occur but I don‘t know under which circumstances (besides quitting).
     
  7. Fornost_Legion

    Fornost_Legion

    Joined:
    Jul 21, 2022
    Posts:
    7
    I think I've found what was triggering the problem, and was a big mistake on my side. I was launching an event when the client disconnects so the UI can register to it and show a message on screen, but I was registering to it every time a game starts and forgot to unregister after finishing, so in the 2nd game the callback was being called twice and probably the second was doing weird stuff.

    What I still cant understand is why this issue have been able to create the bigger problem in the Network code, it seems to be above my paygrade :D

    Thanks a lot, your comments helped me plenty to narrow the issue :)