Party Implementation #
Party flows are built and customized using a combination of calls and plugin methods, which have been grouped on this page by category. Each section includes descriptions of SDK actions and related Party Plugin methods.
The categories are:
- Create a party
- Join or leave a party
- Manage invites
- Make selections
- Set ready states
- Assign the leader role
- Kick players
- Specify preferred game server zones
- Enter matchmaking
- Return from matchmaking
- Return from a game instance
For a full list of all available calls and Party Plugin methods, see All Calls and Methods.
Create a party #
A party is initialized and the first player is added as the leader.
Actions: CreateParty
Functions: initializeParty
, onAddPlayer
Actions #
Create a party
The CreateParty
RPC call requires the following data:
ExtCreateRequest
: custom-defined content related to party creationExtPlayerJoinRequest
: custom-defined content related to players joining- (optional) Game server zones: preferred game server zones, which can be changed later (see
SetPreferredGameServerZones
) - (optional) Game server zone to ping map: a ping map that can be changed later (see
SetGameServerZoneToPing
)TArray<FString> preferredGameServerZones; preferredGameServerZones.Add("gameServerZone1"); preferredGameServerZones.Add("gameServerZone2"); TMap<FString, int32> gameServerZoneToPing; gameServerZoneToPing.Add("gameServerZone1", 10); gameServerZoneToPing.Add("gameServerZone2", 20); UPragmaPartyService::FOnCompleteDelegate OnPartyCreatedDelegate; OnPartyCreatedDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result) { }); Session->GameLoopApi().CreateParty( FPragma_Party_ExtCreateRequest{}, FPragma_Party_ExtPlayerJoinRequest{}, preferredGameServerZones, gameServerZoneToPing, OnPartyCreatedDelegate );
session.GameLoopApi.CreateParty(new ExtCreateRequest(), new ExtPlayerJoinRequest());
{ "requestId": 1, "type": "PartyRpc.CreateV1Request", "payload": { "createRequestExt":{}, "playerJoinRequestExt":{}, "gameClientVersion":"gameClientVersion1", "preferredGameServerZones": [ "gameServerZone1", "gameServerZone2" ], "gameServerZoneToPing": { "gameServerZone1": 10, "gameServerZone2": 20 } } }
Functions #
The following function initializes the party, leveraging the data from the ExtCreateRequest
.
suspend fun initializeParty(
party: Party,
requestExt: ExtCreateRequest,
partyConfig: PartyConfig
)
Once the blank party is created, the first player is added as the party’s leader using the onAddPlayer
function. Note that this is the same function that is used to add other players in the next section.
suspend fun onAddPlayer(
requestExt: ExtPlayerJoinRequest,
playerToAdd: PartyPlayer,
party: Party,
partyConfig: PartyConfig
)
If a player is already in a party when attempting to make a new party, they’re automatically removed from the existing party.
Join or leave a party #
Players join and leave parties.
Actions: JoinWithInviteCode
, JoinWithPartyId
, Leave
Functions: onAddPlayer
, onRemovePlayer
Actions #
Join by invite code
To join by invite code, use the JoinWithInviteCode
request. This includes the following information:
ExtPlayerJoinRequest
- invite code
- game client version
- map of pings to game server zones
UPragmaPartyService::FOnCompleteDelegate JoinWithInviteCodeDelegate; JoinWithInviteCodeDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result) { }); Session->GameLoopApi().JoinWithInviteCode( FPragma_Party_ExtPlayerJoinRequest {}, "CDCLGP", JoinWithInviteCodeDelegate );
session.Party.JoinWithInviteCode( new ExtPlayerJoinRequest(), "CDCLGP" );
{ "requestId": 3, "type": "PartyRpc.JoinWithInviteCodeV1Request", "payload": { "requestExt":{}, "inviteCode":"CDCLGP", "gameClientVersion":"gameClientVersion1" } }
Join by party ID
To join by party ID, use the JoinWithPartyId
request. This includes the following information:
ExtPlayerJoinRequest
- party ID
- game client version
- map of pings to game server zones
UPragmaPartyService::FOnCompleteDelegate JoinWithPartyIdDelegate; JoinWithPartyIdDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result) { }); Session->GameLoopApi().JoinWithPartyId( FPragma_Party_ExtPlayerJoinRequest{}, "5e359a34-8112-4a84-81d5-86f11f261f67", JoinWithPartyIdDelegate );
session.GameLoopApi.JoinWithPartyId( new ExtPlayerJoinRequest(), "5e359a34-8112-4a84-81d5-86f11f261f67" );
{ "requestId": 4, "type": "PartyRpc.JoinWithPartyIdV1Request", "payload": { "requestExt":{}, "partyId":"5e359a34-8112-4a84-81d5-86f11f261f67", "gameClientVersion":"gameClientVersion1" } }
Leave a party
The Leave
call allows players to voluntarily leave a party.
If a leader leaves a party, a random player in the party is made leader.
UPragmaPartyService::FOnCompleteDelegate LeavePartyDelegate;
LeavePartyDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result)
{
});
session->GameLoopApi().LeaveParty(LeavePartyDelegate);
session.GameLoopApi.LeaveParty(LeavePartyDelegate);
{
"requestId": 4,
"type": "PartyRpc.LeaveV1Request",
"payload": {
}
}
If a player disconnects from the engine or if they log into a second client, that player will be removed from the party.
Functions #
The onAddPlayer
function is used for the following calls which add players to a party: JoinWithInviteCode
and JoinWithPartyId
.
suspend fun onAddPlayer(
requestExt: ExtPlayerJoinRequest,
playerToAdd: PartyPlayer,
party: Party,
partyConfig: PartyConfig
)
The onRemovePlayer
function is used for calls that remove players from the party.
- This function is used when a player opts to leave a party and when a player is kicked; the
RemovalReason
includes which case. If a party is in matchmaking when either of these functions is called, the party is also removed from matchmaking.
suspend fun onRemovePlayer(
party: Party,
removedPlayer: PartyPlayer,
removalReason: RemovalReason
)
Manage invites #
Players respond to invites and invite their friends.
Actions: SendInvite
, RespondToInvite
Functions: onAddPlayer
Actions #
Send an invite
The RPC call SendInvite
sends an invitation to the listed player with a PartyRpc.InviteReceivedV1Notification
. This request contains the player ID of the invited player.
UPragmaPartyService::FOnCompleteDelegate SendInviteDelegate;
SendInviteDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result) {});
Session->GameLoopApi().SendInvite("f9525239-cd99-425d-9f14-1ff948c02553",
SendInviteDelegate
);
session.GameLoopApi.SendInvite(
new PragmaId("f9525239-cd99-425d-9f14-1ff948c02553")
);
{
"requestId": 1,
"type": "PartyRpc.SendInviteV1Request",
"payload": {
"inviteePlayerId": "f9525239-cd99-425d-9f14-1ff948c02553"
}
}
Respond to an invite
The RespondToInvite
call determines whether the player will join the party they’ve been invited to.
This request contains the following information:
ExtPlayerJoinRequest
: a developer-defined ext used to declare publicly visible player selections- invite ID including in the
SendInvite
call - boolean stating whether the player accepted or declined the invite
- game client version, which is used to calculate compatible game servers
- map of pings to game server zones
UPragmaPartyService::FOnCompleteDelegate RespondToPartyInviteDelegate; RespondToPartyInviteDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result) { }); Session->GameLoopApi().RespondToInvite( FPragma_Party_ExtPlayerJoinRequest{}, "89962f84-7edd-45b9-97c0-b6fd49fc8497", true, RespondToPartyInviteDelegate );
session.GameLoopApi.RespondToInvite( new ExtPlayerJoinRequest(), invite.InviteId, true );
{ "requestId": 2, "type": "PartyRpc.RespondToInviteV1Request", "payload": { "requestExt":{}, "inviteId":"89962f84-7edd-45b9-97c0-b6fd49fc8497", "accepted":true, "gameClientVersion":"gameClientVersion1" } }
Functions #
The onAddPlayer
function adds players to a party when they respond to an invite with a true
boolean.
suspend fun onAddPlayer(
requestExt: ExtPlayerJoinRequest,
playerToAdd: PartyPlayer,
party: Party,
partyConfig: PartyConfig
)
Make selections #
Players make selections, including setting both player and party options.
Actions: SetGameServerZoneToPing
, UpdatePlayerSelections
, UpdatePartySelections
Functions: updatePlayer
, updateParty
Actions #
Set map to ping
Individual players can call SetGameServerZoneToPing
to update the map of their ping to different game server zones.
UPragmaPartyService::FOnCompleteDelegate SetGameServerZoneToPingDelegate;
SetGameServerZoneToPingDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result){});
const TMap<FString, int32> ZoneToPing = {{"us-west", 100}};
Session()->GameLoopApi().SetGameServerZoneToPing(
ZoneToPing,
SetGameServerZoneToPingDelegate
);
var pingMap = new Dictionary<string, int> { { "us-west", 30 } };
var future = Runtime.Player().Party.SetGameServerZoneToPing(pingMap);
{
"requestId": 9,
"type": "PartyRpc.SetGameServerZoneToPing",
"payload": {
"gameServerZoneToPing": {"us-west": 100}
}
}
Update player selections
Update player selections using UpdatePlayerSelections
. This takes the ExtUpdatePlayerSelectionsRequest
parameter.
UPragmaPartyService::FOnCompleteDelegate UpdatePlayerSelectionsDelegate;
UpdatePlayerSelectionsDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result){});
Session->GameLoopApi().UpdatePlayerSelections(
FPragma_Party_ExtUpdatePlayerSelectionsRequest{},
UpdatePlayerSelectionsDelegate
);
session.GameLoopApi.UpdatePlayerSelections(
new ExtUpdatePlayerSelectionsRequest()
);
{
"requestId": 6,
"type": "PartyRpc.UpdatePlayerSelectionsV1Request",
"payload": {
"requestExt": {}
}
}
Update party selections
Update party selections using UpdatePartySelections
. This takes the ExtUpdatePartySelectionsRequest
parameter.
UPragmaPartyService::FOnCompleteDelegate UpdatePartySelectionsDelegate;
UpdatePartySelectionsDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result){}
);
Session->GameLoopApi().UpdatePartyV1(
FPragma_Party_ExtUpdatePartySelectionsRequest{},
UpdatePartySelectionsDelegate
);
session.GameLoopApi.UpdatePartySelections(
new ExtUpdatePartySelectionsRequest()
);
{
"requestId": 7,
"type": "PartyRpc.UpdatePartySelectionsV1Request",
"payload": {
"requestExt": {}
}
}
ext
data.Functions #
The updatePlayer
function allows players to make individual choices like characters, skins, or votes for maps using the ExtUpdatePlayerSelectionsRequest
.
suspend fun updatePlayer(
playerToUpdate: PartyPlayer,
requestExt: ExtUpdatePlayerSelectionsRequest,
party: Party,
partyConfig: PartyConfig
)
The updateParty
function allows players to set shared information like game mode, map, or difficulty using the ExtUpdatePartySelectionsRequest
.
- This call can be restricted to leader-only by writing the plugin implementation to reject changes based on roles.
suspend fun updateParty(
requestingPlayer: PartyPlayer,
requestExt: ExtUpdatePartySelectionsRequest,
party: Party,
partyConfig: PartyConfig
)
Set ready states #
Determine whether players are ready to enter matchmaking.
Actions: SetReadyState
Functions: canChangeReady
Actions #
Readying up
If players can set their ready state, they should use SetReadyState
which contains the ready
boolean.
UPragmaPartyService::FOnCompleteDelegate SetPartyReadyDelegate;
SetPartyReadyDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result)
{
});
Session->GameLoopApi().SetReadyState(true, SetPartyReadyDelegate);
session.GameLoopApi.SetReadyState(true);
{
"requestId": 5,
"type": "PartyRpc.SetReadyStateV1Request",
"payload": {
"ready": "true"
}
}
Functions #
The canChangeReady
function determines whether players are able to set their own ready state.
suspend fun canChangeReady(
player: PartyPlayer,
newReadyState: Boolean,
party: Party,
partyConfig: PartyConfig
): Boolean
Assign the leader role #
Assign the leader role to another player.
This action is only available to party leaders.
To assign the leader role to another player, use the AssignPartyLeader
call. This takes the player ID to assign leader status.
If PartyConfig.enableTransferPartyLeader
is set to true
, this call transfers the party leader role to the indicated player. If it’s set to false
, a new leader is made, resulting in multiple leaders.
UPragmaPartyService::FOnCompleteDelegate AssignPartyLeaderDelegate;
AssignPartyLeaderDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result)
{
});
Session->GameLoopApi().AssignPartyLeader(
"5e359a34-8112-4a84-81d5-87f11f261f77",
AssignPartyLeaderDelegate
);
session.GameLoopApi.AssignPartyLeader("5e359a34-8112-4a84-81d5-86f11f261f67");
{
"requestId": 3,
"type": "PartyRpc.AssignPartyLeaderV1Request",
"payload": {
"playerId":"5e359a34-8112-4a84-81d5-87f11f261f77"
}
}
Kick players #
Remove a player from a party.
This action is only available to party leaders.
To kick a player from the party, party leaders can use the KickPlayer
call, which takes the player ID for the kicked player. In the case of multiple leaders, one leader can kick another leader.
Session->GameLoopApi().KickPlayer(
PlayerId,
FOnCompleteDelegate& OnComplete
);
session.GameLoopApi.KickPlayer(
playerToKickId,
CompleteDelegate onComplete
)
{
"requestId": 5,
"type": "PartyRpc.KickV1Request",
"payload": {
"playerId":"5e359a34-8112-4a84-81d5-87f11f261f77"
}
}
The target player is removed from the party and the Party Plugin’s onRemovePlayer
method is invoked. The kicked player RemovedV1Notification
with a removal reason of KICKED. The remaining party members receive a notification with updated party state. If the kicked player is in matchmaking with the party, the party will be removed from matchmaking.
suspend fun onRemovePlayer(
party: Party,
removedPlayer: PartyPlayer,
removalReason: RemovalReason
)
Specify preferred game server zones #
Manually specify one or more preferred game server zones.
This action is only available to party leaders.
To manually specify preferred game server zones, party leaders can use the SetPreferredGameServerZones
call. This sets a list of acceptable game server zones for the entire party. Matchmaking can then take into account both manual game server zone selections and all party members’ pings to each game server zone as part of its game server allocation logic.
UPragmaPartyService::FOnCompleteDelegate SetPreferredGameServerZonesDelagate;
SetPreferredGameServerZonesDelagate.BindWeakLambda(this,
[this](TPragmaResult<> Result)
{
});
const TArray<FString> GameServerZones = {"us-west"};
Session()->GameLoopApi().SetPreferredGameServerZones(
GameServerZones,
SetPreferredGameServerZonesDelagate
);
var serverZones = new List<string> { "local" }
var future = Runtime.Player().GameLoopApi.SetPreferredGameServerZones(serverZones);
{
"requestId": 8,
"type": "PartyRpc.SetPreferredGameServerZonesV1Request",
"payload": {
"preferredGameServerZones": ["us-west"]
}
}
Enter matchmaking #
Enter matchmaking and send custom match data.
Actions: EnterMatchmaking
Functions: buildMatchmakingKey
, buildExtEnterMatchmaking
When entering matchmaking, a snapshot of the party’s state is captured, and is not automatically updated with changes.
Actions #
Enter matchmaking
To enter matchmaking, the leader can send EnterMatchmaking
.
- If a player without the leader role attempts to make this call, they receive the
PlayerNotLeader
error. - If any player has not set themselves to ready, the leader who called
EnterMatchmaking
receives thePlayersNotReady
error.
UPragmaPartyService::FOnCompleteDelegate EnterMatchmakingDelegate;
EnterMatchmakingDelegate.BindWeakLambda(this, [this](TPragmaResult<> Result)
{
});
Session->GameLoopApi().EnterMatchmaking(EnterMatchmakingDelegate);
session.GameLoopApi.EnterMatchmaking();
{
"requestId": 8,
"type": "PartyRpc.EnterMatchmakingV1Request",
"payload": {
}
}
Functions #
Once the EnterMatchmaking
call is made by the party leader, the buildMatchmakingKey
, buildExtMatchmakingParty
, and buildExtMatchmakingPlayer
functions are called by the plugin. These allow for customization of matchmaking keys and any other custom matchmaking content.
suspend fun buildMatchmakingKey(
party: Party
): ExtMatchmakingKey
suspend fun buildExtMatchmakingParty(
party: Party
): ExtMatchmakingParty
suspend fun buildExtMatchmakingPlayer(
party: Party
player: Player
): ExtMatchmakingPlayer
See Matchmaking Tasks to see what happens once a party enters matchmaking.
Return from matchmaking #
Process matchmaking instance exit scenarios.
Functions: returnFromMatchmaking
Functions #
Use the returnFromMatchmaking()
function to handle behaviors when a player returns from matchmaking. By default, no selections or relevant party fields are changed when a party leaves matchmaking. For example, if the party leaves matchmaking due to a player disconnecting, you may want to retain character selections so players don’t need to reselect their character.
suspend fun returnFromMatchmaking(
party: Party,
returningPlayers: List<PartyPlayer>,
config: PartyConfig
)
After the player and their party are removed from matchmaking, players receive a OnLeftMatchmaking
event.
Return from a game instance #
Process game instance exit scenarios.
Functions: returnFromMatch
Functions #
The returnFromMatch
method provides a way to handle players leaving a game instance. returnFromMatch
is called when a game instance ends or a player is removed from the game instance.
suspend fun returnFromMatch(
party: Party,
returningPlayers: List<PartyPlayer>,
config: PartyConfig
)
For example, you can use returnFromMatch
to require players to reselect a character after completing a game instance to encourage diverse character pools.
Upon returning from a game instance, players are returned to their original party, allowing them to quickly prepare for the next game instance and queue again.