There is a strange situation when player reconnect to lobby. And I think this is bug.
Step 1: Host player creates a lobby. Step 2: Only the Host player joins the lobby, then the host disconnects by closing the application. (doesn’t use RemovePlayerAsync or DeleteLobbyAsync methods) Step 3: The host reconnects to the lobby with “LobbyService.Instance.ReconnectToLobbyAsync(lobbyId)” before the “Disconnect Removal Time” expires.
Until this point everything works well but, if host close the app again then reconnect the Lobby second time. After this point there is 2 error appear.
1- Player can reconnect the Lobby even “Active Lifespan” expires.
2 - If host close app again the Lobby will not destroy itself even “Active Lifespan” expires.
But, if I close the app then try to reconnect after “Disconnect Removal Time” expires, I got LobbyNotFound error. This is expected behavior but after join lobby with “LobbyService.Instance.ReconnectToLobbyAsync” method. The lobby is not behaving properly.
I use Multiplay Services package with “LobbyService.Instance” methods. Is this effect anything? Except this behavior everything works well.
Also, I forgot to mention something important.
If 2 players join the lobby and one of them has reconnected once, the reconnected player cannot be disconnected if they close the game , which prevents new players from entering the lobby.
That’s the error. You should not leave the Lobby running when the Lobby host quits the application. Be sure to delete the Lobby in OnApplicationQuit for instance.
However, the host can disconnect or leave the lobby while other players are in the lobby. Because of this there is a host switch, right?
Also, if I close the lobby while other players are in the lobby, it will be a very bad experience for other players.
Actually the problem is, when a player reconnected the lobby, after that point is the player will never disconnect the lobby, and that slot always be occupied.
It think this is the bug.
In the scenarios where the host does not specify a new host, the new host is selected randomly from the other players who are currently in the lobby.
This implies that if the host leaves the Lobby with no one else still in the Lobby, there is no host migration and presumably the Lobby timeout counter starts ticking irreversibly.
If you do have a client in the Lobby and the host leaves, check that the host migration did succeed. You may have to implement a callback in order to catch this situation because your code may need to respond to the host switch appropriately (eg provide the new host the ability to change game settings).
This is not unexpected! Every game that I know of where a host starts a private Lobby will kick all players if the Lobby host leaves.
This is true at least for client-hosted games where it wouldn’t make sense that the Lobby host would not actually host the game session, this may provide a bad experience if the Lobby randomly happens to choose the player with the lowest upstream bandwidth and/or the highest ping - then every other client will suffer in that session. Therefore it’s best to leave the decision who is going to host the game to the players in a client-hosted game.
Lobby host switching IMO ought to be left exclusively to dedicated server sessions.
The host or another player can disconnect from the lobby and then reconnect to the lobby within the “Disconnect Timeout” period using the “LobbyService.Instance.ReconnectToLobbyAsync(lobbyId)” method.
However, if that player disconnects a second time, the player will not disconnect from the lobby. So the player can reconnect to the lobby even after the “Disconnect Timeout” period has expired.
I think this is a bug and not appropriate behavior.
That may be a bug. If you can create a minimal project where this behaviour is reproducible you should report this as a bug.
However, in my experience, most of these “bugs” are due to a programming error. Commonly a resource like the Lobby has not been properly shut down, or there’s a timing issue with an async method such as not awaiting a call or not handling an exception but rather ignoring it.
So feel free to post your code if you want other eyes to look over it for such issues. So far we’ve only spoken hypothetically about an issue that sounds like a bug, but neither of us can say for sure whether that’s on you or on Unity.
I made a simple tutorial for testing.
“JoinLobby()”, “ReconnectLobby()”, “CreateLobby()” and “SignIn()” method are triggered on UI.
I builded it out for the Mac version.
Editor is Host and doesn’t left or disconnect from the lobby.
Test steps :
1 - Mac build (Player2) joins the lobby.
2 - Player2 quits the application without to use any methods like “RemovePlayerAsync” etc.
3 - Player2 reconnects to lobby within the “ReconnectToLobbyAsync” method in “Disconnect Removal Time” period.
Note: If Player2 doesn’t reconnect to the lobby in “Disconnect Removal Time” period, “Disconnect Removal Time” will be disconnected after “Disconnect Removal Time” expired.
4 - Same as step 2.
5- Player2 can reconnect after “Disconnect Removal Time” expired.
In Host side, Player2 will never disconnect.
I think this behavior is a bug.
Yes but it’s best practice to await the entire call chain of async methods. Your IDE will actually warn you of this potential source of issues.
If you were to follow up another line of code after JoinAsync() for example, then that second line will run before the async method completes, ie it does not await joining the Lobby even though the called method does await.
An async method not awaited will also not propagate exceptions. Although you enclosed the entire method body with try/catch handling, I would not rely on this pattern because it’s all too easy to forget that the caller is not awaiting.
Thanks for your advice but this is test project and I just wanted to show you the logs.
I use Actions inside the “JoinAsync” method, this way I log in to the lobby or show an error message.
Thanks for the ping ! It indeed looks like a bug for us to investigate. To help replicate, could you please confirm if you use any other multiplayer components on top of Lobby ? (Relay, NGO, …)