Skip to content
UCIK Docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

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

Request a server
Preparing your graph…

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

Check readiness
Preparing your graph…

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
Reserve player slots
Preparing your graph…

Loading the interactive viewer.

Travel to a server
Travel to a server
Preparing your graph…

Loading the interactive viewer.

Terminate a server
Terminate a server
Preparing your graph…

Loading the interactive viewer.

Browse servers
Browse servers
Preparing your graph…

Loading the interactive viewer.

List hosting regions
List hosting regions
Preparing your graph…

Loading the interactive viewer.

Measure region latency
Measure region latency
Preparing your graph…

Loading the interactive viewer.

Ping a server
Ping a server
Preparing your graph…

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.

Was this page helpful?