bevy_persistence_database
Persistence for Bevy ECS to ArangoDB or Postgres with an idiomatic Bevy Query API, explicit load triggers, and manual commits you can await.
Highlights
PersistenceQuerymirrors BevyQuery: use iter/get/single/get_many/iter_combinations after callingensure_loaded().- Smart caching and coalesced loads within a frame;
force_refresh()bypasses cache when needed. - Presence/value filters:
With,Without,Or, optionals, comparisons, and key filters viaGuid::key_field(). - Resources persisted alongside components with
#[persist(resource)]. - Batching + parallel commit execution; per-document versioning for optimistic concurrency.
Install
[]
= { = "0.17", = false, = ["bevy_log"] }
= { = "0.2.2", = ["arango", "postgres"] }
Enable arango or postgres features based on your backend and supply an Arc<dyn DatabaseConnection> at startup.
Define persistable types
use persist;
Add the plugin
use *;
use ;
use Arc;
Loading data
use *;
use ;
After ensure_loaded(), PersistenceQuery derefs to a regular Bevy Query for pass-through reads without additional DB I/O. Use force_refresh() to bypass cache.
Joins and transmute
use *;
use ;
Use join_filtered to correlate data across multiple queries without reloading, and transmute to widen the component view for reuse in systems or for table-style assertions in tests.
Committing changes
Changes are not auto-committed. Use the helpers:
use ;
// Async (drives its own updates internally)
let _ = commit.await?;
// Blocking convenience
let _ = commit_sync?;
Or trigger manually if you’re already inside a running app:
use ;
use oneshot;
let correlation_id = job.operation_id; // choose your own handle
let = channel;
register_commit_listener;
app.world_mut.write_message;
// hold `rx` to await the commit result in your orchestrator
Listeners are just oneshot senders keyed by a correlation ID. Each TriggerCommit should use a unique ID (you can reuse your job/operation ID) so the completion is routed to the right waiter. The plugin cleans up the entry when it sends the result.
Advanced configuration
use ;
let config = PersistencePluginConfig ;
app.add_plugins;
batching_enabled/commit_batch_size: control commit chunking and parallel execution.thread_count: Rayon pool size used for commit preparation.default_store: fallback store when queries/commits don’t override.store().
Scheduling notes
- Loads can run in
UpdateorPostUpdate. - Deferred world mutations from loads are applied before
PersistenceSystemSet::PreCommit. - Commit pipeline runs in
PersistenceSystemSet::Commit; readers that need fresh data should run afterPreCommit.
Error handling
All public APIs return Result<_, PersistenceError>. Version conflicts, connection issues, and timeouts surface through that error type so you can decide whether to retry, fail the job, or surface an error to callers.