Skip to main content

Configure cross-platform matchmaking

Last updated on March 22, 2024

Overview

Crossplay enables players on any platform your game supports to play together. While this is generally the preferred experience for players, some platforms require games support the ability for players to opt-out.

The Matchmaking service defaults with crossplay on, but can be configured to support player control using custom parameters passed from the game client to the service when requesting a match. This allows players to fully opt-in or out of crossplay or choose a subset of platforms they would prefer to match with.

In this guide, you will learn how to configure a match ruleset to support crossplay validation and pass a player's preferences as a custom parameter as part of the matchmaking process.

note

This guide assumes you are using the default match function available with the Matchmaking service. If you plan to write your own function using Extend, you may need to build similar logic.

Goals

  • Provide an overview of how to configure a match ruleset to respect player choice to opt-in or opt-out of crossplay.
  • Provide an overview of how to submit a match ticket with a custom parameter to pass player choice for crossplay.

Prerequisites

Configuring a match ruleset to support custom parameters

To support player control, you need to configure a match ruleset with custom parameter criteria specific to crossplay. To do this, you need to update the ruleset JSON configuration to include match options, as the below example illustrates.

In this example, we assume your game is a four player co-op game and has released on Steam, XBL, and PSN. In the ruleset JSON, you can see a match option with the name cross_platform has been added with the type all. The name of the option will act as the key for the values to be passed as a parameter from the game client. Type allows you to define the criteria used to evaluate the passed values, and can be set to one of these options:

  • All - Players must be matched with others who have the same parameters and values.
  • Any - Players must be matched with others who have the same option parameter name and at least have one matching value.
  • Unique - Players must be matched with others who have the same option parameter name, but different values.

Because all is set in this example, only players who have exact matching values as their preference can be matched together. For example, if one player set Steam and another set XBL and Steam, they would not be able to match.

{
"auto_backfill": true,
"alliance": {
"min_number": 1,
"max_number": 1,
"player_min_number": 4,
"player_max_number": 4
},
"match_options": {
"options": [
{
"name": "cross_platform",
"type": "all"
}
]
}
}

Add the player cross-play selection to the matchmaking request in the game client

Once a match ruleset is configured, you can update the matchmaking call in the game client to support passing player preferences as custom parameters as part of the match request.

Below are examples of how the passed values will be interpreted with example codes showing how to pass custom parameters from the game client as part of the matchmaking request.

  • Player wants to cross-play with any platform user:
    • "cross_platform": ["steam", "xbl", "ps5", "ps4"]
  • Player wants to play only with other XBL platform users:
    • "cross_platform": ["xbl"]
  • Player wants to cross-play with only console users (no PC users):
    • "cross_platform": ["xbl", "ps5", "ps4"]
info

The backend will do a validation to prevent malicious players from tampering the cross_platform value. The backend will check the cross_platform value sent by a player if it contains the player's active platform. For example, when a Steam player sends a cross_platform value of ["ps5", ps4], the backend will add steam into the value, e.g., ["steam", "ps5", "ps4].

const IOnlineSubsystem* Subsystem = Online::GetSubsystem(GetWorld());
if (!ensure(Subsystem != nullptr))
{
return;
}

const FOnlineSessionAccelBytePtr SessionInterface = StaticCastSharedPtr<FOnlineSessionV2AccelByte>(Subsystem->GetSessionInterface());
if (!ensure(SessionInterface.IsValid()))
{
return;
}
const FUniqueNetIdPtr LocalPlayerId = GetUniquePlayerId();
if (!ensure(LocalPlayerId.IsValid()))
{
return false;
}

// Create a new search handle instance for matchmaking. Importantly, you will need to set the match pool that you are searching for with SETTING_SESSION_MATCHPOOL, as shown below.
TSharedRef<FOnlineSessionSearch> MatchmakingSearchHandle = MakeShared<FOnlineSessionSearch>();
MatchmakingSearchHandle->QuerySettings.Set(SETTING_SESSION_MATCHPOOL, FString(TEXT("YOUR_MATCHPOOL_NAME_GOES_HERE")), EOnlineComparisonOp::Equals);

// Custom attributes can be added to the SearchHandle’s QuerySettings:
MatchmakingSearchHandle->QuerySettings.Set(
FName(TEXT("cross_platform")),
TEXT("steam"), EOnlineComparisonOp::Equals);

// Bind a function that has a return type of void and these parameters:
// FName SessionName, bool bWasSuccessful
const FOnMatchmakingCompleteDelegate OnMatchmakingCompleteDelegate = /* Bind to lambda or class method */;
SessionInterface->AddOnMatchmakingCompleteDelegate_Handle(OnMatchmakingCompleteDelegate);

if (SessionInterface->StartMatchmaking(USER_ID_TO_MATCHMAKING_USER_ARRAY(LocalPlayerId.ToSharedRef()), NAME_GameSession, FOnlineSessionSettings(), MatchmakingSearchHandle, OnStartMatchmakingCompleteDelegate))
{
// Update the current search result handle class member with the search handle passed to the matchmaking service.
CurrentMatchmakingSearchHandle = MatchmakingSearchHandle;
}