#bevy_asset_loader

1232 messages ยท Page 2 of 2 (latest)

frosty shale
#

I meant on server spawn((tile, ImageBundle{image: assets.terrain}, Replicated)) (i was wondering if it's possible here to have a empty dummy terrain handle here since it's on the server) and it's replicated to the client, where the client will use the asset.terrain but it's the real asset this time

royal kayak
#

why would server need the terrain asset?

frosty shale
#

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

royal kayak
#

Just make the client app load terrain

frosty shale
royal kayak
#

Client should spawn

#

It is wiser to do so

frosty shale
#

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

obtuse locust
#

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

hushed wind
obtuse locust
#

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

obtuse locust
#

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)

royal kayak
#

@hushed wind Is there a way to load a entire folder without needing to say it is full path

hushed wind
royal kayak
#

Oh i was just using a bunch of relative file paths

#

Weird phrasing

solid lark
#

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

final sparrow
#

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.)

topaz gust
solid lark
#

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

solid lark
solid lark
#

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
frosty shale
#

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'`
frosty shale
#

path = stringify!(test) doesn't work too

#

oh because its being changed into a &str AFTER the AssetCollection macro run

frosty shale
#

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>,
                )*
            }
frosty shale
#

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>,
                )*
            }
hushed wind
hushed wind
frosty shale
topaz gust
#

@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).

GitHub

I'm loading in a repeating texture and have to load it with a custom ImageSamplerDescriptor to set the UV address mode. fn(&mut ImageLoaderSettings) = move |s: &mut ImageLoaderSettings|...

hushed wind
#

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.

topaz gust
#

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.

topaz gust
noble dagger
#

has anyone tried 0.21 (latest) on 0.15 yet? Does it work?

hushed wind
hushed wind
wild canopy
#

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.

wild canopy
#

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.

frozen ingot
#

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.

topaz gust
#

What is AppState?

frozen ingot
#

@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,
}
topaz gust
#

@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>()
        // ...,
);
frozen ingot
#

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),
topaz gust
#

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 ๐Ÿ™‚

frozen ingot
hushed wind
#

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.

hushed wind
#

@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?

frozen ingot
hushed wind
frozen ingot
#

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

hushed wind
#

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.

hushed wind
#

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.

frozen ingot
#

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?

hushed wind
#

I think it can happen in any loading state following a completed loading state.

topaz gust
#

@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.

hushed wind
# topaz gust 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.

topaz gust
topaz gust
#

@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?

GitHub

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...

dense flame
#

mmm, bevy_asset_loader seems very broken on main

dense flame
#

actually, never mind, I think it's my fault

hushed wind
royal kayak
#

shoud i use asset serve in those scenarios? As i think the internal mesh would be loaded

hushed wind
#

Yes, you should be able to get it from the asset. So try getting the asset from the asset collection.

bold meadow
#

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

bold meadow
hushed wind
bold meadow
#

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

hushed wind
#

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

GitHub

Bevy plugin helping with asset loading and organization - NiklasEi/bevy_asset_loader

royal kayak
#

@hushed wind Is it possible to change the asset loader base path?

#

For exampl, make it acess a folder different from assets

hushed wind
#

Those should just work with the plugin

noble dagger
#

@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.

topaz gust
topaz gust
#
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,
        ),
    );
noble dagger
#

I was talking about these annotations inside the assetcollection struct: #[asset(path = "scripts", collection(typed, mapped))]

#

Ohhh, ty let me look into this ๐Ÿ™‚

topaz gust
#

And my asset collection looks like

#[asset(path = "save_games_dir://.", collection(typed))]
pub save_games: Vec<Handle<ArmyAsset>>,
noble dagger
#

ugh, i have to go to bed lol. Thanks for sharing ๐Ÿ™‚

hushed wind
noble dagger
#

gamers dont look up

#

Perfect, that solved my problem

solid mural
#

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_resource to 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?

solid lark
#

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 ???

solid lark
#

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

topaz gust
# solid lark it also says ``` thread 'main' panicked at /home/andy/.cargo/registry/src/inde...

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.

hushed wind
hushed wind
solid lark
#

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

solid mural
hushed wind
#

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.

solid mural
#

Okay cool, I can give that a try. Thanks

plucky palm
#

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?

hushed wind
#

There is no published version compatible with 0.16 yet. I am waiting for a dependency to update.

plucky palm
#

I am aware, I'm using rc3 atm, but if that's known to not be ready for use yet it's all good!

hushed wind
#

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

plucky palm
#

Just to be clear: asset loader rc3 should work with 0.16 (stable)?

hushed wind
#

Are you sure that you have only one Bevy version in your dependencies?

#

No, it works with the last RC of Bevy

plucky palm
spiral steeple
plucky palm
plucky palm
spiral steeple
#

Works for me

plucky palm
#

Hm. I'm not sure if that makes me more or less hopeful ๐Ÿ˜ญ

spiral steeple
#

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

plucky palm
#

Yeah I checked and found no dupes of bevy itself, so that's a bust I think

hushed wind
#

Do you have progress tracking enabled? Without that it might work.

plucky palm
#

Let me just try the bevy_main branch after cleaning some stuff to really make sure it wasn't something stupid

spiral steeple
plucky palm
spiral steeple
#

I always had to use a different key type for these maps

#

AssetFilename and not String

plucky palm
#

Oooo that sounds like you're on to something

spiral steeple
#

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 ๐Ÿ™‚

plucky palm
#

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.

spiral steeple
#

Are you using the right HashMap type coming from bevy?

plucky palm
plucky palm
spiral steeple
nova fern
#

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

hushed wind
#

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.

nova fern
#

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

hushed wind
frosty shale
#

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 !

hushed wind
rigid thistle
#

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

hushed wind
#

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.

rigid thistle
#

On one app have a

(Files: paths[...])

Load the files and on the other return only the paths

native musk
#

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

hushed wind
#

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?

native musk
#

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

#

aha, that was it.

adding

.add_plugins(DefaultPlugins.set(AssetPlugin {
                meta_check: AssetMetaCheck::Never,
                ..default()
            }))

fixed it

frosty shale
#

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

hushed wind
frosty shale
# hushed wind 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 ?

hushed wind
#

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

hushed wind
frosty shale
frosty shale
#

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 \

lilac surge
#

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.

hushed wind
lilac surge
#

thanks

lilac surge
#

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?

hushed wind
#

If you want to load different assets in the same loading state you will need to use dynamic assets.

lilac surge
#

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.

hushed wind
#

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.

lilac surge
#

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.

lilac surge
#

There's plenty other stuff for me to puzzle over.

fading umbra
#

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.

solid mural
#

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

hushed wind
hushed wind
solid mural
#

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.

pearl urchin
#

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

pearl lark
#

Does this happen to support saving data as well like stats?

pearl lark
#

Also, does this support qoi?

pearl lark
#

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

pearl lark
#

Yeah, weird... I took off the rigidbody and it's position was fixed.

lilac surge
hushed wind
hushed wind
hushed wind
hushed wind
lilac surge
hushed wind
# lilac surge No rush, but I do want to know if my guess is right, and it would have to have u...

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

  1. Tell the loading state to use the correct Ron file for the next level
  2. The file is loaded and overwrites the key values
  3. The collection loads with the new keys for the next level
  4. The old resource with handles of the previous level is replaced by the new one
  5. Bevy automatically unloads the assets of the previous level because there are no more handles
  6. Your systems can use the same asset collection resource which now points to the assets for the new level
lilac surge
#

I think my confusion lies in 1. How to tell the loading state to use a different Ron file than previously provided.

hushed wind
#

What might be missing though is a way to remove the Ron file from the previous level from that resource

lilac surge
#

I'll experiment around with it later and let you know.

pearl lark
hushed wind
#

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.

tropic jay
#

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?
hushed wind
#

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.

solid mural
#

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

pseudo rover
#

Is there a way to get this to work with file watcher for hot reloading assets?

hushed wind
pearl lark
#

How do you load a glb Handle<Mesh>?

hushed wind
#

By label: some/path/scene.gltf#Mesh0

pearl lark
#

As in it has a skeleton

hushed wind
topaz gust
#

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.

pseudo rover
#

oooh cool