Skip to content

Federated game server

Game Server Federation allows you to integrate with Third-Party Game Server Orchestrators (such as Edgegap or Agones) as well as running arbitrary server-authoritative code before a "found match" notifies its players.

The interface you implement looks like this:

public async Promise<ServerInfo> CreateGameServer(Lobby lobby);

There are 3 calls that eventually invoke this function:

  • Matchmaking Match Found: The Beamable Backend will call the CreateGameServer function for each match produced by its matchmaking tick
  • Provision Game Server for Lobby: The Lobby's Host Player asks Beamable to provision a Game Server for their Lobby
  • Beam PIE's PIE Lobby: Made by Beam PIE's PIE Lobby setup. See the Real-Time Multiplayer Guides for more information

Configuring a game server federation to be called

Beamable's Backend uses a Content called UBeamGameTypeContent (game_types). A GameType represents a set of rules for how Beamable's Matchmaking should produce matches of this game type (including the Federation).

  1. Implement the IFederatedGameServer Federation in your microservice with a particular Federation Id.
  2. Set up that Federation Id in any UBeamGameTypeContent's federation field.
  3. Publish the Content.

The Create Game Server function is a blocking call with a long default timeout. This means Beamable's Backend waits on a response before notifying the users they were put into the lobby. However, implementing this correctly for all cases can be challenging; the SDK provides a few utilities:

public async Promise<ServerInfo> CreateGameServer(Api.Autogenerated.Models.Lobby lobby)
{
    var serverInfo = new ServerInfo();

    // Use this function to parallelize:
    //  - Creating the lobby in your Orchestrator;
    //  - Preparing your lobby's Global Data;
    //  - Preparing each player's PlayerData dictionaries.
    await lobby.PrepareLobbyAsDedicatedServer(serverInfo,

        // The first function is where you'll provision the game server.

        async l =>
        {
            var connInfo = new ServerInfo();

            // IF the lobby is NOT a PIE lobby from PIE/Playmode, you should be provisioning a server.
            // Lobbies created via BeamPIE are flagged as such so you can avoid asking your Orchestrator for a server.
            if (!l.IsLobbyFromEditorPlayMode())
            {
                // This means we actually need to provision a server and then set its connection information in the lobby.
                connInfo.SetConnectionString("my orchestrator's conn host", "my orchestrator's port");
            }

            return connInfo;
        },
        // This second function is where you should get your game-specific data and set it into the lobby's Global Data; which map players will be playing in, for example.
        l =>
        {
            return Task.FromResult(new ServerInfo());
        },
        // The last function runs ONCE PER LOBBY PLAYER --- here you'll usually be reading from stats, inventory and the lobby itself to validate and fill out what your game server and clients need.
        lp =>
        {
            return Task.FromResult(new Dictionary<string, string>());
        });

    // Because we want Clients to start connecting AFTER the Game Server is ready to accept them, we make this call.
    await lobby.WaitForGameServerReady(Provider.GetService<IBeamLobbyApi>());

    return serverInfo;
}

See the Beamball Demo for a working example of this CreateGameServer function.

Provision game server for custom lobby (non-matchmaking)

Certain games allow players to create custom lobbies manually. If those games also require invoking the federation endpoint to provision a server or run some arbitrary code, they can do so via the following steps:

  1. Create a Lobby with the UBeamGameTypeContent's id.
    1. Closed/Open lobbies both work with federation.
  2. Players will join the lobby and eventually become ready.
    1. Most custom lobby implementations use UBeamLobbySubsystem's UpdatePlayerTags function to update each individual player's ready state.
  3. Once all players are ready, the lobby host can invoke the UBeamLobbySubsystem's ProvisionGameServerForLobby function.
  4. This function requests that the configured Federation on the UBeamGameTypeContent be run.
  5. Once it does, it'll trigger UBeamLobbyState's OnLobbyUpdated callback for the lobby each particular player is in.
    1. You can then use Local State - Lobby - Open Level and, if you've set the connection information in the lobby's data (ULobby::Data), this node will connect and travel accordingly.

No sample covers this exact case, but the Beamball Demo demonstrates the relevant patterns.