From d54490b4f3507ec517e1768115507c0ffbb81418 Mon Sep 17 00:00:00 2001 From: Mark Mandel Date: Mon, 18 May 2020 15:10:34 -0700 Subject: [PATCH] Player Tracking SDK Reference (#1564) Reference for the general Player Tracking SDK API. This included some slight reorganising, to make it less cluttered as we add more functionality. To come, is a full player tracking guide, and updates to the GameServer reference. Work on #1033 --- .../en/docs/Guides/Client SDKs/_index.md | 186 ++++++++++++++---- site/layouts/shortcodes/alpha.html | 9 + 2 files changed, 157 insertions(+), 38 deletions(-) create mode 100644 site/layouts/shortcodes/alpha.html diff --git a/site/content/en/docs/Guides/Client SDKs/_index.md b/site/content/en/docs/Guides/Client SDKs/_index.md index b7bb90985f..9322a8602a 100644 --- a/site/content/en/docs/Guides/Client SDKs/_index.md +++ b/site/content/en/docs/Guides/Client SDKs/_index.md @@ -65,9 +65,16 @@ Functions which changes GameServer state or settings are: 1. SetLabel() 1. SetAnnotation() 1. Allocate() -1. Reserve() +1. Reserve() +{{% feature publishVersion="1.6.0" %}} +1. Alpha().SetCapacity() +1. Alpha().PlayerConnect() +1. Alpha().PlayerDisconnect() +{{% /feature %}} -### Ready() +### Lifecycle Management + +#### Ready() This tells Agones that the Game Server is ready to take player connections. Once a Game Server has specified that it is `Ready`, then the Kubernetes GameServer record will be moved to the `Ready` state, and the details @@ -77,7 +84,7 @@ While Agones prefers that `Shutdown()` is run once a game has completed to delet if you want or need to move an `Allocated` `GameServer` back to `Ready` to be reused, you can call this SDK method again to do this. -### Health() +#### Health() This sends a single ping to designate that the Game Server is alive and healthy. Failure to send pings within the configured thresholds will result in the GameServer being marked as `Unhealthy`. @@ -85,30 +92,43 @@ in the GameServer being marked as `Unhealthy`. See the {{< ghlink href="examples/gameserver.yaml" >}}gameserver.yaml{{< /ghlink >}} for all health checking configurations. -### Shutdown() -This tells Agones to shut down the currently running game server. -The GameServer state will be set `Shutdown` and the -backing Pod will be deleted, if they have not shut themselves down already. +#### Reserve(seconds) -### SetLabel(key, value) +With some matchmaking scenarios and systems it is important to be able to ensure that a `GameServer` is unable to be deleted, +but doesn't trigger a FleetAutoscaler scale up. This is where `Reserve(seconds)` is useful. -This will set a [Label](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) value on the backing `GameServer` -record that is stored in Kubernetes. To maintain isolation, the `key` value is automatically prefixed with "agones.dev/sdk-" +`Reserve(seconds)` will move the `GameServer` into the Reserved state for the specified number of seconds (0 is forever), and then it will be +moved back to `Ready` state. While in `Reserved` state, the `GameServer` will not be deleted on scale down or `Fleet` update, +and also it could not be Allocated using [GameServerAllocation]({{< ref "/docs/Reference/gameserverallocation.md" >}}). -{{< alert title="Warning" color="warning">}} -There are limits on the characters that be used for label keys and values. Details are [here](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set). -{{< /alert >}} +This is often used when a game server process must register itself with an external system, such as a matchmaker, +that requires it to designate itself as available for a game session for a certain period. Once a game session has started, +it should call `SDK.Allocate()` to designate that players are currently active on it. -This can be useful if you want information from your running game server process to be observable or searchable through the Kubernetes API. +Calling other state changing SDK commands such as `Ready` or `Allocate` will turn off the timer to reset the `GameServer` back +to the `Ready` state or to promote it to an `Allocated` state accordingly. -### SetAnnotation(key, value) +#### Allocate() -This will set a [Annotation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) value on the backing -`Gameserver` record that is stored in Kubernetes. To maintain isolation, the `key` value is automatically prefixed with "agones.dev/sdk-" +With some matchmakers and game matching strategies, it can be important for game servers to mark themselves as `Allocated`. +For those scenarios, this SDK functionality exists. -This can be useful if you want information from your running game server process to be observable through the Kubernetes API. +There is a chance that GameServer does not actually become `Allocated` after this call. Please refer to the general note in [Function Reference](#function-reference) above. -### GameServer() +{{< alert title="Note" color="info">}} +Using a [GameServerAllocation]({{< ref "/docs/Reference/gameserverallocation.md" >}}) is preferred in all other scenarios, +as it gives Agones control over how packed `GameServers` are scheduled within a cluster, whereas with `Allocate()` you +relinquish control to an external service which likely doesn't have as much information as Agones. +{{< /alert >}} + +#### Shutdown() +This tells Agones to shut down the currently running game server. +The GameServer state will be set `Shutdown` and the +backing Pod will be deleted, if they have not shut themselves down already. + +### Configuration Retrieval + +#### GameServer() This returns most of the backing GameServer configuration and Status. This can be useful for instances where you may want to know Health check configuration, or the IP and Port @@ -125,7 +145,7 @@ the `message GameServer`. For language specific documentation, have a look at the respective source (linked above), and the {{< ghlink href="examples" >}}examples{{< /ghlink >}}. -### WatchGameServer(function(gameserver){...}) +#### WatchGameServer(function(gameserver){...}) This executes the passed in callback with the current `GameServer` details whenever the underlying `GameServer` configuration is updated. This can be useful to track `GameServer > Status > State` changes, `metadata` changes, such as labels and annotations, and more. @@ -145,34 +165,124 @@ the `message GameServer`. For language specific documentation, have a look at the respective source (linked above), and the {{< ghlink href="examples" >}}examples{{< /ghlink >}}. -### Allocate() +### Metadata Management -With some matchmakers and game matching strategies, it can be important for game servers to mark themselves as `Allocated`. -For those scenarios, this SDK functionality exists. +#### SetLabel(key, value) -There is a chance that GameServer does not actually become `Allocated` after this call. Please refer to the general note in [Function Reference](#function-reference) above. +This will set a [Label](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) value on the backing `GameServer` +record that is stored in Kubernetes. To maintain isolation, the `key` value is automatically prefixed with "agones.dev/sdk-" + +{{< alert title="Warning" color="warning">}} +There are limits on the characters that be used for label keys and values. Details are [here](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set). +{{< /alert >}} + +This can be useful if you want information from your running game server process to be observable or searchable through the Kubernetes API. + +#### SetAnnotation(key, value) + +This will set a [Annotation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) value on the backing +`Gameserver` record that is stored in Kubernetes. To maintain isolation, the `key` value is automatically prefixed with "agones.dev/sdk-" + +This can be useful if you want information from your running game server process to be observable through the Kubernetes API. + + +{{% feature publishVersion="1.6.0" %}} +### Player Tracking + +{{< alpha title="Player Tracking" gate="PlayerTracking" >}} + +#### Alpha().PlayerConnect(playerID) + +This function increases the SDK’s stored player count by one, and appends this playerID to +`GameServer.Status.Players.IDs`. + +[`GameServer.Status.Players.Count` and `GameServer.Status.Players.IDs`][playerstatus] +are then set to update the player count and id list a second from now, +unless there is already an update pending, in which case the update joins that batch operation. + +`PlayerConnect()` returns true and adds the playerID to the list of playerIDs if this playerID was not already in the +list of connected playerIDs. + +If the playerID exists within the list of connected playerIDs, `PlayerConnect()` will return false, and the list of +connected playerIDs will be left unchanged. + +An error will be returned if the playerID was not already in the list of connected playerIDs but the player capacity for +the server has been reached. The playerID will not be added to the list of playerIDs. {{< alert title="Note" color="info">}} -Using a [GameServerAllocation]({{< ref "/docs/Reference/gameserverallocation.md" >}}) is preferred in all other scenarios, -as it gives Agones control over how packed `GameServers` are scheduled within a cluster, whereas with `Allocate()` you -relinquish control to an external service which likely doesn't have as much information as Agones. +Do not use this method if you are manually managing `GameServer.Status.Players.IDs` and `GameServer.Status.Players.Count` +through the Kubernetes API, as indeterminate results will occur. {{< /alert >}} + +#### Alpha().PlayerDisconnect(playerID) -### Reserve(seconds) +This function decreases the SDK’s stored player count by one, and removes the playerID from +[`GameServer.Status.Players.IDs`][playerstatus]. -With some matchmaking scenarios and systems it is important to be able to ensure that a `GameServer` is unable to be deleted, -but doesn't trigger a FleetAutoscaler scale up. This is where `Reserve(seconds)` is useful. +`GameServer.Status.Players.Count` and `GameServer.Status.Players.IDs` are then set to +update the player count and id list a second from now, +unless there is already an update pending, in which case the update joins that batch operation. -`Reserve(seconds)` will move the `GameServer` into the Reserved state for the specified number of seconds (0 is forever), and then it will be -moved back to `Ready` state. While in `Reserved` state, the `GameServer` will not be deleted on scale down or `Fleet` update, -and also it could not be Allocated using [GameServerAllocation]({{< ref "/docs/Reference/gameserverallocation.md" >}}). +`PlayerDisconnect()` will return true and remove the supplied playerID from the list of connected playerIDs if the +playerID value exists within the list. -This is often used when a game server process must register itself with an external system, such as a matchmaker, -that requires it to designate itself as available for a game session for a certain period. Once a game session has started, -it should call `SDK.Allocate()` to designate that players are currently active on it. +If the playerID was not in the list of connected playerIDs, the call will return false, and the connected playerID list +will be left unchanged. -Calling other state changing SDK commands such as `Ready` or `Allocate` will turn off the timer to reset the `GameServer` back -to the `Ready` state or to promote it to an `Allocated` state accordingly. +{{< alert title="Note" color="info">}} +Do not use this method if you are manually managing `GameServer.Status.Players.IDs` and `GameServer.Status.Players.Count` +through the Kubernetes API, as indeterminate results will occur. +{{< /alert >}} + +#### Alpha().SetPlayerCapacity(count) + +Update the [`GameServer.Status.Players.Capacity`][playerstatus] value with a new capacity. + +#### Alpha().GetPlayerCapacity() + +This function retrieves the current player capacity. This is always accurate from what has been set through this SDK, +even if the value has yet to be updated on the GameServer status resource. + +{{< alert title="Note" color="info">}} +If `GameServer.Status.Players.Capacity` is set manually through the Kubernetes API, use `SDK.GameServer()` or +`SDK.WatchGameServer()` instead to view this value. +{{< /alert >}} + +#### Alpha().GetPlayerCount() + +This function returns if the playerID is currently connected to the GameServer. +This is always accurate from what has been set through this SDK, +even if the value has yet to be updated on the GameServer status resource. + +{{< alert title="Note" color="info">}} +If `GameServer.Status.Players.IDs` is set manually through the Kubernetes API, use SDK.GameServer() +or SDK.WatchGameServer() instead to retrieve the current player count. +{{< /alert >}} + +#### Alpha().IsPlayerConnected(playerID) + +This function returns if the playerID is currently connected to the GameServer. This is always accurate from what has +been set through this SDK, +even if the value has yet to be updated on the GameServer status resource. + +{{< alert title="Note" color="info">}} +If `GameServer.Status.Players.IDs` is set manually through the Kubernetes API, use SDK.GameServer() +or SDK.WatchGameServer() instead to determine connected status. +{{< /alert >}} + +#### Alpha().GetConnectedPlayers() + +This function returns the list of the currently connected player ids. This is always accurate from what has been set +through this SDK, even if the value has yet to be updated on the GameServer status resource. + +{{< alert title="Note" color="info">}} +If `GameServer.Status.Players.IDs` is set manually through the Kubernetes API, use SDK.GameServer() +or SDK.WatchGameServer() instead to list the connected players. +{{< /alert >}} + +[playerstatus]: {{< ref "/docs/Reference/agones_crd_api_reference.html#PlayerStatus" >}} + +{{% /feature %}} ## Writing your own SDK diff --git a/site/layouts/shortcodes/alpha.html b/site/layouts/shortcodes/alpha.html new file mode 100644 index 0000000000..dd1e435bdb --- /dev/null +++ b/site/layouts/shortcodes/alpha.html @@ -0,0 +1,9 @@ +{{- $gate := .Get "gate" }} +{{- $title := .Get "title" }} +