---
title: "Connect to a dedicated server"
description: "Allocate a server and connect players with shared connection information."
seo:
  noindex: true
---

{/* Copyright (c) 2026 Betide Studio. All Rights Reserved. */}

Deploy a server build with [GameLift](/integrations/aws/gamelift) or [Edgegap](/integrations/edgegap/deployment), then select the provider under **Hosting**. Hosting requests allocate a deployed version; they do not build or upload the game.

## Request a server

**Blueprint**

<BlueprintViewer title="Request a server" src="/blueprints/crossplay-request-server.txt" />

**C++**

Game module dependencies: `UCIKCore`, `BetideCore`.

```cpp
#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

**Blueprint**

<BlueprintViewer title="Check readiness" src="/blueprints/crossplay-check-server-ready.txt" />

**C++**

Game module dependencies: `UCIKCore`, `BetideCore`.

```cpp
#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](/integrations/aws/gamelift#validate-player-reservations).

## Connect and clean up

**Blueprint**

<Accordion>
  <AccordionItem title="Reserve player slots">
<BlueprintViewer title="Reserve player slots" src="/blueprints/crossplay-reserve-player-slots.txt" />
  </AccordionItem>
  <AccordionItem title="Travel to a server">
<BlueprintViewer title="Travel to a server" src="/blueprints/crossplay-travel-connect-info.txt" />
  </AccordionItem>
  <AccordionItem title="Terminate a server">
<BlueprintViewer title="Terminate a server" src="/blueprints/crossplay-terminate-server.txt" />
  </AccordionItem>
  <AccordionItem title="Browse servers">
<BlueprintViewer title="Browse servers" src="/blueprints/crossplay-list-servers.txt" />
  </AccordionItem>
  <AccordionItem title="List hosting regions">
<BlueprintViewer title="List hosting regions" src="/blueprints/crossplay-query-regions.txt" />
  </AccordionItem>
  <AccordionItem title="Measure region latency">
<BlueprintViewer title="Measure region latency" src="/blueprints/crossplay-measure-latency.txt" />
  </AccordionItem>
  <AccordionItem title="Ping a server">
<BlueprintViewer title="Ping a server" src="/blueprints/crossplay-server-ping.txt" />
  </AccordionItem>
</Accordion>

**C++**

Game module dependencies: `UCIKCore`, `BetideCore`.

<Accordion>

  <AccordionItem title="Reserve player slots">

```cpp
#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);
            }));
}
```

  </AccordionItem>

  <AccordionItem title="Terminate a server">

```cpp
#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"));
        }));
}
```

  </AccordionItem>

  <AccordionItem title="Browse servers">

```cpp
#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);
                   }));
}
```

  </AccordionItem>

  <AccordionItem title="List hosting regions">

```cpp
#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);
                }));
}
```

  </AccordionItem>

  <AccordionItem title="Measure region latency">

```cpp
#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);
                }));
}
```

  </AccordionItem>

  <AccordionItem title="Ping a server">

```cpp
#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());
                         }));
}
```

  </AccordionItem>

  <AccordionItem title="Travel to a server">

```cpp
#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"));
        }));
}
```

  </AccordionItem>
</Accordion>

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.
