bevy_malek_async
Runtime‑agnostic async ECS access for Bevy. Run async work on any executor (Tokio, Bevy task pools, or another runtime) and safely hop into Bevy’s world to read or mutate ECS state using normal SystemParams.
Features
- Runtime‑agnostic: use with Tokio, Bevy task pools, or any async executor
- Familiar ECS access: acquire
Res,ResMut,Query, and otherSystemParams - Persistent state across calls: reuse an
EcsTask<P>to preserveLocal,Changed, etc.
How It Works
Add AsyncEcsPlugin to your app. It installs lightweight systems across many schedules. When those systems run, they wake pending async tasks, temporarily expose world access, run your closure with the requested SystemParams, then apply commands/state and close access again.
Your async code creates an EcsTask<P> from a WorldId and calls run_system(schedule, |params| { ... }).await. The closure runs during the next access window for the chosen schedule.
Registered schedules include: PreStartup, Startup, PostStartup, PreUpdate, Update, PostUpdate, FixedPreUpdate, FixedUpdate, FixedPostUpdate, First, Last, FixedFirst, FixedLast.
Important Note: The systems that we run are actually more powerful than normal bevy systems. You can use mutable state from outside the closure inside of it unlike normal bevy systems.
Install
In your Cargo.toml:
[]
= "0.17"
= "0.2"
[]
# If you want to use the Tokio + HTTP example below
= { = "1", = ["full"] }
= { = "0.12", = false, = ["rustls-tls"] }
Quick Start (Tokio)
This example spawns a Tokio runtime on its own thread and mutates a Bevy resource from that async task using an EcsTask.
use *;
use WorldId;
use ;
;
Or run the included example:
Other Runtimes (Bevy task pools, async-std, smol, …)
EcsTask::run_system is just an async method. You can .await it on any executor. For example, Bevy’s IO pool:
use *;
use IoTaskPool; // or AsyncComputeTaskPool/ComputeTaskPool
use CreateEcsTask;
;
API Overview
-
AsyncEcsPlugin- Installs the wake/apply systems across common schedules (see list above).
-
WorldId::ecs_task::<P>() -> EcsTask<P>(viaCreateEcsTask)- Creates a reusable task token keyed to a specific
WorldIdandSystemParamsetP. - Reuse the same
EcsTask<P>to preserveLocal,Changed, and similar state across calls.
- Creates a reusable task token keyed to a specific
-
EcsTask<P>::run_system(schedule, |P| -> Out) -> impl Future<Output = Out>- Schedules your closure to run during the next access window for
schedule(e.g.Update). Pcan be anySystemParamor tuple (e.g.Res<T>,ResMut<T>,Query<...>, etc.).- Returns the closure’s output to your async context.
- Schedules your closure to run during the next access window for
Notes and Limitations
- Access happens during short windows inside Bevy schedules and does not run in parallel with other systems.