| name | spacetimedb-agent |
| description | SpacetimeDB module creation, table definitions, reducer functions, client subscriptions, and real-time sync patterns.
|
| version | 0.1.0 |
| author | Jero (LATTICE / MARPA Design Studios) |
| triggers | ["create a spacetimedb module","spacetimedb table","spacetimedb reducer","real-time database","spacetime sync"] |
| tools | ["Bash","Read","Write","Edit"] |
SpacetimeDB Agent
USE WHEN the user wants to create SpacetimeDB modules, define tables with real-time subscriptions, write reducer functions, or set up client-side sync for multiplayer/real-time applications.
What It Does
Generates SpacetimeDB server modules (Rust or C#) and client integration code for real-time applications with automatic state synchronization.
Core Concepts
- Module — Server-side logic deployed to SpacetimeDB (Rust or C#)
- Table — Persistent data with automatic client sync
- Reducer — Server-side function called by clients (transactional, serializable)
- Subscription — Client-side SQL query that auto-updates on table changes
- Identity — Built-in auth, each connection has a unique identity
Module Structure (Rust)
use spacetimedb::{spacetimedb, ReducerContext, Identity, Timestamp};
#[spacetimedb(table)]
pub struct Player {
#[primarykey]
pub identity: Identity,
pub name: String,
pub x: f32,
pub y: f32,
pub online: bool,
}
#[spacetimedb(reducer)]
pub fn set_name(ctx: &ReducerContext, name: String) {
if let Some(mut player) = Player::filter_by_identity(&ctx.sender) {
player.name = name;
Player::update_by_identity(&ctx.sender, player);
}
}
#[spacetimedb(init)]
pub fn init(_ctx: &ReducerContext) {
}
#[spacetimedb(connect)]
pub fn on_connect(ctx: &ReducerContext) {
Player::insert(Player {
identity: ctx.sender,
name: String::new(),
x: 0.0,
y: 0.0,
online: true,
}).unwrap();
}
#[spacetimedb(disconnect)]
pub fn on_disconnect(ctx: &ReducerContext) {
if let Some(mut player) = Player::filter_by_identity(&ctx.sender) {
player.online = false;
Player::update_by_identity(&ctx.sender, player);
}
}
Client Subscription (TypeScript)
import { SpacetimeDBClient, Identity } from "@clockworklabs/spacetimedb-sdk";
const client = new SpacetimeDBClient("ws://localhost:3000", "my_module");
client.subscribe(["SELECT * FROM Player WHERE online = true"]);
Player.onInsert((player, reducerEvent) => {
console.log(`Player joined: ${player.name}`);
});
Player.onUpdate((oldPlayer, newPlayer, reducerEvent) => {
console.log(`Player moved: ${newPlayer.x}, ${newPlayer.y}`);
});
client.call("set_name", ["MyPlayer"]);
CLI Commands
curl -fsSL https://install.spacetimedb.com | bash
spacetime init --lang rust my_module
spacetime init --lang csharp my_module
spacetime publish my_module
spacetime generate --lang typescript --out-dir client/src/module_bindings
spacetime logs my_module
spacetime sql my_module "SELECT * FROM Player"
Patterns
Unique Constraints
#[spacetimedb(table)]
pub struct Item {
#[primarykey]
#[autoinc]
pub id: u64,
#[unique]
pub name: String,
pub owner: Identity,
}
Scheduled Reducers
#[spacetimedb(table)]
#[spacetimedb(scheduled(tick))]
pub struct TickSchedule {
#[primarykey]
#[autoinc]
pub id: u64,
pub scheduled_at: spacetimedb::ScheduleAt,
}
#[spacetimedb(reducer)]
pub fn tick(ctx: &ReducerContext, _schedule: TickSchedule) {
}
Rules
- Tables MUST have a
#[primarykey] field
- Reducers are transactional — if they panic, all changes roll back
- Use
filter_by_* for indexed lookups, SQL subscriptions for complex queries
- Generate client bindings after every schema change
- Test locally with
spacetime start before publishing to cloud