Unreal Engine Dedicated Server Backend: SDK, REST & Persistence
Build a UE dedicated-server backend with Crux's beta C++ plugin or REST/OpenAPI fallback while Unreal keeps simulation authority and replication.
Unreal Engine already gives you the hard realtime part: an authoritative client/server model, replication, RPCs and a headless dedicated-server build. The production backend is a separate concern: identity, persistent player data, progression, leaderboards, live config and the registry/orchestration metadata that survives one server process.
Important boundary: Crux now ships a beta Unreal C++ plugin under sdks/sdk-unreal. Its wire protocol and structure tests pass, but it has not yet been compiled with Unreal Build Tool against the engine. Treat the first real UBT build/live call as part of evaluation. The public REST/OpenAPI surface through FHttpModule remains the verified fallback. Crux still does not host general Unreal dedicated-server fleets.
1. What Unreal already owns
Epic's current dedicated-server documentation describes Unreal's network multiplayer as authoritative client/server. A dedicated server is a headless game instance: no local player and no rendering, with remote clients connecting to the authoritative host. Epic notes listen servers can be reasonable for casual/co-op games, while dedicated servers are particularly useful for large-scale or competitive games.
The same Epic guide currently requires a source build and a C++ multiplayer project for its dedicated-server tutorial, and uses a separate Server.Target.cs target to build the server executable.
2. What the external backend owns
- Identity: turn a guest/email/platform identity into a backend player session.
- Persistence: saves, progression, inventory and other data that outlives the Unreal process.
- Stats / achievements / leaderboards: backend-owned results rather than trusting the client that benefits from them.
- Live config: operational values that should not require a new packaged build.
- Server registry: advertise only healthy/joinable dedicated processes and expire stale ones.
3. Choose the beta plugin or Unreal's built-in HTTP module
The first-party plugin wraps the same public API used by every other Crux SDK. Copy sdks/sdk-unreal/Crux/ into your project's Plugins/ directory and add Crux to your target dependencies. Because the plugin has not yet had a real UBT build in this repository, keep the REST path available while you validate it.
#include "CruxClient.h"
TSharedPtr<FCruxClient> Crux = FCruxClient::ForPlayer(
TEXT("https://crux.supercraft.host"),
TEXT("YOUR_PROJECT_ID"),
TEXT("YOUR_ENVIRONMENT_ID"),
TEXT("YOUR_PUBLISHABLE_KEY")
);
Crux->LoginAnonymous(FString(), [Crux](const FCruxResult& Result)
{
if (Result.bSuccess)
{
UE_LOG(LogTemp, Log, TEXT("player %s"), *Crux->GetPlayerId());
}
});
If you prefer the lowest-level proof, or hit an engine-version issue in the beta plugin, Epic exposes FHttpModule and IHttpRequest for ordinary HTTP calls. The same anonymous-login request proves the wire contract without the plugin:
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
void UMyBackendService::BeginAnonymousLogin()
{
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request =
FHttpModule::Get().CreateRequest();
Request->SetURL(TEXT("https://crux.supercraft.host/v1/auth/anonymous"));
Request->SetVerb(TEXT("POST"));
Request->SetHeader(TEXT("Authorization"), TEXT("ApiKey YOUR_PUBLISHABLE_KEY"));
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
Request->SetContentAsString(TEXT("{}"));
Request->OnProcessRequestComplete().BindUObject(
this, &UMyBackendService::OnAnonymousLogin
);
Request->ProcessRequest();
}
The response gives you the player/session data needed for player-scoped calls. Persist the anonymous device id returned by the service so a guest does not become a fresh player on every launch.
4. Client and dedicated-server credentials are different
| Caller | Credential | Rule |
|---|---|---|
| Shipped Unreal client | Publishable key + player token | Never embed server/secret credentials |
| Trusted UE dedicated server | Server token | Authoritative cross-player and server-registry operations |
| Operator / CI | Secret operator credential | Administrative operations only |
5. Online Subsystem / Online Services are not the persistence layer by definition
Unreal provides Online Subsystem and the newer Online Services framework to integrate platform/online functionality such as Epic, Steam and console services. Keep those when they solve the platform job. A custom application backend is complementary when you need durable game-specific data or business rules behind your own HTTP contract.
6. Hosting and persistence must stay separable
Run the dedicated server with the hosting/orchestration provider that fits your fleet. Crux is not currently a UE process host. Your headless server can still register itself, heartbeat, read live config and write authoritative results through a stable backend API. That separation makes a future hosting migration a fleet change rather than a player-data migration.
7. Avoid these production mistakes
- Inventing a validation endpoint. Use the actual OpenAPI contract rather than copying a blog URL that is not a deployed route.
- Client-authoritative progression. Rewards with economic value should be validated or written by a trusted server/backend path.
- Putting server tokens in packaged clients. Treat them as infrastructure secrets.
- Assuming every UE game requires dedicated hosting. Choose listen vs dedicated based on authority, fairness, scale and product requirements.
- Coupling fleet provider callbacks directly to player persistence. Keep provider-specific lifecycle code behind a thin adapter.
Primary references
Sources
Technical, pricing, and product claims were checked against these primary sources on the verification date above.