Reconnect Parties
Last updated
Last updated
Party reconnection is a new feature in Kronos that allows you to reconnect parties after returning to the main menu.
The way this system works is basically when the party reconnect is requested, the plugin will check what the previous role of the player was (either party host or client), and based on that it will either recreate the party or find it and reconnect to it. Whether the player was a party host or party client is automatically updated while in a party.
This is only the first iteration of this system, and I expect to improve it in the future.
Lets go over how you can implement party reconnection.
To make party re-connection possible, we will need to tell the server that we are leaving the match so that it can notify party clients to leave as well. We will use the PlayerController
class to request (and receive) leave match calls, and we will use the GameMode
class to process these requests for our players.
Let's start by creating a custom event in the GameMode
class. The event should have an object reference parameter for your player controller class.
Next lets go over to the PlayerController
class and set up the leave requests. We'll need two custom events for this. When the RequestLeaveWithParty
is called, we make sure that we are on server side and ask the game mode to handle the leave request for us.
Make sure that the ServerRequestLeaveWithParty
event is set to "Run On Server" and Reliable!
We are also going to create a ClientLeaveMatch
event which will be the response from the server that we should leave the match and reconnect the party. Make sure that this event is set to "Run On Owning Client" and Reliable!
Since we have joined the session as a party, our reservation includes the unique id of all party members, so we can use the reservation system to figure out which players belonged to our party.
So back in the GameMode
class, let's start by getting the requesting player's reservation. If he somehow doesn't have a valid reservation then we simply tell him to leave without reconnecting the party. You can treat this as an error basically.
We will loop through the reservation members and check if they are complete, meaning the player has joined the game. We will also have to make sure that the reservation member's player id is not the same as the hosting player's id because we want the server to leave last (if he has to).
If the conditions above are met, we can tell the client to leave the match and reconnect the party. The PlayerId of GetPlayerControllerFromUniqueId
is coming from the Break KronosReservationMember
node. You will need to cast to your own player controller blueprint to call the ClientLeaveMatch
function you created earlier.
However, if the reservation is actually the hosting player's reservation then it means the server will have to leave as well. Since we must notify everyone before closing the server, we'll create a bool variable in the GameMode
and set it to true.
After we looped through all members we will check if the server should leave as well. The logic below is connected to the "Completed" output of the ForEachLoop
node. Since we want all RPCs to reach the desired players, we'll delay a bit before closing the server.
Ideally you should keep checking if all clients have left already (using a timer for example), but to keep things simple I'm just going to use a delay. The engine also does a net flush before closing the server, so the delay might not be necessary.
The ClientLeaveMatch
event is on client side again, so we are ready to call the LeaveKronosMatch
function. Before leaving, we set a variable in the GameInstance
that we'll use later to check if we should attempt party reconnection or not. Create a bool variable in your GameInstance
class and set it to true before leaving the match.
After the LeaveKronosMatch
node, the player will return to the main menu where we will attempt to reconnect to the party.
After the player has returned to the main menu from the match, we will check if we want to attempt reconnecting the party. You can do this from any blueprint (GameMode, HUD, PlayerController, etc.) but you should make sure that the player is logged in with the Online Subsystem before attempting to reconnect parties!
I'll just use the BeginPlay
event of the main menu GameMode
.
We can reconnect the party using the ReconnectKronosParty
node. Before reconnecting, we will also reset the ShouldAttemptPartyReconnect
to false so that next time when we return to the main menu we don't attempt to reconnect again unless it was requested.
If you read the text inside the PrintString
nodes, you can see what happens at the different outputs of the node. OnSuccess means we have recreated or found the party, and we are about to connect to it. OnFailure means something went wrong. Either the party session was not found or we failed to join the session.
The failure event will not be called if connecting to the party fails. In that case the KronosPartyClient
beacon already notifies the party subsystem for error events.
It is also a good idea to display a widget to the user before attempting to reconnect parties, so that they can tell what is happening. You should also lock any user input while reconnecting to avoid cases where the player presses the create party button while reconnecting.
Now we just have to hook the leave requesting logic to a UI button. When the player will press the leave match button, we just have to call the RequestLeaveWithParty
function that we created above to leave the match and bring all party members back to the main menu.
For this example I made it so that only the party host can request to leave with the party, but the system we set up above works even if a party client requests it.
Since there is no overarching state machine that handles party reconnects, you must account for cases where the player might try to interact with parties in some way (e.g. creating a new party) while party reconnection is in progress. It is also possible that the player accept a session invite while reconnecting.
Create a bool variable in your GameInstance
class that will keep track of whether party reconnection is in progress or not. You can set it to true before starting party reconnection, and reset it to false after either reconnection succeeded or failed. You can use this bool to disable certain UI buttons or game logic that shouldn't be accessible while reconnecting to a party.
To prevent players from accepting invites, you can override the CanAcceptSessionInvite
function in the KronosOnlineSession
class and simply return false while party reconnection is in progress.