Giter Club home page Giter Club logo

bevy_proto's Introduction

GitHub Stats


๐Ÿ‘‹ ๐ŸŒŽ


Wakatime Stats Top Programming Languages

bevy_proto's People

Contributors

atbentley avatar b-reif avatar catthingy avatar chrisburnor avatar edouardpoitras avatar hafiidz avatar kaosat-dev avatar mrgvsv avatar wusticality avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

bevy_proto's Issues

Compability with bevy 0.12

I am currently using this package in my private project. I would like to upgrade my bevy dependency to 0.12 but this crate does not support it yet and I don't see any work done in that direction. Is there a timeline on when can we expect a new version?
I started some experiments with bringing bevy_proto to 0.12 on my own, but I'm not very familiar with parts of the engine that require changes.

[Feature Request] Templates

An excellent feature would be the ability to use some entities as 'templates':

---
name: "Template Enemy"
components:
  - type: Enemy

Then using the template would be like:

---
name: "Enemy 1"
template: "Template Enemy"
components:
  - type: Attack
    value:
      damage: 10
  - type: Armed
    value:
      weapons: [ "laser sword", "ray-blaster" ]
      primary: "laser sword"

The result would insert components from the template into the specific instance of it.

Question: Is it possible to use TextureAtlas?

I'm trying to use a spritesheet for one of the protos I'm working on and run into a sang with getting textureatlas

following this:
https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_sheet.rs
and trying to merge the ideas from this example:
https://github.com/MrGVSV/bevy_proto/blob/main/examples/bundles.rs

I created this code:

#[typetag::serde]
impl ProtoComponent for EnemySprite {
    fn insert_self(&self, commands: &mut ProtoCommands, _asset_server: &Res<AssetServer>) {
        // === Get Prepared Assets === //
        let texture: Handle<TextureAtlas> = commands
            .get_handle(self, &self.texture_path)
            .expect("Expected Image handle to have been created");

        // === Generate Bundle === //
        let my_bundle = SpriteSheetBundle  {
            texture_atlas:texture,
            ..default()
        };

        // === Insert Generated Bundle === //
        commands.insert(my_bundle);
    }

    fn prepare(&self, world: &mut World, prototype: &dyn Prototypical, data: &mut ProtoData) {
        // === Load Handles === //
        let asset_server = world.get_resource::<AssetServer>().unwrap();
        let handle:Handle<Image>=  asset_server.load(self.texture_path.as_str());
        let mut textureatlases = world.get_resource_mut::< Assets<TextureAtlas>>().unwrap();

        let textureatlas = TextureAtlas::from_grid(handle,Vec2 { x: 24.0, y: 24.0 },4,1,None,None);

        let texture_atlas_handle = textureatlases.add(textureatlas);

        println!("Built Textureatlas for {:?}",texture_atlas_handle);
        // === Save Handles === //
        data.insert_handle(prototype, self, texture_atlas_handle);
    }

However, get_handle fails as it expects id to be an AssetPathId

is there anything I can do or is this unsupported in bevy_proto?

Thanks.

Enquiry on better/proper way to despawn/remove entity with prototype

Hi, would like to check for a better practice in despawning and re-spawning an entity.
Scenario, I have Appstate:Game and Appstate:MainMenu transitioning between each other which require spawning and despawning and (re)-spawning again later. I had to create an additional entity existing check via if !is_spawned.value to ensure re-spawning happen when re-entering Game, which I think is not efficient. Would like to hear a better solution to force check if entity exist and if not respawning them. Option B, cheated a bit by only respawning descendants and leaving a non visible root entity when leaving Game state.

fn build(&self, app: &mut App) {
        app
            .add_system(load.in_schedule(OnEnter(AppState::GameInit)))
            .add_system(spawn.in_set(OnUpdate(AppState::Game)))
            .add_system(despawn.in_schedule(OnExit(AppState::Game)));
}

// == option A === //
fn spawn(mut commands: ProtoCommands) {
    commands.spawn("PlayerRoot");
}

pub fn despawn(mut commands: Commands, query: Query<Entity, With<PlayerRoot>>) {
    if let Ok(entity) = query.get_single() {
        commands.entity(entity).despawn_recursive();
    }
}


// ==== Option B ====//
fn spawn(
    mut commands: ProtoCommands,
    mut proto_entity: Local<Option<Entity>>,
    mut proto_asset_events: EventReader<ProtoAssetEvent>,
    mut is_spawned: ResMut<IsCardRootSpawned>,
) {
    let proto_entity = *proto_entity.get_or_insert_with(|| commands.spawn(PROTO_ID).id());

    // when the children has been de-spawned via despawn command, re-spawn
    // else re-spawn also when there is some changes to the assets (i.e. Root.prototype.ron)
    // this allows for spawn and despawn when transitioning from and to Main Menu
    if !is_spawned.value {
        commands.entity(proto_entity).insert(PROTO_ID);
        is_spawned.value = true;
    } else {
        for proto_asset_event in proto_asset_events.iter() {
            if proto_asset_event.is_modified(PROTO_ID) {
                commands.entity(proto_entity).insert(PROTO_ID);
            }
        }
    }
}

pub fn despawn(
    mut commands: Commands,
    query: Query<Entity, With<CardRoot>>,
    mut is_spawned: ResMut<IsCardRootSpawned>,
) {
    if let Ok(entity) = query.get_single() {
        commands.entity(entity).despawn_descendants();
        is_spawned.value = false;
    }
}

Allow Transform rotations to be defined in euler angles

Current Issue:

Rotations in transformations can only be defined using quaternions (Quat). While this is suitable for engine representation, it is less than ideal for human readability and ease of input.

Desired Solution:

Introduce a custom input type called ProtoTransform that utilizes an enum to specify the rotation type. This would be adopted by all existing custom implementations.

enum ProtoTransform {
    TranformWithQuaternionRotation {
        translation: Vec3,
        rotation: Quat,
        scale: Vec3,
    },
    TransformWithEulerXYZRotation {
        translation: Vec3,
        rotation: Vec3,
        scale: Vec3,
    },
}

String Vector schematic

I am trying to create a schematic that is able to read the prototype.ron files that contains vector/arrays of String, pseudocode below"

// in schematic.rs 
#[derive(Component, Default, Reflect, Debug, Clone)]
#[reflect(Schematic)]
pub struct Cardset {
    pub on_game: Vec<String>,
    pub on_deck: Vec<String>,
    pub on_hand: Vec<String>,
}

//ron file 
(
  name: "CardsetRoot",
  schematics: {
    "deck_proto::app::schematic::Cardset": (
        on_game: [],
        on_deck: [],
        on_hand: ["Card1", "Card2"],
   ),
  },
)

Tried a few different variation but often encountered errors, such as

WARN bevy_asset::asset_server: encountered an error while loading an asset: RON error in "schematics/cardset/CardsetRoot.prototype.ron": 5:14: no registration found for type alloc::vec::Vec<alloc::string::String>

Appreciate some advice on the right direction I need to explore further ya. Not sure where to refer.

Error in adding child in custom schematics

I am using custom schematics to add player sprite and some text to the window.
Not sure exactly what is the root problem, but after a few changes including migrating from bevy_proto 0.11 release to latest github version, I couldn't get the add child text working. The screenshot demonstrating the child text appearance in old build vs new.

Old build:
Screenshot 2023-10-18 091719

New build:
image

impl Schematic for PlayerSpriteSheet {
    // Applying `EnemyInput` type
    type Input = PlayerSpriteSheet;

    fn apply(input: &Self::Input, _id: SchematicId, context: &mut SchematicContext) {

       //skipped some section to load atlas & transform

        context.entity_mut().unwrap().insert((
            SpriteSheetBundle {
                texture_atlas: texture_atlas_handle,
                sprite: TextureAtlasSprite::new(input.sprite.animation.first),
                transform,
                ..default()
            },
            input.sprite.animation,
            AnimationTimer(Timer::from_seconds(
                input.sprite.animation.duration,
                TimerMode::Repeating,
            )),
            PlayerSprite,
        ));

        // Insert the Defend Text within the 2d world (i.e. not using node UI)

        let text = "Defend: 1".to_string();

        let defend_text = context
            .world_mut()
            .spawn((
                Text2dBundle {
                    text: Text::from_section(
                        // Accepts a String or any type that converts into a String, such as &str.
                        text,
                        TextStyle {
                            font_size: 200.0,
                            color: Color::RED,
                            ..default()
                        },
                    ),
                    visibility: Visibility::Visible,
                    ..Default::default()
                },
                PlayerDefendUIText,
            ))
            .id();

        // add health bar & text child entity to Enemy
        context.entity_mut().unwrap().add_child(defend_text);
    }

    // skipped 
    // fn remove()
    // fn preload_dependencies()

I have a debug system/function to print all entity to console, and when I do that, the child entity exist. Not sure what else can be done to diagnose this new behavior further.

[src\state\mod.rs:255] entity = 26v0
        Component: bevy_transform::components::transform::Transform
        Component: bevy_transform::components::global_transform::GlobalTransform
        Component: bevy_hierarchy::components::parent::Parent
        Component: bevy_render::view::visibility::ComputedVisibility
        Component: bevy_text::text::Text
        Component: deck_proto::app::schematic::player::PlayerDefendUIText
        Component: bevy_render::view::visibility::Visibility
        Component: bevy_text::text2d::Text2dBounds
        Component: bevy_text::pipeline::TextLayoutInfo
        Component: bevy_sprite::sprite::Anchor

Properly handle nested schematics

Currently nested schematics are really restrictive.

// works
#[derive(Component, Reflect, Schematic)]
#[reflect(Schematic)]
pub struct Foo {
    bars: Vec<Bar>,
}

#[derive(Component, Reflect, Schematic)]
#[reflect(Schematic)]
pub struct Bar {
    duration: f32,
}
// does not work
#[derive(Reflect)]
pub struct DurationInput(f32);

impl From<DurationInput> for Duration {
    fn from(value: DurationInput) -> Self {
        Duration::from_secs_f32(value.0)
    }
}

#[derive(Component, Reflect, Schematic)]
#[reflect(Schematic)]
pub struct Foo {
    bars: Vec<Bar>,
}

#[derive(Reflect, Schematic)]
#[reflect(Schematic)]
pub struct Bar {
    #[schematic(from = DurationInput)]
    duration: Duration,
    #[schematic(asset)]
    handle: Handle<Baz>,
}

While the first example works, as soon as you add more complex types to Bar such as a Handle or Duration like in the second example, serialization will fail because the #[schematic] attributes are not respected. Another issue is that Bar has to derive Component, which might not make sense in a context where it is only used inside of Foo and not as a component itself.

bevy_proto_backend is pulling in every bevy feature

I added

[dependencies.bevy_proto]
version = "0.9.0"
default-features = false
features = []

to my Cargo.toml and noticed it added a bunch of Bevy features I wasn't using (audio, gltf, etc). I think the root cause is that bevy_proto_backend has all the optional stuff in its default features, and bevy_proto doesn't disable default features.

Since it's a backend crate, maybe it makes sense to just not have any default features?

`AssetSchematic`: Defining assets inline

Objective

Allow assets to be defined within a prototype file rather than outside of it, using a Schematic-like approach.

While this probably won't be useful for large assets or those that make no sense in a text-based format, it should be great for assets defined in code.

For example, we should be able to define a prototype like:

(
  name: "Sphere",
  schematics: {
    "bevy_proto::custom::MaterialMeshBundle<bevy_pbr::pbr_material::StandardMaterial>": (
      mesh: Asset(UvSphere((
        radius: 1.0,
      ))),
      material: Asset((
        base_color: Green,
      )),
    )
  }
)

In the example above, we define a a prototype, Sphere, which contains a schematic for the MaterialMeshBundle<StandardMaterial> (aka a PbrBundle). This schematic contains the definitions for two assets that are normally defined in code:

  1. We create a primitive UvSphere mesh
  2. We create a StandardMaterial with a given color

This is powerful because it means users can play around with an asset's values without needing to rebuild the entire application.

Implementation

This should be powered by a new trait: AssetSchematic.

The AssetSchematic trait should work very similar to a normal Schematic. It should be derivable (for Asset types) and have convenient attributes for handling common scenarios.

It should also support defining an AssetSchematic to build an asset not owned by the user. The intention here is that users should be able to define their own schemas for Bevy-owned assets (e.g. adding their own primitive shapes for a Mesh asset).

Lastly, an AssetSchematic should properly handle overwriting itself. This is important because it means that existing references to the asset will automatically receive the changes. This is consistent with regular Bevy assets: there cannot be two versions of an asset referred to by the same path/handle. However, this feature should be optional (though, on by default) and configurable via an attribute in the derive macro.

Considerations

While I haven't really looked at the changes proposed in bevyengine/bevy#8624, I understand that it might change how a feature like AssetSchematic works. In fact, there's a possibility that it breaks it completely.

However, that work is still in draft mode and I'm unsure of when it is planned to actually be released. So for the time being, I plan on proceeding with this feature, along with the understanding that it may require refactoring/removal down the line.

Smart-forward `reflect` attributes

The Problem

Currently, reflect attributes are forwarded 1:1 from fields on a schematic to fields on a generated input type.

This may not always be desired. For example:

#[derive(Component, Reflect, Schematic)]
struct MyStruct {
  #[reflect(default)]
  #[schematic(from = MyInteger)]
  foo: i32,
}

#[derive(Reflect)]
struct MyInteger(i32);
impl From<MyInteger> for i32 {/* ... */}

The above code ends up generating the following input type:

// GENERATED
#[derive(::bevy::reflect::Reflect)]
struct MyStructInput {
  #[reflect(default)]
  foo: MyInteger,
}

But this results in a compile error due to MyInteger not implementing Default.

The Solution

While it would make things a bit more verbose, we could add a new attribute, #[schematic(reflect(...))], that makes forwarding reflection attributes explicit. This could also be used to pass certain reflection attributes to the generated input container rather than just its fields.

One way to assuage this added verbosity would be to only require this attribute on fields that define some custom schematic functionality. Fields that don't use any #[schematic] attribute are meant to map 1:1 with the input field type. For example:

#[derive(Component, Reflect, Schematic)]
struct MyStruct {
  #[reflect(default)]
  #[schematic(from = MyInteger)]
  #[schematic(reflect(default))] // <-- Needed
  foo: i32,
  #[reflect(default)] // <-- Not needed
  bar: i32,
}

The issue with doing this is that it feels a little implicit and confusing, so it might not even be worth it.

It might be good just to start with the more verbose approach so we can get this working properly, and then reassess how/if we make it better.

Unstable/inconsistent bevy_proto_backend::registration::systems: could not register prototype

It is me again, TT_TT. Currently working alone on this hobby dev, really appreciate the helps.

ERROR bevy_proto_backend::registration::systems: could not register prototype: the prototype with handle HandleUntyped { id: AssetPathId(AssetPathId(SourcePathId(12790493230470399281), LabelId(8823233378563626002))), handle_type: Weak } either doesn't exist or isn't fully loaded

Hi, I have encountered the above error quite a few time, especially after a code change and rebuild (when running cargo run after code change). When I run the second (or sometime need 3rd) time without any code changes, this error went away until I made another code change and rebuild. The error seems to indicate relation to the way the prototype is loaded, but I don't know which asset is not set properly.

Question 1
This may happen again at a different stage of my game, but again, it is not consistent enough for me to know which prototype is causing this. Is there a way for us to identify what the PathID and SourceID refers to?

Not sure if relevant, but I often try to make the loading happen during AppState::Init then spawn during AppState::Game or similar steps. Use prototype.is_ready as auto state change trigger from Init to Game.

Question 2
Is there a built in prototype.is_all_ready or similar or do I need to manually code in for each prototype ya? I am afraid that I may at time forget to include the loading check when adding new type of assets.

Question: How to spawn a simple cube

Bevy provides simple shapes to whitebox a level or to create simple gameplay prototypes.

Ideally I would like to use bevy_proto to define the locations and shapes for faster iterations, especially for colliders for rapier etc., but when I try to get the handle of the created mesh, it panicks.

Here is what I tried to do:

#[derive(Serialize, Deserialize)]
pub struct ShapeDef {
    pub size: f32,
    pub color: Color,
    pub position: Vec3,
    #[serde(skip)]
    pub mesh_handle:  RwLock<Option<Handle<Mesh>>>,
    #[serde(skip)]
    pub material_handle: RwLock<Option<Handle<StandardMaterial>>>,
}
#[typetag::serde]
impl ProtoComponent for ShapeDef {
    fn insert_self(&self, commands: &mut ProtoCommands, asset_server: &Res<AssetServer>) {

        let mesh_handle_id = self.mesh_handle.read().unwrap().as_ref().unwrap().id();
        let mesh_handle = commands.get_handle(self, mesh_handle_id).expect("mesh handle");
        let material_id = self.material_handle.read().unwrap().as_ref().unwrap().id();
        let material_handle = commands.get_handle(self, material_id).expect("material handle");
        commands.insert(PbrBundle {
            mesh: mesh_handle,
            material: material_handle,
            transform: Transform::from_xyz(self.position.x, self.position.y, self.position.z),
            ..default()
        });
    }

    fn prepare(&self, world: &mut World, prototype: &dyn Prototypical, data: &mut ProtoData) {
        let mut meshes = world.get_resource_mut::<Assets<Mesh>>().unwrap();

        let mesh_handle = meshes.add(Mesh::from(shape::Cube { size: self.size }));
        let mut materials = world.get_resource_mut::<Assets<StandardMaterial>>().unwrap();
        let material_handle = materials.add(Color::rgb(0.3, 0.5, 0.3).into());
        *self.mesh_handle.write().unwrap() = Some(mesh_handle);
        *self.material_handle.write().unwrap() = Some(material_handle);
    }
}

The panic happens when I try to extract the mesh_handle from the commands_get_handle().

How exactly can I pass the Handle<Mesh> from the prepare invocation to the insert_self.

Entity is empty when spawning from a SystemState

I use bevy_mod_script to get Scripting working with my project.
I have a function that can be called by scripts, that takes the World and a String as a Parameter, goal of the function is to simply spawn a prototype.
As I only have access to the World, I somehow have to get ProtoCommands:

let mut system_state: SystemState<ProtoCommands> = SystemState::new(&mut world);

and with that I can then spawn a Prototype, so the whole system looks like this:

pub(crate) fn spawn_mod(world: &mut ScriptWorld, mod_name: ImmutableString) -> Dynamic {
    let mut world = world.write();

    let mut system_state: SystemState<ProtoCommands> = SystemState::new(&mut world);
    let mut proto_commands = system_state.get_mut(&mut world);
    let spawned_mod = proto_commands.spawn(mod_name.as_str()).id();

    Dynamic::from(spawned_mod)
}

It does spawn an entity, but it stays empty.
image

It's my first time working with SystemState, so maybe I misunderstand something.

Bevy `Resource` schematics

Similar to #33, schematics should be added for most Bevy Resources (where appropriate anyways).

This will allow users to use resources directly in prototypes without needing to create a custom schematic.

Unwrap error when using ButtonBundle

Hi, I am encountering consistent crash & couldn't get the button text to show up when I tried to enter a simple ButtonBundle. I have tested when removing the ButtonBundle, the rest of the MenuPlay.prototype.ron is working fine. It seems to be happening during state transition, i.e. when moving away for the spawned menu (i.e. despawning).

(
  name: "MenuPlay",
  schematics: {
    "bevy_proto::custom::NodeBundle": (
      style: (
        flex_direction: Row,
        justify_content: SpaceAround,
        align_items: Center,
        size: (
          width: Auto,
          height: Px(64.0),
        ),
      ),
      background_color: (Rgba(
        red: 0.5,
        green: 0.15,
        blue: 0.15,
        alpha: 1.0
      )),
    )
  },
  children: [(
        value: Inline((
          name: "Play Button",
          schematics: {
            "bevy_proto::custom::ButtonBundle": (
              style: (
                size: (
                  width: Px(64.0),
                  height: Px(32.0),
                ),
              ),
            ),
          },
          children: [(
            value: Inline((
              name: "Play Text",
              schematics: {
                "bevy_proto::custom::TextBundle": (
                  text: (
                    sections: [(
                      // Label for Play Button
                      value: "Play",
                      style: (
                        font: AssetPath("fonts/FiraSans-Bold.ttf"),
                        font_size: 15.0,
                        color: White,
                      )
                    )]
                  ),
                ),
              }
            ))
          )]
        ))
      ),
  ]
)
thread 'Compute Task Pool (5)' panicked at 'called `Option::unwrap()` on a `None` value', C:\Users\hafiidz\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ui-0.10.1\src\render\mod.rs:608:70
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'Compute Task Pool (5)' panicked at 'A system has panicked so the executor cannot continue.: RecvError', C:\Users\hafiidz\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.10.1\src\schedule\executor\multi_threaded.rs:194:60
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', C:\Users\hafiidz\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_tasks-0.10.1\src\task_pool.rs:376:49
thread 'Compute Task Pool (5)' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', C:\Users\hafiidz\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_render-0.10.1\src\pipelined_rendering.rs:136:45
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', C:\Users\hafiidz\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_tasks-0.10.1\src\task_pool.rs:376:49
error: process didn't exit successfully: `target\debug\deck_proto.exe` (exit code: 101)

Not sure what else do I need to provide here to help diagnose the problem.

Allow `ProtoData` to store handles without paths

Currently the ProtoData struct requires a path when insert a handle:

    pub fn insert_handle<T: Asset>(
        &mut self,
        protoytpe: &dyn Prototypical,
        component: &dyn ProtoComponent,
        path: &HandlePath,
        handle: Handle<T>,
    ) {}

This poses a problem when inserting handles that don't correspond 1:1 with an asset path.

For instance, when loading an Aseprite file with bevy_ase, one .aseprite file path corresponds to many different handles (each frame has its own Image handle, other metadata handles are inserted, etc.)

As far as I can tell, ProtoData only uses this path as a key in its map. Fortunately for us, Handle already exposes HandleId, which implements Hash and uniquely identifies the Handle. We can fix this problem and simplify our API by keying on HandleId instead of a HandlePath.

Additional Formats Support

A few additional file formats for the prototypes would be helpful. In particular Ron and Toml support would be a nice extension to Yaml and Json and are supported by existing libraries.

Access to world in on_load_prototype?

Hi, I have following scenario.
I'm working on adding mod support to my game, and I want to be able to define Mods via .ron files that then are interpreted by the game into entities. And with this crate that works great!
I encountered one problem though, I want the user to have control over when the mod will be spawned. For example, a UI Manager that will be spawned once the MainMenu is ready.

For this I've created an Enum that defines in what schedule it should be spawned. The only problem, for this to work, I need to register the name of the Prototype in a Bevy resource.
But in the on_load_prototype of a custom loader, as far as I can see, i don't have any way to do so?

   fn on_load_prototype(
        &self,
        mut prototype: Prototype,
        meta: &bevy_proto::backend::load::ProtoLoadMeta<Prototype>,
    ) -> Result<Prototype, Self::Error> {
        // Register for spawn on schedule, if any.
       // Getting the input, works great!
        if let Some(spawn_on_schedule) = prototype.schematics().get::<SpawnOnSchedule>() {
            let spawn_on_schedule = spawn_on_schedule
                .input()
                .downcast_ref::<SpawnOnSchedule>()
                .unwrap();

            // somehow get access to the world
            let mut world meta.world_mut();
            world.resource_scope(|world, mods_to_spawn_resource|{
                // add to the resource
            });
        }

        Ok(prototype)
    }

Something like that, is there maybe a possible workaround?

Question: how to deal with optional fields of a component?

I'm trying to use a couple of components:

#[derive(Component, Schematic, Reflect)]
#[reflect(Schematic)]
pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

#[derive(Component, Schematic, Reflect)]
#[reflect(Schematic)]
pub struct MovementDirection {
    pub x_axis: Option<Direction>,
    pub y_axis: Option<Direction>,
}

but I get an error from proto no registration found for type core::option::Option<expeditions::core::controls::components::Direction> when I try to spawn a player that has MovementDirection. How can I use a component with another component that is optional? It is working with standard types like String, but not with my components.

Bevy 0.6

Creating an issue for this because it's going to require some discussion rather than a simple fix.

Bevy 0.6 changes Component from:

pub trait Component: Send + Sync + 'static;

to

pub trait Component: Send + Sync + 'static {
       type Storage: ComponentStorage;
}

This breaks the implementation of ProtoComponent which must extend Component, which now has a trait type. This has all sorts of downstream implications in the code base.

I can see three possible (non-exclusive) paths forward:

  1. Simply move forward as-is and see if it is possible to update the types.
  2. Change ProtoComponent to not be bound to Component and create some sort of shim type to convert.
  3. Use Bevy Reflect (somehow) to work around the problem.

Enquiry on simpler custom_loader

Is there a way we could do a simple edit of the ron files on the fly without resorting to a full custom loader, especially since this is only planned for some portion of the ron files (i.e. have many different ron file types)?

More detailed use case, wanted to use on_fight vectors from Enemyset to replace children list in EnemyRoot before prototype.load, i.e. the on_flight, might be changed programmatically (on_fight1, on_fight2), or might be a vector of vectors such as in on_fight_alternative

// EnemyRoot.prototype.ron
(
  name: "EnemyRoot",
  schematics: {
    "deck_proto::game::enemy::EnemyRoot": (),
  },
  children: ["EnemySprite", "EnemySprite2"]
)

// EnemysetRoot.prototype.ron
(
  name: "EnemysetRoot",
  schematics: {
    "deck_proto::game::enemy::enemyset::EnemysetRoot": (),
    "deck_proto::app::schematic::Enemyset": (
      // UNIQUE list of enemy that is available in the game
      // TODO, use this list as card list to be loaded during GameState::Init 
      on_fight1: ["EnemySprite", "EnemySprite", "EnemySprite2"],
      on_fight2:  ["EnemySprite2", "EnemySprite", "EnemySprite2"],
      on_fight_alternative:  [["EnemySprite2", "EnemySprite"], ["EnemySprite2"]],

    ),
  }
)

If there is no other choices but to use custom loader, how can I specify custom loader only for a certain portion of the ron file ya? The example .add_plugins(ProtoPlugin::new_with_loader(MyLoader)) will apply custom loader to all files, right? Or it will add this custom loader on top of existing loader?

Alternatively, I might just perform a simple read-write operation via std::fs on the actual ron file on the disk prior to load, hopefully this is not too time consuming ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.