Finding a session
To join a multiplayer game, you'll need to search for available sessions.
Default search filters
- C++
- Blueprints
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:
- 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.
- Check the
__EOS_bListening
attribute of the session in the EOS backend. If it'sfalse
, 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. - Check that the game session isn't considered full and has at least one player slot available.
- 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));
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
- C++
- Blueprints
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.