Alpha features require the PlayerTracking feature gate to be enabled in your Agones installation. These APIs may change in future releases.
Overview
The Alpha SDK provides player tracking capabilities, allowing game servers to manage connected players through the Agones API. The SDK maintains player counts and IDs, syncing them to the GameServer status resource.
Package : agones.dev.sdk.alpha
Key Features
Automatic Capacity Tracking : Maintain player count and capacity automatically
Player ID Management : Track individual player connections by ID
Batched Updates : Player updates are batched for efficiency (1-second intervals)
Capacity Enforcement : Prevents exceeding configured player capacity
SDK-Managed State : SDK maintains accurate state even before Kubernetes updates
Important Considerations
Do not use Alpha SDK player tracking methods if you’re manually managing GameServer.Status.Players.IDs and GameServer.Status.Players.Count through the Kubernetes API. This will cause indeterminate results.
Update Batching
Player tracking updates are batched to reduce Kubernetes API load:
Updates are sent approximately 1 second after the first change
Multiple changes within the 1-second window are combined
The SDK maintains accurate state immediately, even before the batch update
Use SDK methods (not Kubernetes API) to query current state for accuracy
PlayerConnect
Increases the player count by one and adds the player ID to the connected players list.
rpc PlayerConnect (PlayerID) returns (Bool);
Behavior
Increments GameServer.Status.Players.Count by 1
Appends the player ID to GameServer.Status.Players.IDs
Updates are batched and sent ~1 second later
Returns true if the player ID was added successfully
Returns false if the player ID already exists
Returns an error if capacity is reached
Request
The unique identifier for the player connecting to the game server.
Response
true: Player ID was added successfully
false: Player ID already exists in the connected players list
Error: Player capacity has been reached
Example Usage
import (
" log "
alphaSdk " agones.dev/agones/sdks/go/alpha "
)
func onPlayerJoin ( alpha * alphaSdk . Alpha , playerID string ) error {
connected , err := alpha . PlayerConnect ( playerID )
if err != nil {
return fmt . Errorf ( "could not connect player: %v " , err )
}
if connected {
log . Printf ( "Player %s connected successfully" , playerID )
} else {
log . Printf ( "Player %s was already connected" , playerID )
}
return nil
}
// Usage
if err := onPlayerJoin ( alpha , "player-12345" ); err != nil {
if strings . Contains ( err . Error (), "capacity" ) {
log . Println ( "Server is full" )
// Reject connection
}
}
PlayerDisconnect
Decreases the player count by one and removes the player ID from the connected players list.
rpc PlayerDisconnect (PlayerID) returns (Bool);
Behavior
Decrements GameServer.Status.Players.Count by 1
Removes the player ID from GameServer.Status.Players.IDs
Updates are batched and sent ~1 second later
Returns true if the player ID was removed successfully
Returns false if the player ID was not in the list
Request
The unique identifier for the player disconnecting from the game server.
Response
true: Player ID was removed successfully
false: Player ID was not in the connected players list
Example Usage
func onPlayerLeave ( alpha * alphaSdk . Alpha , playerID string ) {
disconnected , err := alpha . PlayerDisconnect ( playerID )
if err != nil {
log . Printf ( "Error disconnecting player: %v " , err )
return
}
if disconnected {
log . Printf ( "Player %s disconnected successfully" , playerID )
} else {
log . Printf ( "Player %s was not connected" , playerID )
}
}
SetPlayerCapacity
Updates the maximum player capacity for the game server.
rpc SetPlayerCapacity (Count) returns (Empty);
Behavior
Updates GameServer.Status.Players.Capacity to the specified value
Can increase or decrease capacity dynamically
Cannot set capacity below current player count
Request
The new player capacity. Must be a non-negative integer and greater than or equal to the current player count.
Response
Returns empty on success.
Example Usage
// Increase capacity for a large match
func setLargeMatchCapacity ( alpha * alphaSdk . Alpha ) error {
count := & alpha . Count { Count : 64 }
if err := alpha . SetPlayerCapacity ( count ); err != nil {
return fmt . Errorf ( "could not set capacity: %v " , err )
}
log . Println ( "Set player capacity to 64" )
return nil
}
// Reduce capacity for a small match
func setSmallMatchCapacity ( alpha * alphaSdk . Alpha ) error {
count := & alpha . Count { Count : 8 }
if err := alpha . SetPlayerCapacity ( count ); err != nil {
return fmt . Errorf ( "could not set capacity: %v " , err )
}
log . Println ( "Set player capacity to 8" )
return nil
}
GetPlayerCapacity
Retrieves the current player capacity. This is always accurate from the SDK’s perspective, even before Kubernetes updates.
rpc GetPlayerCapacity (Empty) returns (Count);
Behavior
Returns the current capacity maintained by the SDK
Accurate even if the value hasn’t been written to Kubernetes yet
For manually-set capacity via Kubernetes API, use SDK.GameServer() instead
Request
Response
The current player capacity.
Example Usage
func checkCapacity ( alpha * alphaSdk . Alpha ) ( int64 , error ) {
capacity , err := alpha . GetPlayerCapacity ()
if err != nil {
return 0 , err
}
log . Printf ( "Current capacity: %d " , capacity . Count )
return capacity . Count , nil
}
GetPlayerCount
Retrieves the current player count. This is always accurate from the SDK’s perspective, even before Kubernetes updates.
rpc GetPlayerCount (Empty) returns (Count);
Behavior
Returns the current count maintained by the SDK
Accurate even if the value hasn’t been written to Kubernetes yet
For manually-set counts via Kubernetes API, use SDK.GameServer() instead
Request
Response
The current number of connected players.
Example Usage
func logPlayerCount ( alpha * alphaSdk . Alpha ) error {
count , err := alpha . GetPlayerCount ()
if err != nil {
return err
}
log . Printf ( "Current player count: %d " , count . Count )
return nil
}
// Check if server is full
func isServerFull ( alpha * alphaSdk . Alpha ) ( bool , error ) {
count , err := alpha . GetPlayerCount ()
if err != nil {
return false , err
}
capacity , err := alpha . GetPlayerCapacity ()
if err != nil {
return false , err
}
return count . Count >= capacity . Count , nil
}
IsPlayerConnected
Checks if a specific player ID is currently connected.
rpc IsPlayerConnected (PlayerID) returns (Bool);
Behavior
Returns true if the player ID is in the connected players list
Returns false if the player ID is not in the list
Accurate even if the value hasn’t been written to Kubernetes yet
For manually-managed player IDs via Kubernetes API, use SDK.GameServer() instead
Request
Response
true: Player is connected
false: Player is not connected
Example Usage
func checkPlayerConnection ( alpha * alphaSdk . Alpha , playerID string ) ( bool , error ) {
result , err := alpha . IsPlayerConnected ( playerID )
if err != nil {
return false , err
}
if result . Bool {
log . Printf ( "Player %s is connected" , playerID )
} else {
log . Printf ( "Player %s is not connected" , playerID )
}
return result . Bool , nil
}
// Prevent duplicate connections
func connectPlayerIfNew ( alpha * alphaSdk . Alpha , playerID string ) error {
connected , err := alpha . IsPlayerConnected ( playerID )
if err != nil {
return err
}
if connected . Bool {
return fmt . Errorf ( "player %s is already connected" , playerID )
}
_ , err = alpha . PlayerConnect ( playerID )
return err
}
GetConnectedPlayers
Retrieves the list of all currently connected player IDs.
rpc GetConnectedPlayers(Empty) returns (PlayerIDList);
Behavior
Returns all player IDs in the connected players list
Accurate even if the value hasn’t been written to Kubernetes yet
For manually-managed player IDs via Kubernetes API, use SDK.GameServer() instead
Request
Response
Array of connected player IDs.
Example Usage
func listConnectedPlayers ( alpha * alphaSdk . Alpha ) ([] string , error ) {
players , err := alpha . GetConnectedPlayers ()
if err != nil {
return nil , err
}
log . Printf ( "Connected players: %v " , players . List )
return players . List , nil
}
// Send message to all connected players
func broadcastToAllPlayers ( alpha * alphaSdk . Alpha , message string ) error {
players , err := alpha . GetConnectedPlayers ()
if err != nil {
return err
}
for _ , playerID := range players . List {
sendMessage ( playerID , message )
}
return nil
}
Message Types
PlayerID
message PlayerID {
string playerID = 1 ;
}
Represents a unique player identifier.
Count
message Count {
int64 count = 1 ;
}
Represents a count value (player count or capacity).
Bool
message Bool {
bool bool = 1 ;
}
Represents a boolean result.
PlayerIDList
message PlayerIDList {
repeated string list = 1 ;
}
Represents a list of player IDs.
HTTP Gateway
Alpha SDK methods are available via HTTP/JSON:
PlayerConnect
PlayerDisconnect
SetPlayerCapacity
GetPlayerCapacity
GetPlayerCount
IsPlayerConnected
GetConnectedPlayers
curl -X POST http://localhost:9357/alpha/player/connect \
-H "Content-Type: application/json" \
-d '{"playerID": "player-12345"}'
Complete Integration Example
package main
import (
" context "
" log "
" time "
" agones.dev/agones/sdks/go "
alphaSdk " agones.dev/agones/sdks/go/alpha "
)
type GameServer struct {
sdk * sdk . SDK
alpha * alphaSdk . Alpha
}
func NewGameServer () ( * GameServer , error ) {
s , err := sdk . NewSDK ()
if err != nil {
return nil , err
}
a := alphaSdk . NewAlpha ( s )
return & GameServer { sdk : s , alpha : a }, nil
}
func ( gs * GameServer ) Start () error {
// Set player capacity
capacity := & alphaSdk . Count { Count : 32 }
if err := gs . alpha . SetPlayerCapacity ( capacity ); err != nil {
return err
}
// Signal ready
if err := gs . sdk . Ready (); err != nil {
return err
}
log . Println ( "Game server ready with capacity for 32 players" )
return nil
}
func ( gs * GameServer ) OnPlayerJoin ( playerID string ) error {
connected , err := gs . alpha . PlayerConnect ( playerID )
if err != nil {
return err
}
if ! connected {
return fmt . Errorf ( "player already connected" )
}
count , _ := gs . alpha . GetPlayerCount ()
log . Printf ( "Player %s joined. Total: %d " , playerID , count . Count )
return nil
}
func ( gs * GameServer ) OnPlayerLeave ( playerID string ) error {
disconnected , err := gs . alpha . PlayerDisconnect ( playerID )
if err != nil {
return err
}
if ! disconnected {
return fmt . Errorf ( "player not connected" )
}
count , _ := gs . alpha . GetPlayerCount ()
log . Printf ( "Player %s left. Total: %d " , playerID , count . Count )
// Shutdown if no players left
if count . Count == 0 {
log . Println ( "No players remaining, shutting down..." )
time . Sleep ( 30 * time . Second ) // Grace period
gs . sdk . Shutdown ()
}
return nil
}