diff --git a/examples/gameserver.yaml b/examples/gameserver.yaml index 26595c2324..8a90fa1eb7 100644 --- a/examples/gameserver.yaml +++ b/examples/gameserver.yaml @@ -76,6 +76,13 @@ spec: # conflict with other TCP connections. grpcPort: 9357 httpPort: 9358 + # [Stage:Alpha] + # [FeatureFlag:PlayerTracking] + # Players provides the configuration for player tracking features. + # Commented out since Alpha, and disabled by default + # players: + # # set this GameServer's initial player capacity + # initialCapacity: 10 # Pod template configuration # https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#podtemplate-v1-core template: diff --git a/pkg/apis/agones/v1/gameserver.go b/pkg/apis/agones/v1/gameserver.go index 8cfb5a96d1..af70e1282a 100644 --- a/pkg/apis/agones/v1/gameserver.go +++ b/pkg/apis/agones/v1/gameserver.go @@ -156,8 +156,7 @@ type GameServerSpec struct { Players *PlayersSpec `json:"players,omitempty"` } -// PlayersSpec tracks the initial player capacity, and what webhooks to send events to when there are -// connection/disconnection events. +// PlayersSpec tracks the initial player capacity type PlayersSpec struct { InitialCapacity int64 `json:"initialCapacity,omitempty"` } diff --git a/site/content/en/docs/Guides/feature-stages.md b/site/content/en/docs/Guides/feature-stages.md index 539a2f7124..0cb0aa9188 100644 --- a/site/content/en/docs/Guides/feature-stages.md +++ b/site/content/en/docs/Guides/feature-stages.md @@ -24,11 +24,22 @@ that can be found in the [Helm configuration]({{< ref "/docs/Installation/Instal The current set of `alpha` and `beta` feature gates are: +{{% feature expiryVersion="1.5.0" %}} | Feature Name | Gate | Default | Stage | Since | |--------------|---------|---------|-------|-------| | Multicluster Allocation* | N/A | Enabled | `Alpha` | 0.11.0 | | Example Gate (not in use) | `Example` | Disabled | None | 0.13.0 | | [Port Allocations to Multiple Containers]({{< ref "/docs/Reference/gameserver.md" >}}) | `ContainerPortAllocation` | Disabled | `Alpha` | 1.5.0 | +{{% /feature %}} + +{{% feature publishVersion="1.6.0" %}} +| Feature Name | Gate | Default | Stage | Since | +|--------------|---------|---------|-------|-------| +| Multicluster Allocation* | N/A | Enabled | `Alpha` | 0.11.0 | +| Example Gate (not in use) | `Example` | Disabled | None | 0.13.0 | +| [Port Allocations to Multiple Containers]({{< ref "/docs/Reference/gameserver.md" >}}) | `ContainerPortAllocation` | Disabled | `Alpha` | 1.5.0 | +| [Player Tracking]({{< ref "/docs/Guides/player-tracking.md" >}}) | `PlayerTracking` | Disabled | `Alpha` | 1.6.0 | +{{% /feature %}} *Multicluster Allocation was started before this process was in place, and therefore is enabled by default, and will not have a feature flag. diff --git a/site/content/en/docs/Guides/player-tracking.md b/site/content/en/docs/Guides/player-tracking.md new file mode 100644 index 0000000000..43a863b050 --- /dev/null +++ b/site/content/en/docs/Guides/player-tracking.md @@ -0,0 +1,126 @@ +--- +title: "Player Tracking" +linkTitle: "Player Tracking" +date: 2020-05-19 +weight: 30 +description: > + Track player connections, disconnections, counts and capacities through the Agones SDK +--- + +{{< alpha title="Player Tracking" gate="PlayerTracking" >}} + +## Managing GameServer Capacities + +To track your `GameServer` current player capacity, Agones gives you the ability to both set an initial capacity at +`GameServer` creation, as well be able to change it during the lifecycle of the `GameServer` through the Agones SDK. + +To set the initial capacity, you can do so via `GameServer.Spec.Players.InitialCapacity` like so: + +```yaml +apiVersion: "agones.dev/v1" +kind: GameServer +metadata: + name: "gs-example" +spec: + # ... + players: + # set this GameServer's initial player capacity to 10 + initialCapacity: 10 +``` + +From there, if you need to change the capacity of the GameSever as gameplay is in progress, you can also do so via +[`SDK.Alpha().SetPlayerCapacity(count)`]({{< ref "/docs/Guides/Client SDKs/_index.md#alpha-setplayercapacity-count" >}}) + +The current player capacity is represented in `GameServer.Status.Players.Capacity` resource value. + +We can see this in action, when we look at the Status section of a GameServer resource +, wherein the capacity has been set to 20: + +``` +... +Status: + Address: 14.81.195.72 + Node Name: gke-test-cluster-default-6cd0ba67-1mps + Players: + Capacity: 20 + Count: 0 + Ids: + Ports: + Name: gameport + Port: 7983 + Reserved Until: + State: Ready +``` + +From the SDK, the game server binary can also retrieve the current player capacity +via [`SDK.Alpha().GetPlayerCapacity()`]({{< ref "/docs/Guides/Client SDKs/_index.md#alpha-getplayercapacity" >}}). + +{{% alert title="Note" color="info" %}} +Changing the capacity value here has no impact on players actually +connected to or trying to connect to your server, as that is not a responsibility of Agones. + +This functionality is for tracking purposes only. +{{% /alert %}} + +## Connecting and Disconnecting Players + +As players connect and disconnect from your game, the Player Tracking functions enable you to track which players +are currently connected. + +It assumed that each player that connects has a unique token that identifies them as a player. + +When a player connects to the game server binary, +calling [`SDK.Alpha().PlayerConnect(playerID)`]({{< ref "/docs/Guides/Client SDKs/_index.md#alpha-playerconnect-playerid" >}}) +with the unique player token will register them as connected, and store their player id. + +At disconnection time, +call [`SDK.Alpha().PlayerDisconnect(playerID)`]({{< ref "/docs/Guides/Client SDKs/_index.md#alpha-playerdisconnect-playerid" >}}) +, which will deregister them and remove their player id from the list. + +Each of these `playerIDs` is stored on `GameServer.Status.Players.IDs`, and the current count of connected players +can be seen in `GameServer.Status.Players.Count`. + +You can see this in action below in the `GameServer` Status section, where there are 4 players connected: + +``` +... +Status: + Address: 39.82.196.74 + Node Name: gke-test-cluster-default-6cd0ba77-1mps + Players: + Capacity: 10 + Count: 4 + Ids: + xy8a + m0ux + 71nj + lpq5 + Ports: + Name: gameport + Port: 7166 + Reserved Until: + State: Ready +``` + +{{% alert title="Note" color="info" %}} +Calling `PlayerConnect` or `PlayerDisconnect` functions will not +connect or disconnect players, as that is not under the control of Agones. + +This functionality is for tracking purposes only. +{{% /alert %}} + +## Checking Player Data + +Not only is the connected player data stored on the `GameServer` resource, it is also stored in memory within the +SDK, so that it can be used from within the game server binary as a realtime, thread safe, registry of connected +players. + +Therefore, if you want to: + +* Get the current player count, call [`SDK.Alpha().GetPlayerCount()`]({{< ref "/docs/Guides/Client SDKs/_index.md#alpha-getplayercount" >}}) +* Check if a specific player is connected, call [`SDK.Alpha().IsPlayerConnected(playerID)`]({{< ref "/docs/Guides/Client SDKs/_index.md#alpha-isplayerconnected-playerid" >}}) +* Retrieve the full list of connected players, call [`SDK.Alpha().GetConnectedPlayers()`]({{< ref "/docs/Guides/Client SDKs/_index.md#alpha-getconnectedplayers" >}}) + +## Next Steps + +* Review the [Player Tracking SDK Reference]({{< ref "/docs/Guides/Client SDKs/_index.md#player-tracking" >}}) diff --git a/site/content/en/docs/Reference/agones_crd_api_reference.html b/site/content/en/docs/Reference/agones_crd_api_reference.html index c3b285a203..c2eafb515e 100644 --- a/site/content/en/docs/Reference/agones_crd_api_reference.html +++ b/site/content/en/docs/Reference/agones_crd_api_reference.html @@ -4050,8 +4050,7 @@

PlayersSpec GameServerSpec)

-

PlayersSpec tracks the initial player capacity, and what webhooks to send events to when there are -connection/disconnection events.

+

PlayersSpec tracks the initial player capacity

diff --git a/site/content/en/docs/Reference/gameserver.md b/site/content/en/docs/Reference/gameserver.md index d52ce0f55c..4c2f13dbb7 100644 --- a/site/content/en/docs/Reference/gameserver.md +++ b/site/content/en/docs/Reference/gameserver.md @@ -9,6 +9,7 @@ description: > A full GameServer specification is available below and in the {{< ghlink href="examples/gameserver.yaml" >}}example folder{{< /ghlink >}} for reference : +{{% feature expiryVersion="1.5.0" %}} ```yaml apiVersion: "agones.dev/v1" kind: GameServer @@ -79,6 +80,87 @@ spec: image: gcr.io/agones-images/udp-server:0.19 imagePullPolicy: Always ``` +{{% /feature %}} + +{{% feature publishVersion="1.6.0" %}} +```yaml +apiVersion: "agones.dev/v1" +kind: GameServer +# GameServer Metadata +# https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#objectmeta-v1-meta +metadata: + # generateName: "gds-example" # generate a unique name, with the given prefix + name: "gds-example" # set a fixed name +spec: + # if there is more than one container, specify which one is the game server + container: example-server + # Array of ports that can be exposed as direct connections to the game server container + ports: + # name is a descriptive name for the port + - name: default + # portPolicy has three options: + # - "Dynamic" (default) the system allocates a free hostPort for the gameserver, for game clients to connect to + # - "Static", user defines the hostPort that the game client will connect to. Then onus is on the user to ensure that the + # port is available. When static is the policy specified, `hostPort` is required to be populated + # - "Passthrough" dynamically sets the `containerPort` to the same value as the dynamically selected hostPort. + # This will mean that users will need to lookup what port has been opened through the server side SDK. + portPolicy: Static + # (Alpha) the name of the container to open the port on. Defaults to the game server container if omitted or empty. + container: simple-udp + # the port that is being opened on the game server process + containerPort: 7654 + # the port exposed on the host, only required when `portPolicy` is "Static". Overwritten when portPolicy is "Dynamic". + hostPort: 7777 + # protocol being used. Defaults to UDP. TCP is the only other option + protocol: UDP + # Health checking for the running game server + health: + # Disable health checking. defaults to false, but can be set to true + disabled: false + # Number of seconds after the container has started before health check is initiated. Defaults to 5 seconds + initialDelaySeconds: 5 + # If the `Health()` function doesn't get called at least once every period (seconds), then + # the game server is not healthy. Defaults to 5 + periodSeconds: 5 + # Minimum consecutive failures for the health probe to be considered failed after having succeeded. + # Defaults to 3. Minimum value is 1 + failureThreshold: 3 + # Parameters for game server sidecar + sdkServer: + # sdkServer log level parameter has three options: + # - "Info" (default) The SDK server will output all messages except for debug messages + # - "Debug" The SDK server will output all messages including debug messages + # - "Error" The SDK server will only output error messages + logLevel: Info + # grpcPort and httpPort control what ports the sdkserver listens on. + # Starting with Agones 1.2 the default grpcPort is 9357 and the default + # httpPort is 9358. In earlier releases, the defaults were 59357 and 59358 + # respectively but as these were in the ephemeral port range they could + # conflict with other TCP connections. + grpcPort: 9357 + httpPort: 9358 + # [Stage:Alpha] + # [FeatureFlag:PlayerTracking] + # Players provides the configuration for player tracking features. + # Commented out since Alpha, and disabled by default + # players: + # # set this GameServer's initial player capacity + # initialCapacity: 10 + # Pod template configuration + # https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#podtemplate-v1-core + template: + # pod metadata. Name & Namespace is overwritten + metadata: + labels: + myspeciallabel: myspecialvalue + # Pod Specification + spec: + containers: + - name: simple-udp + image: gcr.io/agones-images/udp-server:0.19 + imagePullPolicy: Always +``` +{{% /feature %}} Since Agones defines a new [Custom Resources Definition (CRD)](https://kubernetes.io/docs/concepts/api-extension/custom-resources/) we can define a new resource using the kind `GameServer` with the custom group `agones.dev` and API version `v1`. @@ -89,6 +171,29 @@ The length of the `name` field of the Gameserver should not exceed 63 characters The `spec` field is the actual GameServer specification and it is composed as follow: +{{% feature expiryVersion="1.5.0" %}} +- `container` is the name of container running the GameServer in case you have more than one container defined in the [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/). If you do, this is a mandatory field. For instance this is useful if you want to run a sidecar to ship logs. +- `ports` are an array of ports that can be exposed as direct connections to the game server container + - `name` is an optional descriptive name for a port + - `portPolicy` has three options: + - `Dynamic` (default) the system allocates a random free hostPort for the gameserver, for game clients to connect to. + - `Static`, user defines the hostPort that the game client will connect to. Then onus is on the user to ensure that the port is available. When static is the policy specified, `hostPort` is required to be populated. + - `Passthrough` dynamically sets the `containerPort` to the same value as the dynamically selected hostPort. This will mean that users will need to lookup what port to open through the server side SDK before starting communications. + - `container` (Alpha) the name of the container to open the port on. Defaults to the game server container if omitted or empty. + - `containerPort` the port that is being opened on the game server process, this is a required field for `Dynamic` and `Static` port policies, and should not be included in Passthrough configuration. + - `protocol` the protocol being used. Defaults to UDP. TCP is the only other option. +- `health` to track the overall healthy state of the GameServer, more information available in the [health check documentation]({{< relref "../Guides/health-checking.md" >}}). +-`sdkServer` defines parameters for the game server sidecar + - `logging` field defines log level for SDK server. Defaults to "Info". It has three options: + - "Info" (default) The SDK server will output all messages except for debug messages + - "Debug" The SDK server will output all messages including debug messages + - "Error" The SDK server will only output error messages + - `grpcPort` the port that the SDK Server binds to for gRPC connections + - `httpPort` the port that the SDK Server binds to for HTTP gRPC gateway connections +- `template` the [pod spec template](https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#podtemplatespec-v1-core) to run your GameServer containers, [see](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/#pod-templates) for more information. +{{% /feature %}} + +{{% feature publishVersion="1.6.0" %}} - `container` is the name of container running the GameServer in case you have more than one container defined in the [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/). If you do, this is a mandatory field. For instance this is useful if you want to run a sidecar to ship logs. - `ports` are an array of ports that can be exposed as direct connections to the game server container - `name` is an optional descriptive name for a port @@ -107,7 +212,9 @@ The `spec` field is the actual GameServer specification and it is composed as fo - "Error" The SDK server will only output error messages - `grpcPort` the port that the SDK Server binds to for gRPC connections - `httpPort` the port that the SDK Server binds to for HTTP gRPC gateway connections +- `players` (Alpha, behind "PlayerTracking" feature gate), sets this GameServer's initial player capacity - `template` the [pod spec template](https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#podtemplatespec-v1-core) to run your GameServer containers, [see](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/#pod-templates) for more information. +{{% /feature %}} ## GameServer State Diagram