A small Bevy utility crate that extends App with ergonomic helpers for observer-based event propagation — including schedule-based triggers, single-condition propagators, and multi-condition propagators.
Bevy's observer system is powerful, but common patterns — like "fire event B whenever event A fires", or "fire event C only after both event A and event B have fired" — require boilerplate. bevy_event_extras captures these patterns into a clean, chainable API directly on App.
| Helper | Description |
|---|---|
trigger_on |
Fire an event on a given schedule |
add_propagator |
Trigger a new event whenever a given event fires |
add_multicondition_propagator |
Trigger a new event only after a set of events have all fired |
use bevy::prelude::*;
use bevy_event_extras::*;
#[derive(Event)] struct AppStarted;
#[derive(Event)] struct AssetsReady;
#[derive(Event)] struct WorldReady;
#[derive(Event)] struct GameReady;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
// Fire AppStarted during PreStartup
.trigger_on(PreStartup, || AppStarted)
// Propagate AppStarted -> AssetsReady and WorldReady separately
.add_propagator(|_: On<AppStarted>| AssetsReady)
.add_propagator(|_: On<AppStarted>| WorldReady)
// Only fire GameReady once BOTH AssetsReady and WorldReady have fired
.add_multicondition_propagator(|conditions| {
conditions
.add::<AssetsReady>()
.add::<WorldReady>()
.then_call(GameReady)
})
.add_observer(|_: On<GameReady>| {
info!("Game is ready!");
})
.run();
}- Order sensitivity: Conditions use a
PreUpdatepolling system, so there is a one-frame delay between all conditions being met and the output event firing. - Reset behavior: After the output event is triggered, all condition flags are reset to
false. This makes multi-condition propagators suitable for recurring sequences.
MIT OR Apache-2.0