Crossplay Integration Kit
Architecture

Hosting providers

Dedicated-server allocation through the shared hosting interface

Hosting providers

Hosting is provider-mediated. An adapter implements IUCIKHostingProvider, advertises only the operations it really supports, and registers with FUCIKHostingRegistry. Callers select an available provider with the required capability flags; provider SDK names and response formats never escape the adapter.

The shared types live in BetideCore/Public/Hosting/. FUCIK_ServerRequest describes allocation, FUCIK_ServerHandle identifies a provider-owned server, FUCIK_ServerStatus reports normalized state, and FUCIK_ConnectInfo is the single travel shape shared with matchmaking.

Capability table

ProviderRequestPollTerminateList/BrowseReservationsLatency/RegionsBackfillPushJoin token
EdgegapYesYesYesYesYesYesYesNoNo
GameLiftYesYesYesYesYesYesNoNoYes

Edgegap also advertises self-stop and named ports. A missing flag means orchestration must not call that operation; the base interface returns a normalized not-supported error for optional methods.

Request a server in C++

#include "Hosting/UCIKHostingRegistry.h"

TSharedPtr<IUCIKHostingProvider> Provider = FUCIKHostingRegistry::Get().GetPrimary();
if (!Provider.IsValid() ||
    !EnumHasAnyFlags(Provider->GetCapabilities(), EUCIK_HostingCapabilities::RequestServer))
{
    return;
}

FUCIK_ServerRequest Request;
Request.Version = TEXT("1.0.0");
Request.PreferredRegions = { TEXT("us-east") };
Request.MaxPlayers = 8;
Request.IdempotencyKey = FGuid::NewGuid().ToString();

Provider->RequestServer(Request,
    FBetideCallback<FUCIK_ServerHandle>::CreateLambda(
        [](const TBetideResult<FUCIK_ServerHandle>& Result)
        {
            if (Result.bOk)
            {
                TrackAllocation(Result.GetValue());
            }
        }));

Use GetStatus or FUCIKHostingPoller until the phase is Ready, then travel using Status.ConnectInfo.ToUrl(). Prefer OnStatusChanged() when the provider advertises StatusPush.

Write an adapter

Implement the three required operations (RequestServer, GetStatus, and OnStatusChanged) plus GetProviderId, GetCapabilities, and IsAvailable. Override optional methods only when the backend supports them. Normalize raw phases into EUCIK_ServerPhase, map all failures to FBetideError, preserve the provider name in every handle/connect result, and invoke each callback exactly once on the game thread.

Register a shared instance from the provider module and unregister it before releasing the instance:

void FMyHostingModule::StartupModule()
{
    Provider = MakeShared<FMyHostingProvider>();
    FUCIKHostingRegistry::Get().Register(Provider.ToSharedRef(), 50);
}

void FMyHostingModule::ShutdownModule()
{
    FUCIKHostingRegistry::Get().Unregister(TEXT("MyHosting"));
    Provider.Reset();
}

Test capability-gated optional methods, status mapping, idempotent allocation, callback completion, malformed responses, and shutdown with an in-flight request.

On this page