Connect to a dedicated server
Allocate a server and connect players with shared connection information.
Deploy a server build with GameLift or Edgegap, then select the provider under Hosting. Hosting requests allocate a deployed version; they do not build or upload the game.
Request a server
Loading the interactive viewer.
Game module dependencies: UCIKCore, BetideCore.
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void AllocateMatchServer(UGameInstance &GameInstance, const FString &Version)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
FUCIK_ServerRequest Request;
Request.Version = Version;
Request.MaxPlayers = 4;
Service->RequestServer(
Request, FBetideCallback<FUCIK_ServerHandle>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<FUCIK_ServerHandle> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Server request: %s"), *Result.GetValue().Id);
}));
}Keep the returned Server Handle. A request being accepted does not mean the server is ready. Supply regions, measured latency, player IDs, and metadata only as required by your provider’s deployment.
Check readiness
Loading the interactive viewer.
Game module dependencies: UCIKCore, BetideCore.
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void CheckMatchServer(UGameInstance &GameInstance, const FUCIK_ServerHandle &Server)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
Service->GetServerStatus(
Server, FBetideCallback<FUCIK_ServerStatus>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<FUCIK_ServerStatus> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Server phase: %d"),
static_cast<int32>(Result.GetValue().Phase));
if (Result.GetValue().Phase == EUCIK_ServerPhase::Failed)
UE_LOG(LogUCIK, Warning, TEXT("%s"),
*Result.GetValue().Error.GetLogString());
if (Result.GetValue().Phase == EUCIK_ServerPhase::Ready)
{
UE_LOG(LogUCIK, Log, TEXT("Server ready in region: %s"),
*Result.GetValue().ConnectInfo.Region);
}
}));
}The readiness example checks once. Poll with a bounded interval and timeout, allowing only one request at a time. Stop on Ready, Failed, or Terminated. Keep the full Connect Info for travel and player admission. The travel URL uses its endpoint but does not transmit Token; pass required reservation tokens through your game’s admission flow, as described for GameLift.
Connect and clean up
Reserve player slots
Loading the interactive viewer.
Travel to a server
Loading the interactive viewer.
Terminate a server
Loading the interactive viewer.
Browse servers
Loading the interactive viewer.
List hosting regions
Loading the interactive viewer.
Measure region latency
Loading the interactive viewer.
Ping a server
Loading the interactive viewer.
Game module dependencies: UCIKCore, BetideCore.
Reserve player slots
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void ReservePlayerSlots(UGameInstance &GameInstance, const FUCIK_ServerHandle &Server,
const TArray<FUCIK_PlayerHandle> &Players)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
Service->RequestPlayerSlots(
Server, Players,
FBetideCallback<TArray<FUCIK_ConnectInfo>>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<TArray<FUCIK_ConnectInfo>> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
for (const FUCIK_ConnectInfo &Connection : Result.GetValue())
UE_LOG(LogUCIK, Log, TEXT("%s"), *Connection.Host);
}));
}Terminate a server
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void TerminateMatchServer(UGameInstance &GameInstance, const FUCIK_ServerHandle &Server)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
Service->TerminateServer(
Server,
FBetideCallbackVoid::CreateWeakLambda(&GameInstance, [](const TBetideResult<void> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Termination request completed"));
}));
}Browse servers
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void BrowseOpenServers(UGameInstance &GameInstance)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
FUCIK_ServerQuery Query;
Query.MinOpenSlots = 1;
Query.MaxResults = 20;
Service->ListServers(
Query, FBetideCallback<TArray<FUCIK_ServerStatus>>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<TArray<FUCIK_ServerStatus>> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
for (const FUCIK_ServerStatus &Server : Result.GetValue())
UE_LOG(LogUCIK, Log, TEXT("%s"), *Server.Handle.Id);
}));
}List hosting regions
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void ListHostingRegions(UGameInstance &GameInstance)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
Service->QueryRegions(
{}, FBetideCallback<TArray<FUCIK_Region>>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<TArray<FUCIK_Region>> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
for (const FUCIK_Region &Region : Result.GetValue())
UE_LOG(LogUCIK, Log, TEXT("%s"), *Region.Id);
}));
}Measure region latency
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void MeasureRegionLatency(UGameInstance &GameInstance)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
Service->MeasureLatency(
{}, FBetideCallback<TMap<FString, float>>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<TMap<FString, float>> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
for (const TPair<FString, float> &Region : Result.GetValue())
UE_LOG(LogUCIK, Log, TEXT("%s: %.1f ms"), *Region.Key, Region.Value);
}));
}Ping a server
#include "Engine/GameInstance.h"
#include "Hosting/UCIKHostingSubsystem.h"
#include "UCIKCore.h"
void PingServer(UGameInstance &GameInstance, const FUCIK_ConnectInfo &ConnectInfo)
{
auto *Service = GameInstance.GetSubsystem<UUCIKHostingSubsystem>();
if (!Service)
return;
Service->MeasureServerPing(
ConnectInfo, FBetideCallback<float>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<float> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("%.1f ms"), Result.GetValue());
}));
}Travel to a server
#include "Engine/GameInstance.h"
#include "Travel/UCIKTravelSubsystem.h"
#include "UCIKCore.h"
void TravelToServer(UGameInstance &GameInstance, const FUCIK_ConnectInfo &ConnectInfo)
{
auto *Service = GameInstance.GetSubsystem<UUCIKTravelSubsystem>();
if (!Service)
return;
Service->TravelToConnectInfo(
ConnectInfo,
FBetideCallback<bool>::CreateWeakLambda(&GameInstance, [](const TBetideResult<bool> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Travel requested"));
}));
}An empty region provider uses the first available provider in Hosting policy. Server listings may be partial when another provider fails; servers with unknown capacity remain in the results.
Keep deployment/tooling credentials outside client builds. Use the provider’s supported client credential or backend route for allocation. Stop polling and release unused capacity when a player cancels. ICMP ping can fail when a healthy server blocks echo requests.