mrgvsv / bevy_proto Goto Github PK
View Code? Open in Web Editor NEWCreate config files for entities in Bevy
License: Other
Create config files for entities in Bevy
License: Other
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.
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.
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.
I didn't find an example. I want to make a predefined door structure consisting of a parent (DoorProto, looks like a doorframe) and the door itself, which is a child of DoorProto. Both parent and child have their own gltf meshes. Also it is required to predefine entity in DoorProto on a door.
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;
}
}
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.
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,
},
}
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.
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.
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
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.
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?
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:
UvSphere
meshStandardMaterial
with a given colorThis is powerful because it means users can play around with an asset's values without needing to rebuild the entire application.
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.
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.
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
.
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.
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.
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
.
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.
It's my first time working with SystemState, so maybe I misunderstand something.
Similar to #33, schematics should be added for most Bevy Resource
s (where appropriate anyways).
This will allow users to use resources directly in prototypes without needing to create a custom schematic.
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.
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
.
Hello. I found a plugin here for exporting to JSON from Blender https://github.com/Hairein/MKS_BlenderToolScripts
It would be cool if we could import it.
Blender has wonderful plugins like https://blendermarket.com/products/asset-sketcher
which would be very helpful in the development of the game.
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.
That being said, I think ProtoEntityCommands
might benefit from despawn
and despawn_recursive
methods. These could then remove and despawn/recursively despawn the given entity.
Originally posted by @MrGVSV in #49 (reply in thread)
The ProtoCommands::remove
method is using the wrong command:
bevy_proto/bevy_proto_backend/src/proto/commands.rs
Lines 60 to 62 in 37a72d7
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?
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.
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:
ProtoComponent
to not be bound to Component
and create some sort of shim type to convert.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 ...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.