Fleet Service Migration Guide #
Pragma Engine version 0.0.97 introduces the Fleet service, a service for processing game instance requests and coordinating with third-party game server management providers to allocate game servers. The Fleet service is intended to eventually replace the existing Match Capacity service, although both services are currently available.
This guide is intended to help current Match Capacity users migrate to using the Fleet service. For detailed information about the Fleet service, see the Fleet service documentation.
Fleet service introduction #
The new Fleet service allows users to better manage their fleet of game servers. Through the introduction of server pools, the Fleet service allows you to manage homogenous groups of servers for different contexts. The Fleet service automatically manages game server capacity by server pool, based on defined management policies. With these features you no longer have to manually track capacity.
Overview of Tasks #
- Update class references
- Update configuration values
- Migrate MatchCapacityConfig to ServerPoolManagementPolicy
- Migrate LocalProcessCapacityProvider to LocalProcessFleetPlugin
- Migrate PragmaNomadCapacityProvider to NomadFleetPlugin
- Implement Fleet Plugin Methods
- Migrate CapacityProvider.add capabilities to to FleetPlugin.add
- Implement selectServerPool and getServerPoolById
- Update SDK calls
Update class references #
Change classes that extend MatchCapacityProvider
to instead extend FleetPlugin
, updating the interface appropriately (see Implement the Fleet Plugin Methods).
Update configuration values #
To take advantage of the Fleet service features, such as server pools and server pool management policies, add/update configuration blocks and values in your YAML configuration file.
Migrate MatchCapacityConfig values to ServerPoolManagementPolicies #
The Fleet service allows you to define various server pool management policies that you can apply to one or more server pools (groups of game servers). To take advantage of this capability, migrate the data in the MatchCapacityServiceConfig
matchCapacityConfig
configuration block to a serverPoolManagementPolicies
block in the FleetServiceConfig
section, giving it an id of defaultPoolManagementPolicy
:
Before: Sample MatchCapacityServiceConfig
configuration data
MatchCapacityServiceConfig:
matchCapacityConfig:
floor: 0
ceiling: 10
headroomPercent: 0
serverMaxStartDurationMillis: 120000
serverHeartbeatPeriodMillis: 1000
serverHeartbeatExpiryFactor: 5.0
gameCapacityResolvedTimeoutMillis: 30000
After: Sample FleetServiceConfig
configuration data after migrating and configuring a default server pool management policy
game:
serviceConfigs:
FleetServiceConfig:
serverPoolManagementPolicies:
1:
id: "defaultPoolManagementPolicy"
gameCapacityPerServer: 1
capacityFloor: 0
capacityCeiling: 10
capacityBuffer: 40
serverMaxStartDurationMillis: 120000
serverHeartbeatPeriodMillis: 1000
serverHeartbeatExpiryFactor: 5.0
gameCapacityResolvedTimeoutMillis: 30000
Note the following values were updated/added:
Old | New | Description |
---|---|---|
N/A | id | Unique identifier for the server pool management policy |
N/A | gameCapacityPerServer | Number of game instances this server can host at a given time |
floor | capacityFloor | Minimum game capacity allocated at all times |
ceiling | capacityCeiling | Maximum game capacity allocated at all times |
headroomPercent | capacityBuffer | Preferred available game capacity defined as a percentage of used game capacity |
Migrate LocalProcessCapacityProvider configuration values to LocalProcessFleetPlugin #
If currently using the LocalProcessCapacityProvider
, move the configuration values in the matchcapacity.LocalProcessCapacityProvider
class to the fleet.LocalProcessFleetPlugin
class, as shown in the following example:
In addition, the Fleet service includes three updated/new configuration values:
Old | New | Description |
---|---|---|
serverIdParam: -serverId= | serverIdParam: -gameServerId= | Game server ID |
gameServerZoneParam: -gameServerZone= | Removed | N/A |
N/A | serverPoolIdParam: -serverPoolId= | Server pool ID for the server |
N/A | serverPoolConfigs: | Config blocks for various server pools, including values such as server pool ID, associated management policy, and game server versions |
Before: Sample LocalProcessCapacityProvider
configuration
MatchCapacityService.capacityProvider:
class: "pragma.matchcapacity.LocalProcessCapacityProvider"
config:
processCommand:
0: "path/to/your/built/unity/Server.exe"
1: -pragmaBackendAddress="http://127.0.0.1:10100"
2: -hostname="127.0.0.1"
3: -port=9999
4: -version="GameServerVersion1"
# 5: -pragmaServerNoExit
serverIdParam: -serverId=
gameServerZoneParam: -gameServerZone=
logPathParam: ""
logOutputPath: ""
maximumLocalServers: 1
After: Sample LocalProcessFleetPlugin
configuration
FleetService.fleetPlugin:
class: "pragma.fleet.LocalProcessFleetPlugin"
config:
processCommand:
0: "path/to/your/built/unity/Server.exe"
1: -pragmaBackendAddress="http://127.0.0.1:10100"
2: -hostname="127.0.0.1"
3: -port=9999
4: -version="GameServerVersion1"
# 5: -pragmaServerNoExit
serverIdParam: -gameServerId=
serverPoolIdParam: -serverPoolId=
logPathParam: "" # these don't do anything in unity
logOutputPath: "" # these don't do anything in unity
maximumLocalServers: 1
serverPoolConfigs:
0:
serverPoolId: "LocalServerPool"
managementPolicyConfigId: "LocalDevelopment"
gameServerVersions:
0: "myLocalServerVersion"
TheLocalProcessFleetPlugin
allows for configuring multiple server pools and will use the game server version to decide which server pool to return whenselectServerPool
is called. This means that a single game server version should not appear on more than onegameServerVersions
list.
Migrate PragmaNomadCapacityProvider configuration values to NomadFleetPlugin #
If currently using the PragmaNomadCapacityProvider
, move the configuration values in the matchcapacity.PragmaNomadCapacityProvider
class to the fleet.NomadFleetPlugin
class, as shown in the following example.
Before: Sample PragmaNomadCapacityProvided
configuration
MatchCapacityService.capacityProvider:
class: "pragma.matchcapacity.PragmaNomadCapacityProvider"
config:
url: "https://nomad.playtest.internal.arbiter.arbiterstudios.pragmaengine.com"
jobDatacenter: "us-west-2"
executableName: "ServerLinux"
capacityPerServer: 64
args:
0: -pragmaBackendAddress="https://playtest.arbiter.arbiterstudios.pragmaengine.com:10100"
1: -server
2: -pragmaDebug=0
3: -gameServerZone="UsWest"
4: -batchmode
5: -nographics
After: Sample NomadFleetPlugin
configuration
FleetService.fleetPlugin:
class: "pragma.fleet.NomadFleetPlugin"
config:
url: "https://nomad.playtest.internal.arbiter.arbiterstudios.pragmaengine.com"
jobDatacenter: "us-west-2"
executableName: "ServerLinux"
capacityPerServer: 64
args:
0: -pragmaBackendAddress="https://playtest.arbiter.arbiterstudios.pragmaengine.com:10100"
1: -server
2: -pragmaDebug=0
3: -gameServerZone="UsWest"
4: -batchmode
5: -nographics
Migrate MultiplayCapacityProvider to MultiplayFleetPlugin #
If currently using the MultiplayCapacityProvider
(for environments using Unity Game Server Hosting Multiplay), move the configuration values in the matchcapacity.MultiplayCapacityProvider
class to the fleet.MultiplayFleetPlugin
class, as shown in the following example.
The serverPoolId
, profileId
, and regionId
configured in each ServerPoolConfig
block should be unique to that server pool so that the plugin can map Multiplay region IDs to a unique Multiplay profile ID when allocating game servers. This allows for configuring your Multiplay profile IDs per region.
Before: Sample MultiplayCapacityProvider
configuration
MatchCapacityService.capacityProvider:
class: "pragma.matchcapacity.MultiplayCapacityProvider"
config:
capacityPerServer: 1
regionId: "2222a2a2-a22a-22a2-a2a2-2a222aa22222"
fleetId: "1111a1a1-a11a-11a1-a1a1-1a111aa11111"
projectGuid: "1111b1b1-b11b-11b1-b1b1-1b111bb11111"
profileId: "1234567"
accessKey: "YOUR_ACCESS_KEY"
secretAccessKey: "YOUR_SECRET_ACCESS_KEY_THAT_HAS_BEEN_ENCRYPTED_BY_PRAGMA"
useAllocateV2: true
pragmaGamePartnerBackendAddress: "http://somehost.net:10100"
gameServerZoneToMultiplayRegionId:
UsWest: "1111a1a1-a11a-11a1-a1a1-1a111aa11111"
UsEast: "2222a2a2-a22a-22a2-a2a2-2a222aa22222"
Europe: "3333a3a3-a33a-33a3-a3a3-3a333aa33333"
Korea: "4444a4a4-a44a-44a4-a4a4-4a444aa44444"
After: Sample MultiplayFleetPlugin configuration
FleetService.fleetPlugin:
class: "pragma.fleet.MultiplayFleetPlugin"
config:
capacityPerServer: 1
fleetId: "1111a1a1-a11a-11a1-a1a1-1a111aa11111"
projectGuid: "1111b1b1-b11b-11b1-b1b1-1b111bb11111"
accessKey: "YOUR_ACCESS_KEY"
secretAccessKey: "YOUR_SECRET_ACCESS_KEY_THAT_HAS_BEEN_ENCRYPTED_BY_PRAGMA"
useAllocateV2: true
pragmaGamePartnerBackendAddress: "http://somehost.net:10100"
gameServerZoneToMultiplayRegionId:
UsWest: "1111a1a1-a11a-11a1-a1a1-1a111aa11111"
UsEast: "2222a2a2-a22a-22a2-a2a2-2a222aa22222"
Europe: "3333a3a3-a33a-33a3-a3a3-3a333aa33333"
Korea: "4444a4a4-a44a-44a4-a4a4-4a444aa44444"
serverPoolConfigs:
0:
serverPoolId: "3v3_UsWest"
managementPolicyConfigId: "3v3_LowPop"
profileId: "1234567" # First Profile Id
regionId: "1111a1a1-a11a-11a1-a1a1-1a111aa1111" # UsWest
1:
serverPoolId: "3v3_UsEast"
managementPolicyConfigId: "3v3_HighPop"
profileId: "7654321" # Second Profile Id
regionId: "2222a2a2-a22a-22a2-a2a2-2a222aa22222" # UsEast
The MultiplayFleetPlugin will no longer send thegameServerZone
, but instead send thepragmaBackendAddress
andserverPoolId
values in theAllocateV2
request body payload. Provide theserverPoolId
value to theMatchApi.StartReportCapacityPolling
method to ensure Pragma can properly track the allocated server.
Implement the Game Instance Host Plugin Method #
The new Game Instance Host Plugin contains the findHostForGameInstance
method, which populates the ExtHostRequest
. The ExtHostRequest
is used in the Fleet service to determine which server pool to assign for the game instance.
fun findHostForGameInstance(
gameInstance: GameInstance,
): ExtHostRequest?
If you choose to not use Pragma’s Fleet service and instead want to manage your fleet outside of Pragma, return null. Use this method to integrate with your game server provider in order to allocate a game server for this game instance.
Implement the Fleet plugin methods #
The new Fleet Plugin contains the add method formerly handled by the Capacity Provider, as well as new selectServerPool
and getServerPoolById
methods.
Migrate CapacityProvider.add capabilities to to FleetPlugin.add #
If the Fleet service determines that the current available capacity cannot fulfill a request to create a game instance in a given server pool, the Fleet Plugin’s add()
method is called to generate additional capacity onto the service.
The new Fleet Plugin add()
method simplifies the Capacity Provider’s add process in the following ways:
- You no longer need to calculate the number of game servers to spin up or to create server IDs. The
add()
method is provided with a list of Pragma-generated server IDs (allocation: List <UUID>
) that you can use to spin up game servers (one game server for each game server ID in the allocations list). - You can use the
serverPool
object, which includes the server pool ID, the management policy ID, and theExtServerPool
payload, to specific game servers according to values.
Move custom functionality from your CapacityProvider.add
implementation to your FleetPlugin.add
implementation:
Before: Sample CapacityProvider add method implementation
override suspend fun add(
gameVersion: String,
gameServerZone: String,
extraMatchCapacity: Int,
capacityTracker: CapacityTracker
) {
val partnerGameAuthToken = tokenSignerNodeService.createPartnerGameToken(
service.pragmaNode.pragmaConfig.core.shardId
)
val partnerSocialAuthToken = tokenSignerNodeService.createPartnerSocialToken()
val requiredServerCount = calculatServerCount(
extraMatchCapacity,
config.capacityPerServer
)
repeat(requiredServerCount) {
val serverId = capacityTracker.addNewServer(
gameVersion,
gameServerZone,
config.capacityPerServer
)
val configArgs = config.args.entries
.sortedBy { it.key }
.map { it.value }
.toMutableList()
val dispatchRequest = mapOf(
META to mapOf(
ARGS to configArgs,
EXECUTABLE_NAME to config.executableName,
PARTNER_GAME_AUTH_TOKEN to partnerGameAuthToken,
PARTNER_SOCIAL_AUTH_TOKEN to partnerSocialAuthToken,
SERVER_ID to serverId,
VERSION to gameVersion,
)
)
dispatchRequestToGameServerProvider(
dispatchRequest,
serverId,
capacityTracker
)
}
}
After: Sample FleetPlugin add method implementation
override suspend fun add(serverPool: ServerPool, allocations: List<UUID>) {
val partnerGameAuthToken = tokenSignerNodeService.createPartnerGameToken(
service.pragmaNode.pragmaConfig.core.shardId
)
val partnerSocialAuthToken = tokenSignerNodeService.createPartnerSocialToken()
allocations.forEach { serverId ->
val configArgs = config.args.entries
.sortedBy { it.key }
.map { it.value }
.toMutableList()
val dispatchRequest = mapOf(
META to mapOf(
ARGS to configArgs,
EXECUTABLE_NAME to config.executableName,
PARTNER_GAME_AUTH_TOKEN to partnerGameAuthToken,
PARTNER_SOCIAL_AUTH_TOKEN to partnerSocialAuthToken,
SERVER_ID to serverId,
SERVER_POOL_ID to serverPool.serverPoolId,
)
)
dispatchRequestToGameServerProvider(dispatchRequest)
}
}
Implement selectServerPool and getServerPoolById #
The new Fleet Plugin selectServerPool()
method determines what server pool a given game instance should be associated with, ensuring the game instance finds an appropriate game server to run on. See our documentation for instructions on customizing the selectServerPool
method.
The Fleet Plugin getSeverPoolById()
method determines what server pool should be used when given a ServerPool.serverPoolId
. This is used as a fallback if your game server reports a server id that is unrecognized by Pragma. This situation can occur when you are using a local game server not allocated using the Fleet service.
The Fleet service executes this when Pragma is unable to reconcile a server pool for a game server that is reporting capacity.
If your plugin needs to access thegameServerVersion
andgameServerZone
in theadd()
method, be sure to include it on theExtServerPool
returned fromselectServerPool
.
Update SDK calls #
Ensure you are calling the correct StartReportCapacityPolling
SDK method, which contains the following parameters:
ServerId
- ID for the server that should start reporting its capacity. This value will be provided by the Fleet Plugin add function, and should be passed to the game server provider as it spins up the server.ServerPoolId
- Server Pool ID for the server that should start reporting its capacity. This value will be provided by the Fleet Plugin add function, and should be passed to the game server provider as it spins up the server.Timeout
- Defines how long to wait for the first game allocation to the game server. If you do not want to use the timeout, provide a value of0
for thetimeout
parameter.MaxGameInstanceCount
- Number of game instances that can run on this server. This value should match your configuredgameCapacityPerServer
. Default is 1.