Skip to main content
Last updated on August 3, 2026

Set up P2P transport using OSS

This guide covers the Unreal Engine P2P-specific transport setup and host connection behavior for a matched game session.

For the shared Matchmaking flow, including creating match tickets, handling match results, and joining the game session, see Integrate matchmaking (Unreal). When you reach the host connection step in that guide, choose the P2P tab and use this page for the transport prerequisites.

Plugin dependencies

P2P using OSS requires the full AccelByte OSS plugin suite including the Network Utilities plugin for P2P functionality. For detailed dependency information, see UE Plugin Dependencies Guide.

Prerequisites

  • Configure the match pool to use a session template with the P2P session type. See Configure P2P.

  • Enable Sessions V2 in the AccelByte Online Subsystem (OSS) by adding the following to the DefaultEngine.ini file:

    [OnlineSubsystemAccelByte]
    bEnableV2Sessions=true
  • Enable AccelByteNetworkUtilities by adding the following to DefaultEngine.ini:

    [AccelByteNetworkUtilities]
    UseTurnManager=true
    HostCheckTimeout=5

    [/Script/AccelByteNetworkUtilities.IpNetDriverAccelByte]
    NetConnectionClassName=AccelByteNetworkUtilities.IpConnectionAccelByte
    AllowDownloads=false

    [/Script/Engine.Engine]
    !NetDriverDefinitions=ClearArray
    +NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/AccelByteNetworkUtilities.IpNetDriverAccelByte",DriverClassNameFallback="/Script/OnlineSubsystemUtils.IpNetDriver")
    +NetDriverDefinitions=(DefName="DemoNetDriver",DriverClassName="/Script/Engine.DemoNetDriver",DriverClassNameFallback="/Script/Engine.DemoNetDriver")
note

Non-seamless travel fail workaround

During non-seamless travel, Unreal Engine's base networking class (UIpConnection) attempts to perform DNS resolution on the AccelByte IP format, even though this format is not a valid DNS hostname. As a result, the resolution fails and produces a network error.

To avoid this issue, set bNonSeamlessTravelUseNewConnection=true in your DefaultEngine.ini file under the [AccelByteNetworkUtilities] section. Enabling this option ensures that DisableAddressResolution() is invoked before the base connection initialization, preventing Unreal Engine from attempting DNS resolution on the AccelByte address.

[AccelByteNetworkUtilities]
bNonSeamlessTravelUseNewConnection=true

Connect after joining a P2P game session

After the shared Matchmaking flow joins the game session, check whether the local player is the P2P host. The host should travel as a listen server. Other members should travel to the resolved P2P connect string.

const FOnlineSessionAccelBytePtr SessionInterface = GetSessionInterface();
check(SessionInterface.IsValid());

FNamedOnlineSession* Session = SessionInterface->GetNamedSession(SessionName);
check(Session != nullptr);

TSharedPtr<FOnlineSessionInfoAccelByteV2> SessionInfo =
StaticCastSharedPtr<FOnlineSessionInfoAccelByteV2>(Session->SessionInfo);
check(SessionInfo.IsValid());

if (SessionInfo->GetServerType() != EAccelByteV2SessionConfigurationServerType::P2P)
{
return;
}

const FUniqueNetIdPtr LocalPlayerId = GetUniquePlayerId();
if (!ensure(LocalPlayerId.IsValid()))
{
return;
}

ULocalPlayer* LocalPlayer = GetLocalPlayer();
if (!ensure(LocalPlayer != nullptr))
{
return;
}

APlayerController* Controller = LocalPlayer->GetPlayerController(GetWorld());
if (!ensure(Controller != nullptr))
{
return;
}

FString TravelUrl{};
if (SessionInterface->GetResolvedConnectString(SessionName, TravelUrl, NAME_GamePort) && !TravelUrl.IsEmpty())
{
if (SessionInterface->IsPlayerP2PHost(LocalPlayerId, SessionName))
{
FString MapName;
Session->SessionSettings.Get(SETTING_MAPNAME, MapName);
Controller->ClientTravel(FString::Printf(TEXT("%s?listen"), *MapName), TRAVEL_Absolute);
}
else
{
Controller->ClientTravel(TravelUrl, TRAVEL_Absolute);
}
}
tip

For debugging purposes, use the Relay (TURN) as the Interactive Connectivity Establishment (ICE) connection by passing the additional parameter -iceforcerelay during the game launch.

Troubleshooting

  • To confirm that P2P connection has been established, check the ICE/WebRTC data-channel result from AccelByte Network Utilities. Register RegisterICERequestConnectFinishedDelegate(...) and treat EAccelByteP2PConnectionStatus::Success as the network-level signal that the peer connection is established. A connected Lobby websocket or a successful JoinSession() only confirms service/session connectivity; it does not prove that the P2P data channel is connected. For Private Cloud observability, keep bSendMetricAutomatically=true so Network Utilities sends the TURN connection metric after the ICE connection succeeds.
  • If JoinSession() succeeds but travel fails, verify the AccelByteNetworkUtilities net driver configuration and add bNonSeamlessTravelUseNewConnection=true when using non-seamless travel.
  • If clients connect directly but fail when relay is required, verify TURN Manager is enabled, TURN regions are available for the namespace, and run with -iceforcerelay to reproduce the relay path.