Game Module SDK¶
The
qs-bridge-module-sdkRust crate provides compile-time guarantees, typed registration, and IDE support for building game modules.
Overview¶
The Game Module SDK is a Rust crate that game module authors depend on. Rather than relying on naming conventions, the SDK uses Rust traits to enforce the interface contract at compile time — preventing misconfiguration and eliminating an entire class of integration bugs.
# Cargo.toml for a new game module
[dependencies]
spacetimedb = "1.1"
qs-bridge-module-sdk = { path = "../qs-bridge-module-sdk" }
Crate Structure¶
qs-bridge-module-sdk/
├── Cargo.toml # depends on spacetimedb = "1.1"
├── src/
│ ├── lib.rs # re-exports
│ ├── traits.rs # GameModule trait + lifecycle callbacks
│ ├── platform_types.rs # Read-only views of platform table schemas
│ ├── registration.rs # #[qs_game_module] proc macro
│ └── bridge.rs # Cross-database communication helpers
Core Trait — GameModule¶
Every game module must implement this trait exactly once. The #[qs_game_module] macro generates the SpacetimeDB reducer stubs wired to the trait implementation.
pub trait GameModule: Send + Sync + 'static {
/// Module identity — used in ServerRegistry.module_name
const MODULE_NAME: &'static str;
/// Called when a player joins this server.
/// Platform has already validated identity, checked bans/whitelist.
fn on_player_join(ctx: &ReducerContext, player_id: &str, server_id: &str);
/// Called when a player disconnects (graceful or timeout).
fn on_player_leave(ctx: &ReducerContext, player_id: &str);
/// Called every 30s by the bridge heartbeat.
/// Use for periodic cleanup, decay timers, scheduled spawns.
fn on_heartbeat(ctx: &ReducerContext, server_id: &str);
/// Called when the platform bans a player who is currently in-game.
/// Module should force-disconnect and clean up game state.
fn on_player_banned(ctx: &ReducerContext, player_id: &str, reason: &str) {}
/// Called when a vault deposit arrives for this server.
/// Module should materialise items into the player's inventory.
fn on_vault_deposit(ctx: &ReducerContext, player_id: &str, item_data: &[u8]) {}
/// Called when a character transfer arrives.
/// Module should create/restore the character from the serialised blob.
fn on_transfer_arrive(ctx: &ReducerContext, player_id: &str, char_data: &[u8]) {}
}
Callback Summary¶
| Callback | Required | Trigger | Typical Use |
|---|---|---|---|
on_player_join |
✅ | Platform validates player | Spawn character, load inventory |
on_player_leave |
✅ | Disconnect (graceful/timeout) | Save state, despawn character |
on_heartbeat |
✅ | Every 30s from bridge | Decay timers, zombie spawns, cleanup |
on_player_banned |
Optional | Mid-game ban | Force disconnect, cleanup |
on_vault_deposit |
Optional | Cross-server item transfer | Materialise items in inventory |
on_transfer_arrive |
Optional | Character transfer | Restore character from blob |
Platform Types¶
The SDK provides read-only Rust types matching platform table schemas, so game modules can deserialise platform data without copy-pasting structs:
// platform_types.rs — read-only views
pub struct PlayerPresence {
pub player_id: String,
pub server_id: String,
pub connected_at: Timestamp,
}
pub enum BanState {
Active,
Expired,
Appealed,
}
pub enum AdminLevel {
SuperAdmin, // level 0 — full access
Admin, // level 1 — moderate, configure
Moderator, // level 2 — moderate only
}
Proc Macro — #[qs_game_module]¶
The #[qs_game_module] attribute macro generates SpacetimeDB reducer stubs wired to the trait implementation:
use qs_bridge_module_sdk::prelude::*;
#[qs_game_module]
struct MyGameModule;
impl GameModule for MyGameModule {
const MODULE_NAME: &'static str = "my-game";
fn on_player_join(ctx: &ReducerContext, player_id: &str, server_id: &str) {
// Create player row, spawn character, load inventory
}
fn on_player_leave(ctx: &ReducerContext, player_id: &str) {
// Save state, despawn, update presence
}
fn on_heartbeat(ctx: &ReducerContext, server_id: &str) {
// Periodic cleanup, spawn management
}
}
Generated code (by the proc macro):
// Auto-generated — do not edit
#[spacetimedb::reducer]
fn __qs_on_player_join(ctx: &ReducerContext, player_id: String, server_id: String) {
MyGameModule::on_player_join(ctx, &player_id, &server_id);
}
#[spacetimedb::reducer]
fn __qs_on_player_leave(ctx: &ReducerContext, player_id: String) {
MyGameModule::on_player_leave(ctx, &player_id);
}
#[spacetimedb::reducer]
fn __qs_on_heartbeat(ctx: &ReducerContext, server_id: String) {
MyGameModule::on_heartbeat(ctx, &server_id);
}
// ... and so on for each callback
Bridge Helpers¶
The bridge module provides helpers for game modules to communicate back to the platform:
use qs_bridge_module_sdk::bridge;
// Update player count in ServerRegistry
bridge::report_online_count(ctx, server_id, count);
// Update server status (Starting/Running/Stopping/Offline)
bridge::report_server_status(ctx, server_id, ServerStatus::Running);
Data Flow¶
graph LR
subgraph Platform["Platform Module"]
SR["ServerRegistry"]
PP["PlayerPresence"]
BE["BanEntry"]
GV["GlobalVault"]
TQ["TransferQueue"]
end
subgraph Game["Game Module"]
HB["on_heartbeat()"]
PJ["on_player_join()"]
PB["on_player_banned()"]
VD["on_vault_deposit()"]
TA["on_transfer_arrive()"]
RC["(reducer calls)"]
end
SR -- "heartbeat" --> HB
PP -- "join/leave" --> PJ
BE -- "ban sync" --> PB
GV -- "deposit" --> VD
TQ -- "transfer" --> TA
RC -- "status" --> Platform
What the SDK Provides¶
- ✅
platform_types.rs— typed views of the 12 platform tables - ✅
#[qs_game_module]proc macro — generates reducer stubs wired to trait - ✅
bridge::report_online_count()— update ServerRegistry from game module - ✅
bridge::report_server_status()— set server status from game module
What the SDK Does NOT Provide¶
- ❌ Game tables, game reducers, game logic — entirely the module author's domain
- ❌ Panel UI extensions — game-specific pages are a separate concern (via PanelExtension mods)
- ❌ C++ bridge hooks — engine-specific, handled by
libqsbridge.so
Related Pages¶
- Game Modules Overview — what game modules are
- HumanitZ Module — reference implementation
- Creating a Module — step-by-step guide
- STDB Module — platform STDB module