Support reconnect to Distributed Authority session
Is your feature request related to a problem? Please describe. When users exit the app or it crashes on Oculus Quest, the user does not leave the session cleanly. We need a way to allow users to return to the session after the app restarts.
Describe the solution you'd like We implemented a solution by modifying the multiplayer services package, resulting in code like this:
var sessions = await MultiplayerService.Instance.GetJoinedSessionIdsAsync();
foreach (var sessionId in sessions)
{
_log.Info($"Found already joined session {sessionId}, checking properties.");
var properties = await MultiplayerService.Instance.GetSessionPropertiesAsync(sessionId);
if (properties.TryGetValue("WorldName", out var worldNameProp) && worldNameProp.Value == worldName)
{
_log.Info($"Reconnecting to session {sessionId}");
var reconnectOptions = new ReconnectSessionOptions().WithDistributedAuthorityNetwork();
_session = await MultiplayerService.Instance.ReconnectToSessionAsync(sessionId, reconnectOptions);
_log.Info("Reconnect complete. Waiting for OnClientStarted");
return;
}
}
The two methods we added are:
GetSessionPropertiesAsync- reads the session properties from the lobby.- Extension method
ReconnectSessionOptions().WithDistributedAuthorityNetwork()to start the netcode session after connecting to the lobby.
Describe alternatives you've considered
Alternatively, you could have MatchmakeSessionAsync first search for a session to reconnect to. Currently, if we try this, we get an error that the lobby code is not valid. We think this is because the user is still considered "in the lobby" after the unclean disconnect.
(sorry, tried to address a merge conflict and screwed it up, should be fixed properly now)
I thought of another idea though for after this- what if we refactored Predicate interface to always be four argument match itself? Then we'd have only one type of predicate, no need for the ObjectSourcePlayer wrapper. Could be much cleaner in many ways.
I do agree. We still have to carefully refactor a bunch of code to remove the use of the 2-argument match all over the codebase.
So I'm not entirely sure the 2-argument match in FilterPermanent added with last commit is a good idea. It caused some tests to fail, that I fixed in that commit with a few checkObjectClass before calls for the 2-argument match.
This is in the territory of hard to set right overloads with abstract types, so I'm not saying it can not be improved, but for now I do not see how to do it nicely. I'd like to have filters have a failsafe overload for any object, that does class checkObjectClass before attempting to match, but it is hard to set up.
Examples of tests that failed with ManaPool sourceFilters before adding checkObjectClass: