Base structure
The very first step in the port is plugging Bevy's ECS. The source project has a mixed, game engine-wise, design:
- the game loop is managed by the game engine (bracket-lib);
- for each cycle (frame), an update is invoked on the ECS (Legion).
This is bare-bones structure of the source project:
// source: main.rs
struct State {
ecs: World,
resources: Resources,
systems: Schedule,
}
impl State {
fn new() -> Self {
// [...]
Self {
ecs: World::default(),
resources: Resources::default(),
systems: build_scheduler(),
}
}
}
impl GameState for State {
fn tick(&mut self, ctx: &mut BTerm) {
// [...]
self.systems.execute(&mut self.ecs, &mut self.resources);
render_draw_buffer(ctx).expect("Render error");
}
}
fn main() -> BError {
// [...]
main_loop(context, State::new())
}
The translation is straightforward:
World
andResources
map toApp
(which also owns the resources)- Legion's systems update for each tick maps to the
App#update()
API.
leading to:
// port: main.rs
struct State {
ecs: App,
}
impl State {
fn new() -> Self {
// [...]
Self { ecs: App::new() }
}
}
impl GameState for State {
fn tick(&mut self, ctx: &mut BTerm) {
// [...]
self.ecs.update();
render_draw_buffer(ctx).expect("Render error");
}
}