#bevy_asset_loader
1232 messages ยท Page 2 of 2 (latest)
why would server need the terrain asset?
yeah I'll do it manually for each component if needed, but it would be less nice and more code than being able to just replicate the thing
Just make the client app load terrain
so that it will be replicated to the client, and the client doesn't have to spawn it manually
one system to spawn a tile on the server, instead of another one on the client to add the sprite to tile without it
thanks ill do that if the first doesn't work
Is this a good place to ask about bevy_common_assets? (specifically ron?)
My original problem: I'm making a Tower Defense game, I want a way to cycle through towers.
Before using the asset loader plugin, I had defined a enum of towers just as unit structs, now I'm expanding that to have damage, attack speed, etc. I figured ron was the perfect solution to this. Since I want a default tower, I opted to keep the enum as was, but instead try something like: RonAssetPlugin::HashMap::<TowerOptions, TowerDetails>. However that's throwing an error ambiguous associated type. So I'm thinking this is an x/y problem. Is there a bevy way to solve this problem?
Oh, if I change it to RonAssetPlugin::<HashMap::<TowerOptions, TowerDetails>> then it is happier, but I still feel like I'm doing the wrong solution
This seems fine to me. If this works I would say go for it. You can always iterate on a working solution if you find issues with it ๐
I think the idea is working. However, now I have another issue, each tower has it's own glb file. Any patterns for dealing with that? I appreciate it's not really an asset loader issue at this point
It might be an asset loader question afterall. Looking at using Loading States, if I have my own custom asset loader, is it possible to still use loading states? If so, are there any docs (this feels like an rtfm question - if so apologies)
Hang about, think I found it. custom_dynamic_assets? Further down I found this, thanks for being amazing rubber ducks!
@hushed wind Is there a way to load a entire folder without needing to say it is full path
There is multiple ways to load multiple assets like a full folder, see e.g. https://github.com/NiklasEi/bevy_asset_loader?tab=readme-ov-file#collections
What do you mean by "needing to say it is full path"?
now that i am using a git submodule for assets , there is a .git file in there so i get this error
2024-09-30T18:10:48.968300Z ERROR bevy_asset::server: Failed to load folder. Could not find an asset loader matching: Loader Name: None; Asset Type: None; Extension: None; Path: Some("doodad_manifests/.git");
what can i do? can i tell bevy asset loader to NOT try and load the .git file ?
what a silly issue
personally i preload all assets one by one (assetloader.load()) for each one
since i have them sorted in designated folders inside the assets folder (models for glb, images for png.. etc.)
Out of interest does making a .git extension noop asset loader work to get you out of trouble?
That probably would. Okay but aanyways i think i have a better soln overall
1 ) how can i specify an additional custom asset folder while simultaneously using the normal asset folder ? AND use both for this crate
Like could i specify an extra source and then have this crate use it ? https://github.com/bevyengine/bevy/blob/main/examples/asset/extra_source.rs
ok i figured it out
Okay yes you can close this I got it all working !!
For anyone else, what I did was i made a separate repo to hold my game assets and that is a private repo. Each time my editor loads up, I copy the files from that external repo into a local .gitignored folder ("artifacts") . It is adjacent to /assets, not inside of it .
I also configure the artifacts folder as an 'extra source' like the example.
Then when i use bevy_asset_loader, i can set my path to point at stuff in that 'artifacts' folder by using "../artifacts/game_assets/ ...."
So now my game assets are totally separate from my editor assets; they have a private git repo while my editor uses a public repo . Not only that, but when my game (yet another separate repo) boots up, it ALSO copies files from that private game_assets repo into its /assets. So it acts like a private shared asset database. The downside here is that my HDD is a bit more taxed since all assets are copied 3 times.. but oh well. At least it is like auto-backups xD
hello ! we can't use a const as asset(path = TEXTURE) ?
const TEST: &str = "test";
#[derive(Resource, AssetCollection)]
pub struct GameAssets {
#[asset(path = TEST)]
pub texture: Handle<Image>,
}
``` the macro says `Wrong attribute type. Expected 'str'`
path = stringify!(test) doesn't work too
oh because its being changed into a &str AFTER the AssetCollection macro run
i would like do to something like this (inside a macro)
#[derive(Resource, AssetCollection, Reflect)]
pub struct CardsAssets {
$(
#[asset(path = stringify!($module.png))]
pub [<$module>]: Handle<Image>,
#[asset(path = stringify!([<$module _enemy>].png))]
pub [<$module _enemy>]: Handle<Image>,
)*
}
in the mean time of finding a solution i changed the proc derive macro code (first time touching a proc macro lol)
and i use it like this:
#[derive(Resource, AssetCollection, Reflect)]
pub struct CardsAssets {
$(
#[asset(path = ["cards/", $module, ".png"])]
pub [<$module>]: Handle<Image>,
#[asset(path = ["cards/", $module, "_enemy.png"])]
pub [<$module _enemy>]: Handle<Image>,
#[asset(path = ["cards/", $module, "_pawn.png"])]
pub [<$module _pawn>]: Handle<Image>,
#[asset(path = ["cards/", $module, "_pawn_enemy.png"])]
pub [<$module _pawn_enemy>]: Handle<Image>,
)*
}
Somehow I remember that there was some limitations with consts in derive attributes, but I cannot find the relevant Rust issues right now. There sure is some way to support variables in those places (like serde does for default values).
I don't think I want to support that in the crate. But as you already did for yourself now: one could implement that separately.
yup im sure that's not optimal solution, it was just in the mean time what i needed.
do you see a better way of doing this ? either one user space or a feature we can easily add to the derive macro ?
thanks for the answer
@hushed wind https://github.com/NiklasEi/bevy_asset_loader/issues/215#issuecomment-2119010105 was an issue about essentially being able to load an asset as load_with_settings. It was closed as โnot supportedโ. Iโm just wondering if you have any sense for whether it would be something feasible for the crate to support? Would there be a generic enough way to provide the settings object as part of the existing macros?
The use case is: two different parts of the game load the same asset (do cannot use meta files). The asset itself has some embedded paths to other assets and those should only be loaded in one part of the game (because they are not needed in the other part and loading them in both would be a waste).
I closed the issue because configuring the UV address mode is now supported. But you are right, there is no general solution for loading with settings.
I don't know if that could fit into the macros. Feel free to open a new issue for general settings support.
I have some early ideas to start using observers to simplify the plugin. That might open some possibilities, but not sure yet.
OK will do, thanks! Currently confirmed DynamicAsset trait lets me call load_with_settings. So it's possible there's a workaround here even if it may require an extra layer of wrapping. Edit: This is probably not what I want. Edit 2: Actually, it works well enough for part of my use case but isn't as ergonomic as being able to use a macro.
I'll make an issue though.
Issue opened as I'm sure you'll see: https://github.com/NiklasEi/bevy_asset_loader/issues/243
Any bevy_asset_loader users who want to comment on https://github.com/NiklasEi/bevy_asset_loader/issues/244 to share any thoughts/experience on a better name for LoadingState::init_resource, take a look at the issue.
has anyone tried 0.21 (latest) on 0.15 yet? Does it work?
So far there is only an RC in preparation of Bevy 0.15: https://crates.io/crates/bevy_asset_loader/0.22.0-rc.1
Everything is prepared for publishing version 0.22, I am just waiting for a dependency to publish a new version.
The new version is published ๐ฅณ
https://bsky.app/profile/nikl.me/post/3lcbj2ey4bk23
Is there a way to use dynamic assets at runtime? I'm developing a map system where each map is referring to its neighboring maps, and instead of having to hard-code a
#[derive(AssetCollection, Resource)]
struct MapAssets {
#[asset(key = "maps.map_1")]
map_1: Handle<TiledMap>,
// etc.
}
for every possible map, I'd like to be able to grab a Handle<TiledMap> from the asset key maps.map_1 at runtime. You can assume I've done
.with_dynamic_assets_file::<StandardDynamicAssetCollection>(
"maps.assets.ron",
)
with entries like
({
"maps.map_1": File (
path: "maps/map_1.tmx",
),
})
and that I'm getting the asset keys for neighboring maps from the map files themselves. I tried doing this, but it's not valid:
let map_key = format!("maps.{}", current_map.0);
let asset = dynamic_assets.get_asset(&map_key).unwrap();
let map_handle = asset.load(&asset_server).into_iter().next().unwrap();
let map_handle = map_handle.typed::<TiledMap>();
The typed call fails with
The target Handle<bevy_ecs_tiled::asset::TiledMap>'s TypeId does not match the TypeId of this UntypedHandle
and I'm at a loss for where to go from there. I noticed that the code generated by the AssetCollection macro also calls asset.build(&mut world) at some point, but it's incredibly inconvenient to have to use an exclusive system that involves the whole World here.
Never mind. I think I figured it out.
I ended up doing the following to perform runtime loading of a dynamic asset:
let asset = dynamic_assets.get_asset(&key)?;
asset
.load(asset_server)
.into_iter()
.next()?
.try_typed::<LoadedUntypedAsset>()
.ok()
where key is the same as you'd use for #[asset(key)] in an AssetCollection, This gives you a Handle<LoadedUntypedAsset>. Store this somewhere, and in the system you want to use the asset, request Res<Assets<LoadedUntypedAsset>> and, using the handle from earlier, do loaded_untyped_assets.get(handle), which gives you an Option<LoadedUntypedAsset> that is Some when the asset is loaded. At that point, you can access theLoadedUntypedAsset's field handle which holds the handle to the actual asset you want. At that point, you can do foo.handle.clone().typed::<AssetType>() and you've got your runtime-loaded dynamic asset.
Hello! I have this plugin that loads asset collections in LoadingStates:
pub(crate) struct ThetawaveAssetsPlugin;
impl Plugin for ThetawaveAssetsPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_plugins((
EmbeddedAssetPlugin {
mode: PluginMode::ReplaceDefault, //embeds assets into binary
},
ProgressPlugin::<AppState>::new()
.with_state_transition(AppState::MainMenuLoading, AppState::MainMenu)
.with_state_transition(AppState::GameLoading, AppState::Game),
FrameTimeDiagnosticsPlugin,
))
.add_event::<LoadingProgressEvent>()
.add_loading_state(
LoadingState::new(AppState::MainMenuLoading)
.load_collection::<UiAssets>()
.load_collection::<BackgroundAssets>()
.load_collection::<AppAudioAssets>(),
)
.add_loading_state(LoadingState::new(AppState::GameLoading).load_collection::<GameAssets>())
.add_systems(
Update,
get_loading_progress_system
.run_if(in_state(AppState::MainMenuLoading).or(in_state(AppState::GameLoading)))
.after(LoadingStateSet(AppState::MainMenuLoading))
.after(LoadingStateSet(AppState::GameLoading)),
);
}
}
I also have a system that uses the GameAssets resource that was loaded during the GameLoadingState.
pub(crate) struct ThetawavePlayerPlugin;
impl Plugin for ThetawavePlayerPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_plugins(InputManagerPlugin::<PlayerAction>::default())
.add_systems(
OnEnter(AppState::Game),
spawn_players_system,
);
}
}
...
pub(super) fn spawn_players_system(mut cmds: Commands, assets: Res<GameAssets>) {
cmds.spawn((
AseSpriteAnimation {
animation: Animation::tag("idle"),
aseprite: assets.captain_character_aseprite.clone(),
},
Cleanup::<AppState> {
states: vec![AppState::Game],
},
Name::new("Player"),
));
}
The issue is that once every couple of runs I get this error.
thread 'main' panicked at /home/carlo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_ecs-0.15.1/src/system/function_system.rs:216:28:
thetawave_game_starter::player::systems::spawn_players_system could not access system parameter Res<GameAssets>
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `Pipe(bevy_state::state::transitions::last_transition<thetawave_game_starter::states::data::AppState>, bevy_state::state::transitions::run_enter<thetawave_game_starter::states::data::AppState>)`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
The fact that this doesn't happen every run tells me that it is probably something with system ordering. I was wondering if anyone else has experienced this and has any ideas of how to prevent this issue from happening. Weirdly enough it never happens with my MainMenu AppState.
What is AppState?
@topaz gust my bad AppState is the following:
/// States enum for managing the high-level application flow
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
pub(crate) enum AppState {
/// Initial state when app launches, displayed when game first starts up
#[default]
MainMenuLoading,
/// State for the main menu to go to other parts of the game
MainMenu,
/// State for loading the game assets
GameLoading,
/// State for actually playing the game
Game,
}
@frozen ingot are you missing a continue_to_state in there? All my loading state code looks like this (but I don't use the progress stuff like you so not sure if there's a diff with that):
app.add_loading_state(
LoadingState::new(BootState::Loading)
.continue_to_state(BootState::Active)
.on_failure_continue_to_state(BootState::Error)
.load_collection::<BootAssetCollection>()
// ...
.init_resource::<GameConfigRef>()
// ...,
);
yeah that is what I did before I started using iyes-progress, I believe that this line is effectively doing that:
.with_state_transition(AppState::GameLoading, AppState::Game),
Not sure then, sorry! If easy, consider trying without iyes-Progress to see if you can isolate it to that, otherwise wait to see if someone else knows ๐
I appreciate you taking a look!
The code looks fine to me. This panic should not happen.
I will take a closer look at the iyes_progress integration in bevy_asset_loader.
@frozen ingot I have not managed to reproduce this so far. Is the code with the flaky behaviour public?
Also: bevy_asset_loader logs completed loading states. Could you paste more log entries from a failed run please?
thanks @hushed wind I will try to get the log entry for you. Here is a link to the repo with the branch where I am using the GameAssets to spawn a player sprite. https://github.com/cdsupina/thetawave-game-starter/tree/leafwing-input
Thanks, I ran it roughly 20 times and managed to reproduce a crash. The logs only show the completed loading state MainMenuLoading but not GameLoading.
interesting. yeah it's pretty infrequent. Do you think that it is something with system ordering? That has generally been the issue in my experience with inconsistent behavior like this
Yes, it seems that sometimes the progress tracking runs before the loading state can register the first tracking job, so iyes_progress sees Progress { done: 0, total: 0 } and just continues to the next state.
This is a weird one. I am missusing Bevy states a bit and apparently it's biting me now.
In an OnEnter schedule, I reset an internally handled state from Done to Initializing (directly on the world). This system always runs before the loading state schedule runs for the first time in a given loading state. But in the broken runs, Bevy still executes the loading state for Done and not for Initializing O.o
This leads to a single frame where iyes_progress sees Progress { done: 0, total: 0 } and continues before the loading state systems run to register tasks to track.
oh interesting, do think the reason this only happens for GameLoading and not MainMenuLoading is because for I'm only loading one tiny sprite in GameLoading vs many 3D models in the MainMenuLoading?
I think it can happen in any loading state following a completed loading state.
@hushed wind do you think it would be a good idea to add "namespacing" to dynamic asset files?
app.add_loading_state(
LoadingState::new(BootState::Loading)
.continue_to_state(BootState::Active)
.on_failure_continue_to_state(BootState::Error)
.with_dynamic_assets_file::<StandardDynamicAssetCollection>("grayscale-cursor.assets.ron", "grayscale")
.with_dynamic_assets_file::<StandardDynamicAssetCollection>("colored-cursor.assets.ron", "colored")
.load_collection::<GrayscaleCursorAssetCollection>()
.load_collection::<ColoredCursorAssetCollection>()
Then in my AssetCollections:
#[derive(AssetCollection, Debug, Reflect, Resource)]
#[reflect(Debug, Resource)]
pub struct GrayscaleCursorAssetCollection {
#[asset(key = "grayscale.pointer_cursor")]
pub pointer: Handle<StaticCursor>,
}
#[derive(AssetCollection, Debug, Reflect, Resource)]
#[reflect(Debug, Resource)]
pub struct ColoredCursorAssetCollection {
#[asset(key = "colored.pointer_cursor")]
pub pointer: Handle<EnhancedAnimatedCursor>,
}
The point being that I don't need to make my actual RON asset files so verbose:
({
"grayscale_pointer_cursor": File(
path: "cursors/pointer.cur",
),
"colored_pointer_cursor": File(
path: "cursors/pointer.ani",
),
})
i.e. I can split these two assets into their own file and ditch the grayscale_ and colored_ prefix from each of those.
i.e. The namespace passed to with_dynamic_assets_file gets prepended to every key in that file.
An obvious downside is that it hurts grep-ability.
That seems annoying, yeah.
If something like this is really needed, maybe it would be nicer to add support for deserializing maps from the ron files.
("grayscale": {
"pointer_cursor": File(
path: "cursors/pointer.cur",
),
"something_else": File(
path: "test.json",
),
})
Then the ron files would at least only have to list the prefixes once. And you could have multiple prefixes in a file.
Yeah I'm inclined to not worry about this feature request at this time. I don't think that namespacing is worth the sacrifice of not being able to easily grep for your asset keys. At least for now, the added verbosity/repetition on each key is the compromise for that.
@hushed wind do you think you'd reconsider https://github.com/NiklasEi/bevy_asset_loader/issues/219 ? I just started breaking down my game into some smaller subcrates to try and improve compile times, and for one of my new crates I managed to slim it down to only depend on these bevy subcrates:
bevy_app = "0.15"
bevy_asset = "0.15"
bevy_core = { version = "0.15", default-features = false, optional = true }
bevy_derive = "0.15"
bevy_ecs = "0.15"
bevy_reflect = "0.15"
bevy_utils = "0.15"
But bevy_asset_loader wants me to have the bevy dep in my subcrate. Ideally, I'd like to not have to do that.
I was thinking about how to rationalize whether bevy_asset_loader should depend on bevy or the bevy_ subcrates. I came to this as a thought experiment: If bevy_asset_loader was ever upstreamed (but I'm not saying that's on the cards), it would end up in bevyengine/bevy repo, either as a new subcrate or inside bevy_asset, and every crate in there only depends on the bevy_ subcrates that it needs, not the bevy crate. Therefore, bevy_asset_loader should also depend on bevy_ subcrates, not bevy ๐
WDYT?
If I have the following in my game's Cargo.toml: bevy = { version = "..", default-features = false, features = [ # A few features enabled, but no bevy_state, for example # .. ] } be...
mmm, bevy_asset_loader seems very broken on main
actually, never mind, I think it's my fault
I'll think about it again.
Since almost all features are turned off, the bevy crate getting pulled in by the plugin should be pretty small. But sure, it is one more crate in the dependency tree.
Curious, how does one retrieve an internal mesh. Loaded from a gltf file in asset loader?
shoud i use asset serve in those scenarios? As i think the internal mesh would be loaded
Yes, you should be able to get it from the asset. So try getting the asset from the asset collection.
Does anyone know why .init_collection() just gives me an error Cannot get AssetServer?
I'm really struggling to understand this API and how LoadingStates interact with my states I have
it's funny cause when adding a loading state, that does not happen. For more context I have some simple state machine with Menu Loading and Game
Are you calling init_collection after adding the default plugins?
ohh, i'm so fucking dumb
btw I just saw that you are the creator of the crate, right @hushed wind ? Would you mind just briefly explaining how the LoadingState integrates with my States that I have defined? Since I'm struggling to understand how to structure my loading state and if i need seperate states to run in parallel with my main state machine
No separate states needed. Create a state before the state that you want to use an asset collection in. Then make that state the loading state for said collection.
E.g. MenuLoading could be followed by Menu state and LevelLoading by Level. The *Loading states prepare the asset collections for the following state.
But if you want to use loading states, don't use init_collection. Take a look at the examples on GitHub. E.g. https://github.com/NiklasEi/bevy_asset_loader/blob/main/bevy_asset_loader/examples/two_collections.rs
@hushed wind Is it possible to change the asset loader base path?
For exampl, make it acess a folder different from assets
Take a look at asset sources. You can define additional sources and then prefix asset paths with the source id.
See https://github.com/bevyengine/bevy/blob/main/examples/asset/extra_source.rs and the path example_files://bevy_pixel_light.png
Those should just work with the plugin
@hushed wind hi! When im setting a path to a file/folder, can i point to something outside the asset folder? Im in a weird situation where id like to load some files outside that folder and i cant move them in there.
Did you see asset sources? They may work for you. I am using a custom asset source to load save games from outside the assets folder.
Can u clarify?
let save_games_path = proj_dirs.data_dir().join("save-games");
std::fs::create_dir_all(&save_games_path).expect("could not create save games directory");
let mut app = App::new();
app.register_asset_source(
"save_games_dir",
AssetSourceBuilder::platform_default(
save_games_path
.as_os_str()
.to_str()
.expect("could not convert save games path to string"),
None,
),
);
I was talking about these annotations inside the assetcollection struct: #[asset(path = "scripts", collection(typed, mapped))]
Ohhh, ty let me look into this ๐
And my asset collection looks like
#[asset(path = "save_games_dir://.", collection(typed))]
pub save_games: Vec<Handle<ArmyAsset>>,
ugh, i have to go to bed lol. Thanks for sharing ๐
Also see the question and response above your question ๐
omg ๐
gamers dont look up
Perfect, that solved my problem
Hey all, I'm struggling with the following:
- I have a custom ron assets file which is a hashmap of (string -> my custom asset struct) used to store animation configs
- bevy_asset_loader loads this file as a collection of dynamic asset
- I use
finally_init_resourceto build a struct containing all my animation configs like:
* note I would like these to not be Handles, but the full objects
struct Animations {
animation1: AnimationConfig,
animation2: AnimationConfig,
}
I've managed to load the custom .ron file with with_dynamic_assets_file, but I am struggling with the FromWorld implementation of my Animations struct... where in World can I find the loaded assets, and access them using the HashMap keys in the .ron file?
has anyoen tried using bevy_materialize crate with this crate yet ?
i am and i seems to have broke bevy_asset_loader
now i get all these insane errors and i hve no good way to even debug this
resource does not exist: bevy_asset_loader::dynamic_asset::DynamicAssets
Encountered a panic in system `bevy_asset_loader::loading_state::systems::check_loading_collection<healing_spirit::appstate::AppState, healing_spirit::file_system_interaction::asset_loading::CharacterAppearancesAssets>`!
thread 'main' panicked at /home/andy/.cargo/registry/src/index.crates.io-6f17d22bba15001f/
`bevy_asset_loader::loading_state::systems::run_loading_state<healing_spirit::appstate::AppState>`!
why would DynamicAssets res not exist ???
what causes this ? is anyone else totally stuck on this !?
it also says
thread 'main' panicked at /home/andy/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_asset-0.15.1/src/handle.rs:357:13:
The target Handle<bevy_image::image::Image>'s TypeId does not match the TypeId of this UntypedHandle
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
but running w backtrace doesnt tellme anything
its failing to load normal .PNG images into Assets<Image> all of a sudden
the image files are the same
all i did what i modified my cargo crates dependenceis
Yeah Iโve recently got this error. It seemingly came out of the blue and I havenโt been able to work out why. I swear I didnโt upgrade any deps. The only โfixโ I could come up with was to replace uses of File with Image. As in, it was a workaround for me.
Btw I think the missing resource is a symptom of an earlier error so make sure to check the first error in the stack, which I think is this untyped ID one.
I don't know the crate, but the first thing I would check if Type IDs don't match is cargo tree -d.
This is possible, but I would propose to use the intended API for dynamic assets: use their keys in an asset collection. Then you end up with
struct AnimationHandles {
animation1: Handle<AnimationConfig>,
animation2: Handle<AnimationConfig>,
}
and that is easy to "resolve" to full asset objects in finally_init_resource.
ohh okay
its because of a small bug in that crate that changes the way png is handled -- turns out i had to disable a default setting in the plugin - kind of weird that it works that way imo
i reported it in an issue on that repO! thanks for your input
I am doing it this way right now, but don't like needing to duplicate each key in both the AssetCollection and the Resource. Is it possible to build the asset collection as a hashmap of handles from the entire custom .ron file instead of specifying each key individually?
This sounds more and more like you should define your own asset and load it with e.g. bevy_common_assets. Then it's only one handle to resolve and the content of the asset can be a HashMap.
Okay cool, I can give that a try. Thanks
Hello! I'm getting expected HashMap<String, Handle<Scene>>, found HashMap<_, Handle<_>, _> when using the AssetCollection derive on 0.16. Is this a known issue or am I doing something wrong?
There is no published version compatible with 0.16 yet. I am waiting for a dependency to update.
I am aware, I'm using rc3 atm, but if that's known to not be ready for use yet it's all good!
You can use the latest RC version with the last Bevy RC. That's the closest you can get to 0.16 at the moment.
RC 3 should work
Just to be clear: asset loader rc3 should work with 0.16 (stable)?
Are you sure that you have only one Bevy version in your dependencies?
No, it works with the last RC of Bevy
I see. Is that the same for the bevy_main branch?
I am using bevy_main of asset loader successfully with bevy 0.16 ๐
As far as I can tell it's only 0.16
Damn, I tried that first and it didn't seem to work :c
No wait I lied. I am using rc3 of asset loader with bevy 0.16
Works for me
Hm. I'm not sure if that makes me more or less hopeful ๐ญ
You should double check your lock file I bet something else makes you pull in bevy 0.15 or a different version of asset loader
cargo tree is your friend debugging this
Yeah I checked and found no dupes of bevy itself, so that's a bust I think
Do you have progress tracking enabled? Without that it might work.
Nope, just trying to get a base-case of a mapped collection working, no fancy stuff (yet)
Let me just try the bevy_main branch after cleaning some stuff to really make sure it wasn't something stupid
Are you sure what you try to do is working at all (like in bevy 0.15) ?
I was, but now I'm not so sure anymore ๐
I always had to use a different key type for these maps
AssetFilename and not String
Oooo that sounds like you're on to something
And maps did not work for me with scenes - only Handle<Gltf> where you have to pick the right scene inside later
Unless you are loading actual bevy scenes then never mind ๐
The asset pipeline has changed a bit since i last used bevy (0.13 or so?), so I'm still orienting myself with the changes
#[derive(AssetCollection, Resource)]
pub struct Models {
#[asset(path = "models", collection(typed, mapped))]
pub gltfs: HashMap<String, Handle<Gltf>>,
}
So this is what I've got, which gives an error for the AssetCollection derive
Doesn't matter if I change to a list of files, untyped, etc.
Hm. Loading to a vec works.
Are you using the right HashMap type coming from bevy?
Good question. That could be it too
This turned out to be the culprit. Stupid me!
Good itโs fixed ๐
Anyone get a Could not find an asset loader matching: Loader Name: None; Asset Type: None; Extension: None; Path: Some("sounds/bush_impact.ogg"); when trying to use the asset loader with bevy kira audio?
It was working when I used bevy's audiosource but since switching it cannot read the file correctly
Are you sure all the clashing bevy audio features are not enabled? Is the ogg feature of bevy_kira_audio enabled?
Since we are in the beginning of the 0.16 cycle it's also always worth to check your dependency tree for different versions of Bevy.
im using bevy 0.15.3 asset loader 0.22.0 bevy_kira_audio 0.22.0,
for bevy default features off, specified required features that exclude bevy audio(so vorbis and bevy audio), bevy_kira_audio has ogg feature enabled and asset loader is using standard dynamic assets
Please share some code like the AssetCollection
hello ! does bevy file_watcher works for hot reloading of a AssetCollection with compile time assets path ? is there a way of doing that ? thanks !
Yes, for the most part that should just work
is it possible to just collect the paths of files?
more specifically, i have a dynamic asset collection, and on a specific feature i just want to load the paths of the files defined on the ron
You mean paths to the dynamic asset files, or paths belonging to assets defined in a dynamic asset (so asset key -> file path)?
You can access the first in the DynamicAssetCollections<State> resource. The second might be a bit more cumbersome. In the resource DynamicAssets you can resolve a key to dyn DynamicAsset. If you get a StandardDynamicAsset (or your own dynamic asset type) out of that you can read the file path(s) from that.
On one app have a
(Files: paths[...])
Load the files and on the other return only the paths
curious, do dynamic assets work for wasm?
I have
#[asset(key = "levels", collection(typed, mapped))]
pub levels: HashMap<String, Handle<GameLevel>>,
with an assets ron of
"levels": Files(
paths: [
"levels/assembly_line.level.ron",
...
]
),
This runs fine on desktop but wasm errors saying the key doesnt exist
They should, yes. But I haven't tried them on the weg in a while. Can you see in the console/network tab if it managed to load the Ron file correctly?
hm, might be that. its saying it failed to load in console. Also getting a "Failed to deserialize meta for asset "...".ron: Failed to deserialize minimal asset meta" which is weird since im not using asset watcher ๐ค
yeah probably the issue actually. ill see if i can disable this somehow
looksl ike something to do with AssetMetaMode but the API has since changed ๐ฌ https://github.com/bevyengine/bevy/pull/10623
aha, that was it.
adding
.add_plugins(DefaultPlugins.set(AssetPlugin {
meta_check: AssetMetaCheck::Never,
..default()
}))
fixed it
hello !
getting this on windows
2025-06-17T08:44:48.139932Z ERROR system{name="bevy_asset_loader::loading_state::systems::check_loading_collection<game_shared::AppState, game_assets::CardsAssets>"}: bevy_asset::server: Asset path D:\waykeepers2\game_assets\assets/cards\tower_red_projectile.png is unapproved. See UnapprovedPathMode for details.
for all assets.
it works on linux.
the path is good except to forward slash in it, i guess thats what causing the path to be unapproved even tho its in the assets directory. (the asset dir is set to game_assets/assets)
do you think its bevy_asset side issue ?
thanks
Could you share the asset collection please?
#[derive(Reflect, AssetCollection, Resource)]
pub struct CardsAssets {
pub default_projectile: Handle<Image>,
#[asset(
texture_atlas_layout(
tile_size_x = 63u32,
tile_size_y = 14u32,
columns = 1u32,
rows = 1u32
)
)]
pub default_projectile_layout: Handle<TextureAtlasLayout>,
#[asset(path = "cards/ninja_projectile.png")]
}
/// in main:
.set(AssetPlugin {
meta_check: AssetMetaCheck::Never,
#[cfg(not(target_family = "wasm"))]
file_path: format!("{}/../game_assets/assets", env!("CARGO_MANIFEST_DIR")),
unapproved_path_mode: UnapprovedPathMode::Allow, // temp fix
..default()
})
thanks !
the path is valid, and its working on linux. only windows i guess because the path string is not exactly the same because of the backslach + slash combination ?
Yeah. The weird part is that the only forward slash is the one between asset source directory and the asset path. I don't think bev_asset_loader writes that.
But I don't have my laptop right now to test things out
FYI: your filepath could just be ../game_assets/assets . I think there is no need for the format macro and the manifest dir.
yes, but it allows to use the binary from anywhere in my system for development, not only cargo run from the workspace you think this could cause this issue ?
Maybe try once with a relative path.
This test is green on windows: https://github.com/NiklasEi/bevy_asset_loader/blob/test-custom-file-path-on-windows/bevy_asset_loader/tests/custom_asset_file_path.rs
everything is the same sadly. seems bevy asset use the absolute path anyway.
2025-06-18T20:37:37.104095Z ERROR system{name="bevy_asset_loader::loading_state::systems::check_loading_collection<game_shared::AppState, game_assets::CardsAssets>"}: bevy_asset::server: Asset path D:\waykeepers2\game_assets\assets/cards\tower_red_projectile.png is unapproved. See UnapprovedPathMode for details.
with the test passing on github actions windows image, i guess its a weirdness with some windows api versions etc ?
the cargo test runs on my windows install where i normally get the error
is there a way to print in the test whats the path used to see if it has a / instead of \
Can I have multiple loading states? For example, can I have a Preload state that leads into Loading which finally Leads into Gameplay?
Sorry if this is obvious; I couldn't find anything in the repo or docs.
Yes you can. There is no example, but an integration test: https://github.com/NiklasEi/bevy_asset_loader/blob/main/bevy_asset_loader/tests/multiple_loading_states.rs
thanks
Hi, me again. First off, for context, I'm trying to implement a level transition system. Is there a way to go back into an asset loading state later to load a different collection of assets?
I'm guessing it might have something to do with collection maps?
If you want to load different assets in the same loading state you will need to use dynamic assets.
I've been studying the examples, but would that mean I would have to load all level gltfs at the same time? Seems resource intensive if you have a lot of files to load. However, the alternative seems to be having unique loading states and ron files for each level, so that one dynamic collection can be filled with a different gltf at different points during runtime. I'm trying to think of a way to only load certain resources into memory when needed.
There is no example for this use case, but it should be possible to have one Ron file per level defining the same keys. Then have dynamic asset collections using the keys.
Before changing to another level, set the ron file.
I can try to build an example in a couple days; I am on vacation at the moment.
That's what I was thinking, but wouldn't that still require a unique loading state for each ron file?
Unless there's some way to use LoadState(String) to somehow pass the ron as argument.
No, you enjoy your vacation.
There's plenty other stuff for me to puzzle over.
Is there a way to have a typed collection turn .glb files into scenes? Currently the way I'm getting this working is with:
#[asset(path = "tilesets/tiles", collection(typed, mapped))]
pub tiles: HashMap<String, Handle<Gltf>>,
...
SceneRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset(path)))
The asset handles are stored in the collection, but I'm just getting the path from another asset that keeps track of which tiles to load given certain constraints. I would love to be able to use HashMap<String, Handle<Scene>>, but I can't figure out how to do that on a collection.
hey all, quick question: let's say I am loading a scene in an asset collection. After the scene is loaded, I want to run a system to tweak a specific StandardMaterial loaded by the scene. What is the best way of doing this? I would like something like finally_init_resource() but without needing to define a new resource
Run the system in OnExit of the loading state.
You could do that in a custom dynamic asset, but I think your approach is currently the easiest one.
Thanks. I ended up loading the gltf with load_collection, and then doing a finally_init_resource to modify the material and grab the scene handle from the loaded gltf to put in another resource.
In an attempt to make my game more rapidly configurable I want to be able to specify information about the types of structures players can build using .ron files, including their sprite. Ideally I would be able to load an entire folder of ron assets and then have each one load its sprite based on a path specified in the file. Then I'd like to be able to use that list of specifications in a resource or something so I can access it from systems. I've tried my best to wrestle with the examples but I am still struggling to implement this feature. I believe I need to use dynamic assets to do this but I've had very little success. I'm sorry if this is documented but I can't seem to make it work and I'd greatly appreciate any help
Does this happen to support saving data as well like stats?
Also, does this support qoi?
Apparently, for some reason, (I think) bevy_asset_loader screws up transforms
particularly only for bevy_rapier objects
it just gets set to all 0
Yeah, weird... I took off the rigidbody and it's position was fixed.
Any updates on this? Just thought I would ask before I delve into making a custom solution with just Bevy.
I am back from the vacation, but haven't built the example yet.
The custom_dynamic_assets example shows you you can load files throu paths defined in a ron file. Apart from that there is no documentation on how to do that.
Is there any specific point you are struggling with?
No, for that you would need asset savers. There are some plugins for stat/settings management. bevy_common_assets also has some asset savers.
What do you mean with qoi?
No rush, but I do want to know if my guess is right, and it would have to have unique loading states for each level and not some kind of generic loading state. That's the one thing that's kept me stuck.
I think it would be one loading state and dynamic AssetCollections. The collections would use keys that are defined in a Ron file per level. When you change the level
- Tell the loading state to use the correct Ron file for the next level
- The file is loaded and overwrites the key values
- The collection loads with the new keys for the next level
- The old resource with handles of the previous level is replaced by the new one
- Bevy automatically unloads the assets of the previous level because there are no more handles
- Your systems can use the same asset collection resource which now points to the assets for the new level
I think my confusion lies in 1. How to tell the loading state to use a different Ron file than previously provided.
Through this resource: https://github.com/NiklasEi/bevy_asset_loader/blob/07eb61f956cc7d31135e638ac88fdfb9d792cba8/bevy_asset_loader/src/dynamic_asset.rs#L71
What might be missing though is a way to remove the Ron file from the previous level from that resource
I'll experiment around with it later and let you know.
the image format
The supported image formats have nothing to do with this crate, it can work with any asset loader.
Bevy itself does not have an asset loader for qoi images as far as I know, but there are also some third party plugins that define asset loaders.
hello, i am trying to compile the crate and i get this
error[E0277]: `A` does not implement `GetTypeRegistration` so cannot provide type registration information
--> /home/user/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_common_assets-0.13.0/src/ron.rs:20:26
|
20 | .register_type::<A>()
| ------------- ^ the trait `GetTypeRegistration` is not implemented for `A`
| |
| required by a bound introduced by this call
|
= note: consider annotating `A` with `#[derive(Reflect)]`
note: required by a bound in `App::register_type`
--> /home/user/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_app-0.16.0/src/app.rs:595:29
|
595 | pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::register_type`
help: consider further restricting type parameter `A` with trait `GetTypeRegistration`
|
16 | for<'de> A: serde::Deserialize<'de> + Asset + bevy::bevy_reflect::GetTypeRegistration,
| +++++++++++++++++++++++++++++++++++++++++
For more information about this error, try `rustc --explain E0277`.
error: could not compile `bevy_common_assets` (lib) due to 1 previous error
``` anyone know whats going on?
What type are you calling the library with? You could also double check the Bevy version in your lock file as a general measure when compilation fails.
hello, I would like to load a non-SRGB image in an AssetCollection (like a normal map texture). To load this just using bevy's AssetServer, I can pass the following settings to .load_with_settings():
let settings = move |s: &mut ImageLoaderSettings| {
s.is_srgb = false;
};
I notice there is no field is_srgb or something like that on AssetCollection's asset attribute, like there is with sampler. Is there is a clean way to accomplish this with AssetCollection derives? Maybe I am missing something, surely loading normal map texture is a common use case. Thanks
Is there a way to get this to work with file watcher for hot reloading assets?
It depends. Dynamic asset files do not support hot reload. But "normal" assets that are part of an asset collection can be hit reloaded with the usual Bevy features.
How do you load a glb Handle<Mesh>?
By label: some/path/scene.gltf#Mesh0
What about if it's rigged?
As in it has a skeleton
I have no experience with that. You always have the option to load the whole gltf and then extract what you need in a FromWorld resource. Like shown in https://github.com/NiklasEi/bevy_asset_loader/blob/99b5a58382c1eb3296684597309f72220e184f99/bevy_asset_loader/examples/finally_init_resource.rs#L19
I built "managed" asset collections in user-land in my game. Example:
app.add_managed_loading_state(
ManagedLoadingState::new(
LoadingState::new(DebriefLoadingState::Loading)
.continue_to_state(DebriefLoadingState::Loaded)
.on_failure_continue_to_state(DebriefLoadingState::Error),
Debrief::Active, // <-- OnExit state
)
.load_managed_collection::<AssetCollection1>()
.load_managed_collection::<AssetCollection2>()
.load_managed_collection::<AssetCollection3>(),
);
This will load these 3 collections when the state enters, and it will automatically unload them (i.e., remove resource) when the given state exits.
However, it will only unload the asset collection if no other state has requested to load it. In this way, you can have a hierarchy of states and you can declare what asset collections you want to be loaded for a state but if there was, say, a parent state that also declared it needed an asset collection, exiting the child state won't remove the resource.
oooh cool