Skip to content

New API for my project yunfengzh_monolith #19197

@yunfengzh

Description

@yunfengzh

Monolith Overview, https://crates.io/crates/yunfengzh_monolith

I'm glad to introduce my project -- monolith which is a framework based on tokio and bevy. Later
pseudo-code gives an overview:

async sprite::run() {
    sprite_in_village();
    ...
    sprite_enter_dungeon();
    loop {
        match evt = from_bevy().await {
            GameEvent::MoveLeft => {
                self.pos.translation.x -= 1.0;
                to_bevy().send(Task::SyncEntity, self.entity, self.pos);
            }
            ...
        }
    }
    ...
}
  1. Sprite::run should be based on sprite state machine rather than being split to fit with ECS.
  2. Sprite::run hardcodes GameEvent (logic event).
  3. Monolith treats bevy as a display and event-dispatched library -- from_bevy and to_bevy.
  4. Monolith supports tokio, that is, you can run time-cost algorithm in coroutine context.

Unfortunately, I face some problem during the monolith, I hope bevy team to support.

Accelerate to_bevy().send

Currently, to_bevy().send is mainly

fn exclusive_system(world: &mut World) {
    ...
    world.run_system_once_with(task.user_defined_system, task.param);
    ...
}

Since world.run_system_once_with run sequentially, so it's low performance.

Rare System

Some system is rare system such as NewEntity, I hope later API

let cmdqueue = App::get_commands(); // New API
cmdqueue.run_system_cached_with(mysystem, param);

The reason is exclusive_system runs every Update schedule, it's totally unnecessary.

Frequent System

Some system is frequent system such as SyncEntity, I hope later API

#[derive(Event)]
struct ToBevyTask(...);

let ew = App::get_event_writer<ToBevyTask>(); // New API, get EventWriter from bevy.

app.add_systems(Update, user_defined_system.run_if(on_event::<ToBevyTask>()));

Event Dispatch System, from_bevy()

To get keyboard event from bevy, currently later system is used

fn keyboard_system(er: EventReader<KeyboardInput>) {
    ....
}

I hope later API so I can deal with events in coroutine rather than bevy system.

let er = App::get_event_reader<ToBevyTask>(); // New API, get EventReader from bevy.
er.receive().await; // er should be tokio channel.

ECS crate

ECS which bring an innovation idea that split the fields of a struct into components. Put all
components close to each other to improve cache hit rate. But it can be done manually in tokio.

  1. Sprite { ... } -> SpritePos -> Vec<SpritePos>.
  2. run algorithm in coroutine.
  3. Optionally, update original objects.

Here, I hope ECS crate can be public. So ECS component can be used in mygame.

#[derive(component)]
struct MapUnit{ ... };

get_base_address() -> *mut MapUnit
get_entity(*const MapUnit) -> Entity
get_entity_by_offset(Entity, map_width) -> Entity

And to fit with function paradigm, I need sum up multiple results to target component.

let target = ECS::get_component(index);
let a_mut_copy = target.get_mut_clone();
// above line can be run several times, so multiple coroutine can be executed in parallel
sum_up(iterator_of_mut_clones(target), target);

Put my project to https://bevyengine.org/assets/

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-FeatureA new feature, making something new possibleS-Needs-TriageThis issue needs to be labelled

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions