Skip to content

Dedicated Server Bootstrapping

This document describes in detail how the RallyHere Unreal Integration handles bootstrapping a dedicated server. This process is a bit more complex than a standard Unreal Engine dedicated server, as it requires a few extra steps to ensure that the server is properly authenticated and connected to the RallyHere API.

Additionally, it details shutdown flow, which is important for making sure reporting and analytics are handled properly.

Overview

The integration provides a robust means for bootstrapping dedicated servers using the RallyHere allocation and session subsystems. This process ties together multiple separate elements of the RallyHere API and integration layer.

GameHostAdapter

This document assumes an overall understanding of the GameHostAdapter library, which is used to interface with the various hosting providers. For more information on this library, see Game Host Adapter

Bootstrapping Modes

Bootstrapping is done in one of two primary ways, as specified by the -rhbootstrapmode commandline argument. This commandline parameter has some special handling, as it is used by both the integration layer and the game host adapter layer.

For the integration layer, there are several modes that can be specified:

  • Disabled - this mode is the default and disables the bootstrapping flow entirely. This is useful for cases where the full bootstrapping flow would cause problems, since as Play In Editor
  • LoginOnly - this mode only logs the server into the RallyHere API, and does not attempt to host a session. This is useful for cases where the server is not hosting a session, but still needs to be authenticated.
  • AutoCreate - this mode will use the provider to reserve an allocation, and then create its own session for hosting. This may or may not use the GameHostAdapter library.
  • All other options - all other values are assumed to be handled by the GameHostAdapter library, and will be passed through to it. These modes determine how it handles different hosting providers.

Classes

Main Classes

The following are the primary classes used for dedicated server bootstrapping:

  • URH_GameInstanceSubsystem - This class is the top level class for the game instance plugins, and contains the bootstrapper and many other important elements.
  • URH_GameInstanceServerBootstrapper - This class is responsible for bootstrapping the server, retrieving or creating the session it will run, and monitoring the server’s state.
  • URH_GameInstanceSessionSubsystem - This class is responsible for managing the session that the server is running. It is passed the session by the URH_GameInstanceServerBootstrapper, and is responsible for synchronizing the engine’s state with the session’s state. This subsystem is shared with the client, and is responsible for loading client maps and connecting to servers as well as client side hosting.

Secondary Classes

The following classes are utilized by the primary classes for some elements of the bootstrapping process:

  • URH_SessionData and subclasses - These classes contain data about the session being run, and helpers to modify it and update it
  • URH_MatchSubsystem - This class is used to report match data to the RallyHere Match API
  • URH_RemoteFileSubsystem - This class is used to upload files to the RallyHere API for later retrieval
  • IRH_IpConnectionInterface - This interface class is used to add additional information to connection objects, such as the player’s RallyHere Player Uuid
  • URH_IntegrationSettings - This is the main class for storing settings in the integration, as well as loading them
  • URH_BootstrappingSettings - This legacy class contains some bootstrapping specific settings that have not yet been migrated to URH_IntegrationSettings. Right now this is limited to settings controlling the Finalizer helper.

Helper and Reference Classes

In addition to the above, the following classes are small helpers or reference classes that are used in the bootstrapping process:

  • FRH_SessionBootstrappingFinalizer - This class takes information retrieved about the allocation hosting request, and makes sure it is complete enough to actually begin hosting. It generates a FRH_BootstrappingResult upon completion, which is the final result of the bootstrapping process before the server invokes the URH_GameInstanceSessionSubsystem.
  • IRH_GameHostProviderInterface - This interface class is used by the bootstrapper to talk to the underlying hosting provider, and is used to pass through information on allocations, as well as inform the provider about the state of the server, such as the number of players connected.
    • FRH_GameHostProviderGHA - This is an implementation of the interface implementing the Game Host Adapter library. For more information on this library, see Game Host Adapter
    • FRH_GameHostProviderFallbackAutoCreate - This is a fallback implementation of the interface used when the FRH_GameHostProviderGHA implementation is not available. It only supports AutoCreate flows.
  • FRH_ServerLoginHelper - This class is used to log the server into the RallyHere API using a specified OSS.
  • URH_GameMode - This is an example gamemode base class, which can be used directly or as reference. It contains common edge case handling for things like auto-shutdown of servers with no players
  • URH_IpConnection - This is an example implementation of the IRH_IpConnectionInterface that can be used directly or as reference.
  • AnalyticsProvider - The engine configured analytics provider, generally assumed to be AnalyticsRallyHere

Bootstrapping Startup Flow

Flowchart

This flowchart is updated as of v16.0.0 of the RallyHere Unreal Integration SDK. Note that it omits failure cases, which are present at most steps, for simplicity.

Allocation Flow
AutoCreate Flow
Wait for Allocation (Idle)
Session Has No Instance
Session Has Instance
Initialize
Server Login
Recycle
Registration
Register (for Allocation)
Register (for AutoCreate)
Allocation Complete
Finalize Allocation
Create Session
Create Instance
SyncToSession
Session Synced (Gameplay Starts)
Bootstrap Complete

Begin State

The bootstrapping startup process begins shortly after the server is started as part of subsystem initialization.

End State

The bootstrapping startup process completes when a failure is encountered (in which case it immediately begins the Bootstrapping Shutdown Flow), or when the server has successfully begun hosting.

Bootstrapping Startup Flow Details

Initialize

This function is responsible for doing initial commandline parsing, and setting initial state. This also binds engine callbacks.

Once that is complete, it sets the bootstrap state to Unstarted, and begins the primary bootstrapping process by starting login.

Server Login

This step updates the bootstrapping state to LoggingIn. If the server is not already logged in, it will attempt to log in using the FRH_ServerLoginHelper class. Otherwise, it will continue immediately to the next step.

Recycle

This step begins a new server cycle loop. It updates the bootstrapping state to Recycling. This step both initializes the first loop after login, and restarts the loop after hosting is completed if the server is configured to allow internal (same process) recycling. It validates that the server is in a valid state to recycle, then begins the registration process.

Note that failures of checks in this case will cause asserts, as it means the server is in a bad state and may not be able to be gracefully shutdown.

Registration

This step begins the registration process. It updates the bootstrapping state to Registration.

It then creates several objects that are used in the current bootstrapping cycle. This includes creating the analytics provider and game host provider, and initializing them. Once that is complete, it connects to the provider.

At this point the bootstrapping flow splits based on the bootstrapping mode as detailed in Bootstrapping Modes. AutoCreate mode will use the reservation flow within the provider interface, and all other modes will use the registration flow to wait on an allocation.

Register (for Allocation)

This step invokes the game host provider to register that the server is ready for allocation, and then goes idle waiting on the allocation. Once an allocation is received, the next step is to finalize the allocation.

Reserve (for AutoCreate)

This step invokes the game host provider to create a self-hosting reservation. This is expected to be a quick operation, and upon completion will begin the next step.

Create Session (for AutoCreate)

This step invokes the RallyHere API to generate a session for the newly reserved allocation. The session created uses the type and region specified by the configuration for defaults (or overridden by commandline parameters -rh.sessiontype= and -rh.sessionregion=, respectively).

Once the session is successfully created, the next step is to finalize the allocation.

Finalize Allocation

This sub step finalizes the allocation retrieved either from the registration or reservation process. This step’s primary function is to take whatever the in-progress bootstrapping result is, and “finalize” or complete it, to ensure that it has all necessary data to begin hosting.

This is done via the finalizing helper class, FRH_SessionBootstrappingFinalizer.

Once the helper is complete and successful, it will update the bootstrapping stage to WaitingForSession. It then checks if an instance exists on the session, and then proceeds either into creating an instance, or directly to SyncToSession.

Create Instance

This sub step creates an instance on the session if one does not already exist. It will create an instance using the currently loaded map, and then proceed to SyncToSession.

SyncToSession

This step takes the fully complete bootstrapping result and session, updates the bootstrap stage to SyncingToSession, and passes the session object to the URH_GameInstanceSessionSubsystem class to begin changing the engine state to match the session state. Effectively, that causes the engine to load the map specified by the session, and enable it to be joinable.

This step also updates the hosting provider if using the AutoCreate/Reservation flow to inform it that the server is now transitioning into the allocated state.

Once the session sync process is complete, bootstrapping is complete.

Bootstrapping Failed

This is an end state that will immediately begin the Bootstrapping Shutdown Flow.

Bootstrapping Runtime Idle

The bootstrapping handler performs several checks while otherwise idle, both when waiting for an allocation and while allocated.

These include:

  • Checking for a soft stop request, and handling it if appropriate
  • Checking for session updates, and handling the results of them
  • Keeping the game host provider interface alive and healthy

Bootstrapping Shutdown Flow

Flowchart

This flowchart is updated as of v16.0.0 of the RallyHere Unreal Integration SDK.

Active Session
No Active Session
No Active Session
No Active Session
No Soft Stop Request AND Can Recycle
Soft Stop Request OR Cannot Recycle
Cannot refresh access token
Relogin Success
Relogin Failure
AllocationId Mismatch
SessionId Mismatch
InstanceId Mismatch
Else
Engine Code
HandleAppTerminatedGameThread
SyncToSession(nullptr)
Game Code
CleanupAfterInstanceRemoval
OnCleanupSessionSyncComplete
OnActiveSessionChanged
CleanupAfterSessionUnsynced
Soft Stop Request
Tick
Cleanup
ConditionalRecycle
Recycle
Shutdown
Auth Error
OnRefreshTokenExpired
Gameplay continues
CleanupAfterLogout
Session Deleted
OnSessionNotFound
Session Updated
OnSessionUpdated
Gameplay continues
RemoveSessionById

Begin State

The bootstrapping shutdown process begins in the following situations:

  • The Bootstrapping Runtime Idle ticks and determines that there is no active session, and a soft stop had previously been received from the game host provider interface.
  • A termination signal is received from the engine.
  • A termination signal is received from the game host provider interface.
  • Game Code attempts to remove the session from the bootstrapper.
  • Game Code attempts to synchronize the session subsystem to a different session than is being hosted (or the null session).
  • An unrecoverable authentication error is encountered.
  • The session is deleted from the RallyHere API.
  • The session is updated in the RallyHere API, but the update results in the session becoming invalid for hosting.

End State

The bootstrapping shutdown process has three possible end states:

  • The server is successfully shut down.
  • The server is recycled back to the Bootstrapping Startup Flow.
  • The server determines that gameplay should continue (such as in the case of a recoverable error).

Bootstrapping Shutdown Flow Details

Shutdown can be initiated from several starting points, which determine how the shutdown process is handled. The primary starting points are:

  • Engine Code: The engine code initiates a shutdown (ex: application exit)
  • Game Code: The game project code initiates a recycle (ex: gameplay is complete), and recycling is not possible
  • Auth Error: An authentication error is encountered that cannot be resolved
  • Session Deleted: The session is deleted from the RallyHere API
  • Session Updated: The session is updated in the RallyHere API, but the update results in the session becoming invalid for hosting
  • Soft Stop Request: The game host provider interface requests a soft stop. This can cause a deferred shutdown depending on the server state.

From each of the above starting points, the goal is to reach the Cleanup function, which is the final state before the server is shut down. The Cleanup state has a precondition of the game instance no longer hosting a session. Therefore, most paths will route through SyncToSession(nullptr) to ensure that the session is no longer being hosted. Several paths will also route through CleanupAfterInstanceRemoval to ensure that the session is properly cleaned up before being unsynced.

The Cleanup function cleans up all the bootstrapper state, and then attempts an internal recycle. If an internal recycle is not possible (due to either being out of recycle attempts, or a shutdown being requested), it will then finalize its state and shut down the server. If recycling is viable, it will restart the Bootstrapping Startup Flow at the Recycle point to begin the hosting process again.

Output Files

The bootstrapping process logs normally to the engine’s normal log file. However, in order to make that file retrievable from a remote machine, we allow enabling uploads to the FilesAPI via the URH_RemoteFileSubsystem. Support for uploading the default engine log and utrace files is included in the integration.

By default, server file auto-uploads are disabled, so that cloud storage space is not used unintentionally. To enable automated file uploads from the SDK, set the URH_IntegrationSettings property bAutoUploadServerFiles to true. There are some additional settings in that location to further control the upload process (which default to enabled, but depend upon bAutoUploadServerFiles being enabled).

Once enabled, files are uploaded to the Developer Files directory corresponding to a Match on the Files API. These can be retrieved via calling the API with the appropriate permissions, or by using the developer portal.

Note that the SDK supports overriding the setting value for bAutoUploadServerFiles via the commandline, by using -rh.noautouploadserverfiles or -rh.autouploadserverfiles to disable or enable uploads, respectively.