-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Explore how to make APIs play nicer with Plugins #5
Comments
The new App helper methods in 0.4 allow states to be used from plugins, so the most important use case is fixed. Leaving this issue open for future improvements. |
Hi, I'm interested in this! I make heavy use of plugins but cannot get my head around how to make use of the SystemStage for downstream plugins. What do you mean with "and just use functions that take &mut SystemStage (for whatever they need access to) instead."? |
@pinkponk I mean that, for the purposes of internal organization inside your project (this is very suboptimal if you are publishing a plugin crate), you could just do this: // instead of `impl Plugin` ...
pub fn add_enter_systems(stage: &mut SystemStage) {
stage.add_system(thing);
stage.add_system(thing2);
}
pub fn add_exit_systems(stage: &mut SystemStage) {
stage.add_system(cleanup);
}
pub fn add_fixed_timestep_systems(stage: &mut SystemStage) {
stage.add_system(fixed_thing);
}
pub fn add_general_systems(app: &mut App) {
// add other things
} and then: fn main() {
// ... set up other things ...
// add our things, using our helper functions
// (instead of `.add_plugin`)
module::add_general_systems(&mut app);
module::add_fixed_timestep_systems(&mut fixed_stage);
module::add_enter_systems(&mut state_enter_stage);
module::add_exit_systems(&mut state_exit_stage);
} Yes, it is super ugly. You are fragmenting all your setup, instead of having it all in one place, like with |
There is now also an extension trait for working with fixed timestep. |
I ended up doing having all the plugins only add certain systems and resources and then having a method for getting the stages I needed. I make heavy use of your fixedtimestep and add a bunch of stages under it so that my game can make use of fast forwarding. Had a problem with rapier when I did fast forwarding as rapier has its own fixedtimestep system so when I ran 10x speed what happend was that the rapier ran 5x then my systems 5x but now I only have a single fixedtimestep stage which gets its child stages from other plugins. pub struct WorldPlugin {
pub with_map: bool,
pub with_creatures: bool,
pub with_physics: bool,
} //Main time stage
let mut main_stage = FixedTimestepStage::from_stage(
Duration::from_millis((1000.0 / BASE_FPS) as u64),
SystemStage::parallel().with_system_set(
ConditionSet::new()
.run_in_state(GameState::Gaming)
.with_system(sync_game_speed)
.into(),
),
);
//Add map stage
if self.with_map {
app.add_plugin(MapPlugin);
main_stage.add_stage(MapPlugin::get_time_stage());
}
//Add creature stages
if self.with_creatures {
app.add_plugin(CreaturePlugin);
for stage in CreaturePlugin::get_stages() {
main_stage.add_stage(stage);
}
}
//Add physics stages
if self.with_physics {
app.add_plugin(
RapierPhysicsPlugin::<NoUserData>::default().with_default_system_setup(false),
);
main_stage.add_stage(
SystemStage::parallel().with_system_set(
RapierPhysicsPlugin::<NoUserData>::get_systems(PhysicsStages::SyncBackend),
),
);
main_stage.add_stage(
SystemStage::parallel().with_system_set(
RapierPhysicsPlugin::<NoUserData>::get_systems(PhysicsStages::StepSimulation),
),
);
main_stage.add_stage(
SystemStage::parallel().with_system_set(
RapierPhysicsPlugin::<NoUserData>::get_systems(PhysicsStages::Writeback),
),
);
// NOTE: we run sync_removals at the end of the frame, too, in order to make sure we don’t miss any `RemovedComponents`.
main_stage.add_stage(
//TODO run this outside in the correct stage?
SystemStage::parallel().with_system_set(
RapierPhysicsPlugin::<NoUserData>::get_systems(PhysicsStages::DetectDespawn),
),
);
}
app.add_stage_after(CoreStage::Update, GameStages::WorldTopStage, main_stage); |
Because of how our fixed timestep and states implementations rely on the user adding custom stages, that nest other stages, it is difficult to make this play nicely with Bevy's Plugin API.
If a plugin needs to add stuff to happen on state transitions, or on fixed timestep, it has no way of accessing the actual
SystemStage
s to add systems to. Labels don't help, because Bevy'sSystemLabel
s are a top-levelSchedule
thing, and cannot refer to nested stages.The only way right now seems to be to sidestep the Plugin API altogether, and just use functions that take
&mut SystemStage
(for whatever they need access to) instead.This might not be solvable while our stuff is in an external crate, and I cannot think of a better design. I'm open to ideas.
The text was updated successfully, but these errors were encountered: