Star Gambit SDK#
The Star Gambit SDK allows developers to build computer players (coms) and make them available to online Star Gambit players . To write a com, you need to write one function: "given the board, what do I do?". The SDK handles the rest. Connect it to the server with an API token and your com can be played.
//! Usage: cargo run --example random_com -- --token <api_token>
use rand::seq::SliceRandom;
use sg_sdk::{operate_com, Com, Game};
struct RandomCom;
impl Com for RandomCom {
fn act(&mut self, game: &Game) -> Vec<String> {
// Play one random legal action; the runner calls us again until the
// turn ends. (A com could instead return a whole turn at once.)
.choose(&mut rand::thread_rng())
.cloned()
.into_iter()
.collect()
}
}
fn main() {
if let Err(e) = operate_com("random_com", || RandomCom) {
eprintln!("fatal: {e}");
}
}
Writing a com#
Implement Com:
pub trait Com {
fn act(&mut self, game: &Game) -> Vec<String>;
}
act is called when it's your turn, and again while the turn continues. Return
the action(s) to play in the correct order, ending with "END" to end the turn. You can return
one action per call or the whole turn at once. Each action is validated
against the engine before it's sent; illegal actions are skipped and logged. A
call that makes no progress (all-illegal or empty) is retried with the same
state; the same no-progress output three times in a row (or 20 consecutive
no-progress calls) is treated as a crashed com and disconnects from that game
(ComError::ComCrashed). &mut self lets a com keep state across calls.
The &Game is a read-only view of the position:
| Method | Returns |
|---|---|
legal_actions() |
every legal SGN action now, incl. "END" when ending the turn is allowed |
engine() |
the full authoritative GameEngine state. Use .execute(sgn: &str) to compute the results of an action, returning a copy of the game engine with that SGN applied. |
me() |
which player you are: 0 (first) or 1 |
is_my_turn() |
true while it's your turn and the game is unfinished |
SGN actions take the forms "<kind>@<placement>", "<unit>+<move>",
"<unit>*<attack>", and "END"; legal_actions() is also available if you'd
rather pick from the enumerated legal set than build tokens yourself. See
SGN.md for a minimal explanation of the notation.
Getting an API token#
Every com authenticates with an API token, which you create at play.stargamb.it:
- Log in. Open play.stargamb.it and log in (or create an account if you don't have one).
- Open the COMS screen. Reach it either way:
- Settings → User → Manage COMs, or
- PLAY → VS COM, then Manage COMs in the COM picker dialog.
- Register a COM. Press REGISTER A COM and pick a difficulty. A new COM
slot appears with a permanent handle (e.g.
⎇011-00000000). You may register up to three. - Reveal and copy the token. On the COM's card, press Reveal next to
API Token to show it, then Copy token (or select the revealed text).
Keep it secret: anyone with the token can play as your COM. Pass it to
run_as_com/ the examples as<api_token>.
Running a com#
pub fn run_as_com<F, B>(server: &str, com_token: &str, factory: F) -> Result<(), ComError>
where F: Fn() -> B + 'static, B: Com + 'static;
Connects to Metalith's persistent /ws/com?token=… endpoint and plays the
games the server assigns it, calling factory once per game for a fresh com.
Blocks forever, reconnecting with a 5-second back-off. Max-concurrency is
enforced server-side, so there's nothing to configure locally.
The com_token is the API token from Getting an API
token.
server is an HTTP base ("http://localhost", "https://ws.stargamb.it");
the WebSocket base is derived from it (http→ws, https→wss).
Outcome and errors#
run_as_com logs each game's outcome (or error) to stderr and only returns on
a fatal setup error. Outcome { winner, reason } reports the winner slot/id
(empty on a draw) and the game-end SGN (e.g. "0=FF", "0==1"). ComError
(Ws, Json, Runtime, ConnectionClosed, ComCrashed, Protocol,
Spectator) implements Display/Error.
Examples#
Each is a complete com; run from shared/sg-sdk/:
cargo run --example random_com -- --token <api_token> [--server <url>] # uniformly random legal action
cargo run --example fire_com -- --token <api_token> [--server <url>] # random but a little smarter, prioritizing firing.
--server defaults to https://ws.stargamb.it; pass --server http://localhost to target a local dev server.
The example coms ascend in strength (fire_com reliably beats random_com)
and share their decision logic in examples/strategy/mod.rs so the com you run
against the server is the same one the offline tools measure:
cargo run --release --example arena # tournament; checks fire > random
cargo run --release --example debug_game -- fire random # trace one game turn by turn
tests/com_ladder.rs enforces the ladder (the stronger com never loses).