Note
These examples will use theGameServerAllocation
resource for convenience, but these same patterns can be applied
when using the Allocation Service instead.This is the multi-page printable view of this section. Click here to print.
GameServer
starting, allocating and shutdown.GameServerAllocation
resource for convenience, but these same patterns can be applied
when using the Allocation Service instead.Fleets
using a GameServerAllocation
.GameServerAllocation
Since Code Blind will automatically add the label agones.dev/fleet
to a GameServer
of a given Fleet
, we can use that
label selector to target a specific Fleet
by name. In this instance, we are targeting the Fleet
xonotic
.
apiVersion: "allocation.agones.dev/v1"
kind: GameServerAllocation
spec:
required:
matchLabels:
agones.dev/fleet: xonotic
GameServerAllocation
.GameServer
players are sent to.In this scenario, the GameServer
process will need to self Allocate when informed by the matchmaker that players
are being sent to them.
GameServers
are packed across the cluster to the external matchmaker. It is likely
it will not do as good a job at packing and scaling as Code Blind.GameServer
to ensure it works correctly, before rolling it out to all your players.To canary release/test a new Fleet
,
we can run a small, fixed size Fleet
of the new version of our GameServer, while also running the current stable
production version.
Allocations
can then prefer
to come from the canary Fleet
, but if all GameServers
are already allocated from the
canary Fleet
, players will be allocated to the current stable Fleets.
Over time, if the monitoring of those playing on the canary Fleet
is working as expected, the size of the canary
Fleet
can be grown until you feel confident in its stability.
Once confidence has been achieved, the configuration for stable Fleet
can be updated to match the canary (usually
triggering a rolling update). The
canary Fleet
can then be deleted or updated to a new testing version of the game server process.
GameServerAllocation
To ensure we don’t have to change the Allocation system every time we have a canary Fleet
, in this example, we will
state that in our system, the label canary: "true"
will be added to any canary Fleet
in the cluster.
apiVersion: "allocation.agones.dev/v1"
kind: GameServerAllocation
spec:
preferred:
- matchLabels:
canary: "true"
required:
matchLabels:
agones.dev/fleet: stable
The above Allocation
will then preferentially choose the Fleet
that has GameServers
with the label and key
value ofcanary:"true"
, if it exists, and has remaining Ready GameServers
, and if not, will apply the
Allocation
to the Fleet
named “stable”.
Fleet
update options and strategies that are
available.GameServerAllocation
.Fleet
reference.GameServer
has completed a player session, return it back to the pool of Ready GameServers
for reuse.Having a GameServer
terminate after a single player session is better for packing and optimisation of
infrastructure usage, as well as safety to ensure the process returns to an absolute zero state.
However, depending on the GameServer
startup time, or other factors there may be reasons you wish to reuse a
GameServer
for n number of sessions before finally shutting it down.
The “magic trick” to this is knowing that the GameServer
process can call
SDK.Ready()
to return to a Ready
state after the GameServer
has been allocated.
It is then up to the game developer to ensure that the game server process returns to a zero state once a game session has been completed.
Depending on the setup and resource requirements of your game server process, sometimes it can be a more economical
use of resources to run multiple concurrent game sessions from within a single GameServer
instance.
The tradeoff here is that this requires more management on behalf of the integrated game server process and external systems, since it works around the common Kubernetes and/or Code Blind container lifecycle.
Utilising the new allocation gameServerState
filter as well as the existing ability to edit the
GameServer
labels at both allocation time, and from
within the game server process, via the SDK,
means Code Blind is able to atomically remove a GameServer
from the list of potentially allocatable
GameServers
at allocation time, and then return it back into the pool of allocatable GameServers
if and when the
game server process deems that is has room to host another game session.
GameServer.status.state
change from Ready
to Allocated
,
but it is also useful to know that the value of GameServer.metadata.annotations["agones.dev/last-allocated"]
will
change as it is set by Code Blind with each allocation with the current timestamp, regardless of if there
is a state change or not.GameServerAllocation
The below Allocation
will first attempt to find a GameServer
from the Fleet
simple-udp
that is already
Allocated and also has the label agones.dev/sdk-gs-session-ready
with the value of true
.
The above condition indicates that the matching game server process behind the matched GameServer
record is able to
accept another game session at this time.
If an Allocated GameServer
does not exist with the desired labels, then use the next selector to allocate a Ready
GameServer
from the simple-udp
Fleet
.
Whichever condition is met, once allocation is made against a GameServer
, its label of agones.dev/sdk-gs-session-ready
will be set to the value of false
and it will no longer match the first selector, thereby removing it from any
future allocations with the below schema.
It will then be up to the game server process to decide on if and when it is appropriate to set the
agones.dev/sdk-gs-session-ready
value back to true
, thereby indicating that it can accept another concurrent
gameplay session.
apiVersion: "allocation.agones.dev/v1"
kind: GameServerAllocation
spec:
selectors:
- matchLabels:
agones.dev/fleet: simple-udp
agones.dev/sdk-gs-session-ready: "true" # this is important
gameServerState: Allocated # new state filter: allocate from Allocated servers
- matchLabels:
agones.dev/fleet: simple-udp
gameServerState: Ready # Allocate out of the Ready Pool (which would be default, so backward compatible)
metadata:
labels:
agones.dev/sdk-gs-session-ready: "false" # this removes it from the pool
GameServer
process use to add itself back into the pool of
allocatable instances, must start with the prefix agones.dev/sdk-
, since only labels that have this prefix are
available to be [updated from the SDK][sdk].Code Blind, and Kubernetes itself are built as eventually consistent, self-healing systems. To that end, it is worth
noting that there may be minor delays between each of the operations in the above flow. For example, depending on the
cluster load, it may take up to a second for an SDK driven label change on a GameServer
record to be
visible to the Code Blind allocation system. We recommend building your integrations with Code Blind with this in mind.
GameServer
.GameServerAllocation
.GameServer
that has room for a specific number of players.The Player Tracking and Allocation Player Filter features are currently Alpha, not enabled by default, and may change in the future.
Use the FeatureGates PlayerTracking
, and PlayerAllocationFilter
to enable and test these features.
See the Feature Gate documentation for details on how to enable features.
Using this approach, we are able to be able to make a request that is akin to: “Find me a GameServer
that is already
allocated, with room for n number of players, and if one is not available, allocate me a Ready
GameServer
”.
Common applications of this type of allocation are Lobby servers where players await matchmaking, or a persistent world server where players connect and disconnect from a large map.
GameServerAllocation
The below allocation will attempt to find an already Allocated GameServer
from the Fleet
“lobby” with room for 10
to 15 players, and if it cannot find one, will allocate a Ready one from the same Fleet
.
apiVersion: "allocation.agones.dev/v1"
kind: GameServerAllocation
spec:
selectors:
- matchLabels:
agones.dev/fleet: lobby
gameServerState: Allocated
players:
minAvailable: 10
maxAvailable: 15
- matchLabels:
agones.dev/fleet: lobby
GameServer
that there is the expected player capacity
on the GameServer
as there can be a small delay between a player connecting and it being reported
to Code Blind.GameServerAllocation
.