Skip to main content

Finding a session

To join a multiplayer game, you'll need to search for available sessions.

Default search filters

To ensure that you only get usable session results, the EOS plugin adds the following search filters to your search by default:

  • Only sessions that have a listening game server are returned. That is, the Unreal Engine instance that created the session must be running a listen server or be a dedicated server.
  • Only sessions which are not full and have at least one slot available are returned as of API version 2022-02-11.

If you can't see your game session when searching for sessions, try the following troubleshooting steps:

  1. Ensure that the session appears in the EOS backend by opening the Dev Portal and searching for the session ID. The session ID is emitted in the Output Log and log files of the server.
  2. Check the __EOS_bListening attribute of the session in the EOS backend. If it's false, then the session won't be returned by default because either the game server isn't listening, or you haven't configured your networking drivers correctly in your INI files, which prevents the plugin from being aware that the server is listening for connections.
  3. Check that the game session isn't considered full and has at least one player slot available.
  4. Try running the search again. The sessions list is eventually consistent, which means it can take a few seconds (and a few attempts) for a game session to start appearing in it.

Including non-listening sessions

To search for only non-listening sessions, add the following search filter:

Search->QuerySettings.Set(
FName(TEXT("__EOS_bListening")),
false,
EOnlineComparisonOp::Equals);

To search for both listening and non-listening sessions, add the following search filter:

Search->QuerySettings.Set(
FName(TEXT("__EOS_bListening")),
FVariantData() /* Empty value */,
EOnlineComparisonOp::Equals);

Including full sessions

To include sessions which are full, add the following search filter:

Search->QuerySettings.SearchParams.Add(
FName(TEXT("minslotsavailable")),
FOnlineSessionSearchParam(
(int64)0L,
EOnlineComparisonOp::GreaterThanEquals));
caution

The Set function does not have an implementation for int64 values. You must use int64 when querying on integer session attributes, so you have to use the longer SearchParams.Add form to add these kinds of search filters.

If you use the Set function accidentally, you'll get a linker error similar to the one shown below. The fix is to switch to using SearchParams.Add instead.

unresolved external symbol "public: void __cdecl FOnlineSearchSettings::Set<__int64>
class FName,__int64 const &,enum EOnlineComparisonOp::Type)" (??$Set@_J@FOnlineSearchSettings
@@QEAAXVFName@@AEB_JW4Type@EOnlineComparisonOp@@@Z) referenced in function "..."

Finding a session

First, get the online session interface:

#include "OnlineSubsystem.h"
#include "OnlineSubsystemUtils.h"
#include "Interfaces/OnlineSessionInterface.h"

// ...

IOnlineSubsystem* Subsystem = Online::GetSubsystem(this->GetWorld());
IOnlineSessionPtr Session = Subsystem->GetSessionInterface();

Next, create the session settings:

TSharedRef<FOnlineSessionSearch> Search = MakeShared<FOnlineSessionSearch>();
// Remove the default search parameters that FOnlineSessionSearch sets up.
Search->QuerySettings.SearchParams.Empty();

// Add your search settings here. If you're including both listening and non-listening sessions as per the __EOS_bListening example above, then you must include at least one additional filter, or EOS will not return any search results.
Search->QuerySettings.Set(
FName(TEXT("SessionSetting")),
FString(TEXT("SettingValue")),
EOnlineComparisonOp::Equals);

Register the event handler so you know when you're received the list of available sessions. Note that we're passing the Search instance as a bound parameter to the delegate so we can retrieve it when the callback fires. FindSessionsDelegateHandle is declared as an FDelegateHandle.

this->FindSessionsDelegateHandle =
Session->AddOnFindSessionsCompleteDelegate_Handle(FOnFindSessionsComplete::FDelegate::CreateUObject(
this,
&UMyClass::HandleFindSessionsComplete,
Search));

Then call FindSession with your session settings:

if (!Session->FindSessions(0, Search))
{
// Call didn't start, return error.
}

When your callback fires, you can iterate through the returned results. Make sure you clear deregister the event handler.

void UMyClass::HandleFindSessionsComplete(
bool bWasSuccessful,
TSharedRef<FOnlineSessionSearch> Search)
{
IOnlineSubsystem *Subsystem = Online::GetSubsystem(WorldContextObject->GetWorld());
IOnlineSessionPtr Session = Subsystem->GetSessionInterface();

if (bWasSuccessful)
{
for (auto RawResult : Search->SearchResults)
{
if (RawResult.IsValid())
{
FString ConnectInfo;
if (Session->GetResolvedConnectString(RawResult, NAME_GamePort, ConnectInfo))
{
// Store both RawResult and ConnectInfo in an array or some kind of temporary storage. You will need both values when you join the session later.

// If you only want to get the first result, break the loop here.
break;
}
}
}
}

Session->ClearOnFindSessionsCompleteDelegate_Handle(this->FindSessionsDelegateHandle);
this->FindSessionsDelegateHandle.Reset();
}

Once you have stored the search results and connection strings somewhere, you can proceed to Joining a session.