bevy_stdb
A Bevy integration for SpacetimeDB.
Please enjoy this useless AI generated image based on the README contents of this repo.
Overview
bevy_stdb adapts SpacetimeDB's connection and callback model into Bevy-style resources, systems, plugins, and messages. Its built around a few core ideas:
- Configure everything through
StdbPlugin - Expose the active live connection as a Bevy resource via
StdbConnection - Forward table callbacks into Bevy messages with
TableRegistrar - Store subscription intent independently from the live connection with
StdbSubscriptions - Optionally retry failed connections with
StdbReconnectOptions
The library is organized around connection-scoped lifecycle concerns:
- connection lifecycle: establish the initial connection, expose the active connection resource, and track connection state
- table lifecycle: initialize table message channels once and re-bind table callbacks whenever a connection becomes active
- subscription lifecycle: store desired subscription intent and re-apply queued subscriptions when connected
- reconnect lifecycle: optionally retry connection attempts after disconnects using configurable backoff
Features
- Builder-style setup via
StdbPlugin - Connection resource access through
StdbConnection - Table event bridging into normal Bevy
Messages - Managed subscription intent through
StdbSubscriptions - Optional reconnect support through
StdbReconnectOptions
Example
use *;
use *;
use crate;
pub type StdbConn = ;
pub type StdbSubs = ;
Connection driving
bevy_stdb supports two connection-driving modes:
with_background_driver(...): start SpacetimeDB's background processing for the active connectionwith_frame_driver(...): drive SpacetimeDB from the Bevy schedule each frame
Exactly one driver must be configured. These modes are mutually exclusive, and in most applications you'll want with_background_driver(...).
If WASM support is needed, you can enable the browser feature flag in both this crate and your spacetimedb-sdk crate using a target cfg:
# Enable browser support for wasm builds.
# Replace `*` with the versions you are using.
[]
= { = "*", = ["browser"] }
= { = "*", = ["browser"] }
I recommend checking out the bevy_cli 2d template for a good starter example using WASM + native with nice Bevy features configured.
Native background driving
On native targets, the typical choice is run_threaded:
Browser / wasm background driving (async)
On browser targets, use the generated background task helper instead:
If you target both native and browser, I recommend selecting the background driver with cfg:
Bevy frame-tick driving
Use frame_tick when you want Bevy to drive connection progress from Bevy each frame. Internally, bevy_stdb runs this driver from PreUpdate:
use *;
use *;
use crate;
Table registration
Use StdbPlugin::with_tables to register all table callbacks in one place.
The closure receives both a TableRegistrar and the current database view. Use the db argument to select tables, views, and event streams, then register them through reg.
Typical forms are:
.with_tables
with_tables is intended to be called once during plugin setup. These registrations are replayed during initialization to install the required Bevy message channels and again whenever the connection enters the connected state to bind callbacks for the current live database view.
Messages
Depending on the table shape, bevy_stdb forwards updates into Bevy messages such as:
InsertMessage<T>DeleteMessage<T>UpdateMessage<T>InsertUpdateMessage<T>
This lets normal Bevy systems react to database changes using message readers.
Subscriptions
StdbSubscriptions stores desired subscription intent separately from the live connection.
That means you can:
- declare global (or any other) subscriptions during plugin setup with
with_subscriptions - queue additional subscriptions later from normal Bevy systems
- automatically re-apply queued subscription intent after reconnect
Like the other StdbPlugin configuration methods, with_subscriptions is intended to be configured once during plugin setup.
Subscriptions are keyed, so the application can refer to them using its own domain-specific identifiers, allowing you to also unsubscribe as needed later.
Reconnects
Reconnect behavior is opt-in.
Use StdbPlugin::with_reconnect with StdbReconnectOptions to enable retry behavior after disconnects. Like the other StdbPlugin configuration methods, it is intended to be configured once during plugin setup. When reconnect succeeds:
- the live
StdbConnectionresource is replaced - table callbacks are re-bound
- queued subscriptions are re-applied
Type Aliases
It is useful to define some type aliases of your own. I suggest doing something like this:
pub type StdbConn = ;
pub type StdbSubs = ;
// Or a more constrained version for typical use cases:
// pub type StdbConn<'w> = Res<'w, StdbConnection<DbConnection>>;
// pub type StdbSubs<'w> = ResMut<'w, StdbSubscriptions<SubKeys, RemoteModule>>;
// Usage example
Compatibility
| bevy_stdb | bevy | spacetimedb_sdk |
|---|---|---|
| 0.1 - 0.2 | 0.18 | 2.0 |
| 0.3 - 0.4 | 0.18 | 2.1 |
Notes
This crate focuses on table-driven client workflows. Reducer and procedure access still exist through the active StdbConnection, but the primary Bevy-facing event flow is table/message based.
The project was heavily inspired by bevy_spacetimedb, but takes a different approach to plugin structure, connection lifecycle handling, reconnect behavior, and subscription restoration.