Unreal Sessions Integration
The session systems within the integration is one of its most complex systems, as it touches many aspects of game flow. It involves coordination between players, the engine, native platforms, and potentially a server. For this reason, it is broken into several parts, all of which are responsible for different aspects of managing sessions.
The major pieces of the system are:
- RH_LocalPlayerSessionSubsystem - responsible for managing the local player’s sessions. It will poll session templates, check for sessions, you are part of, retrieve them, and maintain their state
- RH_GameInstanceServerBootStrapper - for dedicated servers, this is responsible for bootstrapping the server and managing the server’s session, whether by creating its own or retrieving an existing session.
- RH_GameInstanceSessionSubsystem - responsible for syncing the state from a session object (usually provided by one of the two above systems) with the engine’s gameplay flow. This includes loading maps, establishing connections, and handling errors from the engine
- RH_SessionOwnerInterface - an interface (implemented by RH_LocalPlayerSessionSubsystem and RH_GameInstanceServerBootStrapper) that provides a general interface for sessions to work with their owning entities.
These systems all refer to session objects, which derive from RH_SessionView. The various subclasses provide increasing levels of functionality, mostly determined by the local membership level within the session. The current hierachy is as follows:
- RH_SessionView - the base class, which holds session data and provides accessors for reading it. This class is effecively read only, does not imply any membership, and is suitable for caching (such as with session browser searches)
- RH_InvitedSession - a session (with a session owner), to which the owner has been invited (which assumes the invite came from the RallyHere API). Provides limited functionality, primarily to leave (decline the invite) and join (accept the invite)
- RH_JoinedSession - a session (with a session owner), to which the owner is a member. Provides functionality to modify the state of the session
- RH_OnlineSession - a joined session that is synchronized with the RallyHere API. It provides additional functionaliy, such as polling for updates, as well as some utility functions.
- RH_OfflineSession - a joined session that is local to the game instance. It is not synchronized in any way with the server, but provides limited functionality to modifiy itself. It is intended for utilizing the session flow in cases where the API is not required, such as offline tutorials.
Additionally, there is a final major object, currently under development, RH_PlatformSessionSyncer. It works in conjunction with the sessions in RH_LocalPlayerSessionSubsystem to synchronize session state with a platform (such as Xbox, Steam, or PSN) by utilizing the engine’s OnlineSessionInterface and related systems.
Local Player Session Subsystem
The local player session subsystem’s primary job is to poll for session updates, and dispatch them. It maintains a map of session objects for which the player is invited or is a member, and is responsible for managing those objects.
Session polling is done via a configured polling rate. When a new session is detected, it will instantiate the appropriate session type and initialize it, then fire multicast callbacks in case any objects are listening for session changes. It will also create RH_PlatformSessionSyncer objects if sessions are configured to use them.
Game Instance Server Bootstrapper
The bootstrapper is responsible for bootstrapping dedicated servers so that they work for hosting sessions. It is responsible for logging into the API, finding a session, passing that session to the Game Instance Session Subsystem, and monitoring that session. Once a session is done, it has the ability to internally recycle and host new sessions.
It generally runs in one of a few modes, determined by the
-rhboostrapmode= command line argument. However, those two modes fall primarily into one of two categories:
AutoCreate and allocated modes. This is primarily managed by the Game Host Adapter library, which is responsible for ensuring that the bootstrapping flow works with any given hosting provider.
AutoCreate mode, the bootstrapper will create a brand new session (of SessionType specified by
-rhsessiontype=), and host it.
The other modes use the Allocated Session flow. Generally, they will register with the Game Host Adapter library, and wait for an allocation (such as a Session requesting a dedicated server). Once an allocation is retrieved, they will look up the relevant session, bind to it, and host the session.
Hosting the session is done by using the Game Instance Session Subsystem, and generally follows the same flow as a Peer to Peer hosted session from there.
Game Instance Session Subsystem
The Game Instance Session Subsystem is responsible for synchronizing the state of a session with the state of the engine, in regards to gameplay. The main kickoff function for this logic is called SyncToSession, and takes an input session. Once called, the subsystem will begin the processing of synchronizing to that session, including leaving any old session. It will also do checks to make sure the session is in a good state to join.
In the case of a session being locally hosted (a Peer to Peer host, or a dedicated server), the system is also responsible for updating the Session state to mark it as Joinable - until this happens clients are not allowed to join, and in the case of matchmaking the matchmaking is not considered complete until this is completed.
One major caveat for the system is that ALL local players much have the matching system in their Local Player Session Subsystem, or else it will reject the join. This is to ensure that state is sychronized across all players and that they all have permission to join before transitioning, as the engine can only connect to one host at a time.
Basic Usage (using the debug tool)
The Debug Tool has a window specifically for Sessions, and most operations involving sessions can be performed in it. This section will focus on using the debug tool, but note that it is mostly calling top level functions on the various classes mentioned above, and can be used as an example of how those calls can be made.
Creating a Session
Creating a joining a session in the debug tool is primarily handled at the top of the first tab. To create a session in the debug tool, you must first specify a session type. These types are retrieved from the Local Player Session Subsystem and provided in a dropdown. The types are configured as part of your sandbox configuration.
Once the type is selected, you may want to also specify a region. A list of regions can be found via searching on the region tab.
After selecting your SessionType and Region, click the Create Session button. You should see a new session of the specified type in the list below if creation was successful.
NOTE - In the case of a SessionType configured with the Hub join rule, a session may be joined instead of created. This is because the Hub join rule will attempt to join an existing session if one exists and has space, and only create a new one if none exists.
Joining a Session
There are several ways to join a session. The most basic is a direct Join By ID, for which functionality is provided at the top of the window with a specified ID. However, this only works for sessions that are publicly joinable.
Other methods of joining a session involve being invited, matchmaking, the session browser, or session hubs. Most of these are detailed below.
Inviting Players to a Session
Players can be invited to a session by Player UUID, by expanding a Session’s Player’s list. Note that players are organized into Teams within a session. Sessions that do not need this functionality (such as a “party” style session) should just put all players on Team 0.
A session can be queued into matchmaking by expanding the Session’s matchmaking tab and providing a Queue Id. Alternatively, the Queues tab can be used to search for a queue to join (make sure to select the session to join with at the top of the tab). Once matchmaking is complete, players will be invited to a new session that is the result of matchmaking (the original session is not modified, except in the case of Backfilling, TBD).
The Browser tab provides a method for searching for sessions that have listed themselves on the browser. While some SessionTypes can be configured to be automatically listed, the UpdateBrowserInfo call on a RH_JoinedSession can be used to control the browser listing.
SessionTypes can be configured to use Hub functionality, which is suitable for many things, but especially an “Open World” type area. Players who attempt to create a Hub type session will instead be joined into an existing session if one is suitable, else a new session will be created.
Note that Hub functionality only overrides the Create Session logic, they can also be joiend via the other join methods as needed.
Leaving a Session
To leave a Session, expand its section and click the Leave button at the top.
While SessionTypes can be configured to auto-launch an instance, instances can be manually controlled as well. The debug tool provides a method to request both player hosted instances as well as dedicated server instances (via the Server Allocation flow). The debug tool has a section for a map and mode to be provided (plus a checkbox for beacons). You can configure a default map and mode for the debug tool in the Debug Tool Settings section of the Engine’s Project Settings pages.
Once an instance is requested, the instance section should fill in. Instances can have multiple states. To join an instance, click the Activate button (and Deactivate to leave it). This will sync the session into the Game Instance Session Subsystem.
Note that normal joining rules apply. Activation can fail in many cases, such as:
- You are not the host, and the instance is not in the joinable state
- Not all local players are part of the session
- You are the host, but could not load the proper map
An instance can be ended via the End Instance button. This will end the instance, allowing a new one to be requested. In the case of a dedicated server, it will detect that the instance was ended and attempt to recycle itself.
Beacons are a concept in Unreal Engine documented here. They are a lightweight connection to a server, which allows for some interesting functionality when you do not need a full connection (such as the ability to run utility scripts in a protected environment). Because they are much lighter weight, they can generally serve a much larger number of players.
Some suppport for beacons is provided by the session system. By selecting the Beacon option when requesting a dedicated server, the server will launch in Beacon mode. Normal attempts to join the server will fail, but beacon connections will succeed. When a beacon server is intiialized, the Game Instance Session Subsystem will broadcast it, so that Online Beacon Host Objects (which handle beacon functionality server side) can be created and registered.
By default (though disablable), a test becaon host object (RH_TestBeaconHostObject) will be created and initialized. The debug tool has the ability to connect to this type and do a simple ping test, to ensure connectivity.