Rust Game Server Client SDK

This is the Rust version of the Agones Game Server Client SDK.

Check the Client SDK Documentation for more details on each of the SDK functions and how to run the SDK locally.

SDK Functionality

Area Action Implemented
Lifecycle Ready ✔️
Lifecycle Health ✔️
Lifecycle Reserve ✔️
Lifecycle Allocate ✔️
Lifecycle Shutdown ✔️
Configuration GameServer ✔️
Configuration Watch ✔️
Metadata SetAnnotation ✔️
Metadata SetLabel ✔️
Counters GetCounterCount
Counters SetCounterCount
Counters IncrementCounter
Counters DecrementCounter
Counters SetCounterCapacity
Counters GetCounterCapacity
Lists AppendListValue
Lists DeleteListValue
Lists SetListCapacity
Lists GetListCapacity
Lists ListContains
Lists GetListLength
Lists GetListValues
Player Tracking GetConnectedPlayers ✔️
Player Tracking GetPlayerCapacity ✔️
Player Tracking GetPlayerCount ✔️
Player Tracking IsPlayerConnected ✔️
Player Tracking PlayerConnect ✔️
Player Tracking PlayerDisconnect ✔️
Player Tracking SetPlayerCapacity ✔️

Prerequisites

Usage

Add this crate to dependencies section in your Cargo.toml.

Also note that the SDK is async only, so you will need an async runtime to execute the futures exposed by the SDK. It is recommended to use tokio as the SDK already depends on tokio due to its choice of gRPC library, tonic.

[dependencies]
agones = "1.34.0"
tokio = { version = "1.32.0", features = ["macros", "sync"] }

To begin working with the SDK, create an instance of it.

use std::time::Duration;

#[tokio::main]
async fn main() {
    let mut sdk = agones::Sdk::new(None /* default port */, None /* keep_alive */)
        .await
        .expect("failed to connect to SDK server");
}

To send health checks, call sdk.health_check, which will return a tokio::sync::mpsc::Sender::<()> which will send a health check every time a message is posted to the channel.

let health = sdk.health_check();
if health.send(()).await.is_err() {
    eprintln!("the health receiver was closed");
}

To mark the game session as ready call sdk.ready().

sdk.ready().await?;

To mark the game server as reserved for a period of time, call sdk.reserve(duration).

sdk.reserve(Duration::new(5, 0)).await?;

To mark that the game session is completed and the game server should be shut down call sdk.shutdown().

if let Err(e) = sdk.shutdown().await {
    eprintln!("Could not run Shutdown: {}", e);
}

To set a Label on the backing GameServer call sdk.set_label(key, value).

sdk.set_label("test-label", "test-value").await?;

To set an Annotation on the backing GameServer call sdk.set_annotation(key, value).

sdk.set_annotation("test-annotation", "test value").await?;

To get details of the backing GameServer call sdk.get_gameserver().

The function will return an instance of agones::types::GameServer including GameServer configuration info.

let gameserver = sdk.get_gameserver().await?;

To get updates on the backing GameServer as they happen, call sdk.watch_gameserver.

This will stream updates and endlessly until the stream is closed, so it is recommended to push this into its own async task.

let _watch = {
    // We need to clone the SDK as we are moving it to another task
    let mut watch_client = sdk.clone();
    // We use a simple oneshot to signal to the task when we want it to shutdown
    // and stop watching the gameserver update stream
    let (tx, mut rx) = tokio::sync::oneshot::channel::<()>();

    tokio::task::spawn(async move {
        println!("Starting to watch GameServer updates...");
        match watch_client.watch_gameserver().await {
            Err(e) => eprintln!("Failed to watch for GameServer updates: {}", e),
            Ok(mut stream) => loop {
                tokio::select! {
                    // We've received a new update, or the stream is shutting down
                    gs = stream.message() => {
                        match gs {
                            Ok(Some(gs)) => {
                                println!("GameServer Update, name: {}", gs.object_meta.unwrap().name);
                                println!("GameServer Update, state: {}", gs.status.unwrap().state);
                            }
                            Ok(None) => {
                                println!("Server closed the GameServer watch stream");
                                break;
                            }
                            Err(e) => {
                                eprintln!("GameServer Update stream encountered an error: {}", e);
                            }
                        }

                    }
                    // The watch is being dropped so we're going to shutdown the task
                    // and the watch stream
                    _ = &mut rx => {
                        println!("Shutting down GameServer watch loop");
                        break;
                    }
                }
            },
        }
    });

    tx
};

For more information, please read the SDK Overview, check out agones sdk implementation and also look at the Rust example .


Last modified March 19, 2024: Update Supported Kubernetes to 1.27, 1.28, 1.29 (#3654) (ace51d6)