Null reference exception when closing server

Oh this might be a bug I am seeing other users get. What version of Unity and Netcode for GameObjects are you using?

It could be that the network list is being cleaned up automatically when you close the game in newer versions. So when you try and clean it up manually it’s already gone. If you just comment out the foreach loop, does everything work correctly?

My Unity editor version is 2021.3.9f1
The NGO package version is 1.6.0

Yes, commenting out the foreach loop made so that now there’s no errors pop up in console.
But this code is necessary to clear up leader board items whenever some client leaves the game.

Hmm, that is true, perhaps we need to put the block of code in an IsClientOnly check instead of commenting it out completely.

Okay, my new solution is to add this check before the foreach loop:

if(IsServer && player.OwnerClientId == OwnerClientId)
{
      return;
}

That should let the clients clean up but not the server.

Thank you, it helped fix my issue

I also got other error messages, but they were caused only when I close the editor,
If I make a proper game exit like: pressing Leave Game and only then try to close - then there are no errors.

1 Like

What other error messages did you receive?

Here are the steps when I get error:

  1. Build and Run

  2. On editor launch and create Host

  3. On build join the Host’s lobby

  4. On editor I just close the game
    image

  5. Then I get this error:

which lead to this code again:

If there are more than one client joined, let’s say 2 clients joined, then there are 2 errors:
I also sometimes get this lobby error:

Note: The error does not occur if host is alone and no clients are joined to the game, which was my initial issue, that was fixed by your suggestion.

I thinks it’s the deal of order of closing stuff, when editor is closing game, then each system (lobby, host, client, relay etc.) has to close in some orderly manner.
If it’s really a lack in my project (which is just copy of lecturer’s), then it must be foresought and handled in some code.
I might be wrong though.

Try moving the new check outside of the foreach loop. That’s how I have it and I am not getting any errors.

I moved this code just before foreach loop
It did not help though, I get same errors in same use cases

    private void HandlePlayerDespawn(PlayerInstance player)
    {
        if (leaderBoardEntityStates == null)
        {
            return;
        }
        if (IsServer && player.OwnerClientId == OwnerClientId)
        {
            return;
        }
        foreach (LeaderBoardEntityState item in leaderBoardEntityStates)
        {
            if (item.ClientId != player.OwnerClientId)
            {
                continue;
            }
            if (leaderBoardEntityStates.Contains(item))
            {
                leaderBoardEntityStates.Remove(item);
            }
            break;
        }
        player.Inventory.TotalCoins.OnValueChanged -= (oldCoins, newCoins) => HandleCoinsChange(player.OwnerClientId, newCoins);
    }

PlayerInstance is same as TankPlayer class

Weird that code should just not be running when the server leaves the game, that was the goal of the check.

Can you check if it’s running HandlePlayerDespawn for other clients when it’s the host leaving the game?

Or maybe it doesn’t matter, maybe we should remove the IsServer part of the check. We can just not run this code when we are the ones leaving the game. Would you like to try that? Just use the OwnerClientId check?

Tried and thoroughly tested, still the same errors

    private void HandlePlayerDespawn(PlayerInstance player)
    {
        if (leaderBoardEntityStates == null)
        {
            return;
        }
        if (player.OwnerClientId == OwnerClientId)
        {
            return;
        }
        foreach (LeaderBoardEntityState item in leaderBoardEntityStates)
        {
            if (item.ClientId != player.OwnerClientId)
            {
                continue;
            }
            if (leaderBoardEntityStates.Contains(item))
            {
                leaderBoardEntityStates.Remove(item);
            }
            break;
        }
        player.Inventory.TotalCoins.OnValueChanged -= (oldCoins, newCoins) => HandleCoinsChange(player.OwnerClientId, newCoins);
    }

Ah well, would you like to upload your project here:
https://gdev.tv/projectupload
I can take a look at it and try and do some local debugging.

Done, hope it helps figure out issue

Well I couldn’t get the build to link to Unity Services (worked fine in the editor). Really not sure what is going on there. I’m going to try updating to Unity 2022 and see if that fixes it.

I was working on some project which required this specific verion of Unity editor 2021.3.9f1

Ya the update to 2022 was to let me get the connection working the build (which it did), but doesn’t solve the bug you were having, which I am looking into now.

Well the core of it, is that AFTER the host disconnects, it tries to clean up all the leaderboard entity states network list. These states have been begun being cleaned up by Unity already. For whatever reason in Netcode for GameObejcts 1.6 or in your version of the project, it’s trying to clean up the client’s network state first before the server’s.

I suppose if we could find a way to indicate to the leaderboard that the server has started disconnecting, we could avoid running this code altogether, but I couldn’t find an existing flag for that accessable by this class.

If we look at the exact line causing the bug in the NetworkList class:

internal void MarkNetworkObjectDirty(
{
         if (m_NetworkBehaviour == null)
         {
             Debug.LogWarning($"NetworkList is written to, but doesn't know its NetworkBehaviour yet. " +
                                 "Are you modifying a NetworkList before the NetworkObject is spawned?");
             return;
         }   
         m_NetworkBehaviour.NetworkManager.BehaviourUpdater.AddForUpdate(m_NetworkBehaviour.NetworkObject);
}

Essentially the list has lost it’s connection to either the NetworkManager or the behaviour updater.

Honestly, this is on Unity, they need more null checks in here to handle other cases. We can’t modify the NetworkList class as it’s immutable. The line causing the bug has 3 nested periods in it, which is not the best practice for this very reason.

I couldn’t find any check or state to verify in the LeaderBoard class that would tell us if this list is in the process of being dismantled when we are checking it.

I think you best bet is just to log this error with Unity and ask them to fix it on their end. Sorry I could not be more help. This error does not seem to occur in Netcode for GameObjects 1.4, so if you want to revert to that version to avoid the error you can.

1 Like

Thank you @Yitzchak_Cohen for your detail investigation.
I’m indeed using NGO 1.6 version

I will try to switch version, and try to post this error to Unity is some future time

Privacy & Terms