bevyengine / bevyengine/bevy

Loading an asset and one of its subassets causes two loads of the same asset to occur.

Open
#12,756 2 comments 0 reactions 0 assignees View on GitHub
A-Assets C-Bug
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## Bevy version

Commit: 6840f95d625b413dcaedb6263eab55dc506525b5

Loading an asset as well as one of its subassets causes the loader to run twice. This also causes asset events to trigger twice, and causes assets to be added to `Assets` and then immediately overwritten.

Here is an example that demonstrates the issue:

```rust
use bevy::{gltf::Gltf, prelude::*};

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (print_mesh_events, print_gltf_events))
.run();
}

#[derive(Resource)]
struct Handles {
gltf: Handle,
mesh: Handle,
}

fn setup(asset_server: Res, mut commands: Commands) {
commands.insert_resource(Handles {
gltf: asset_server.load("scene.gltf"),
mesh: asset_server.load("scene.gltf#Mesh0/Primitive0"),
});
}

fn print_mesh_events(mut events: EventReader>) {
for event in events.read() {
dbg!(event);
}
}

fn print_gltf_events(mut events: EventReader>) {
for event in events.read() {
dbg!(event);
}
}
```

This prints that any meshes and the gltf are first added and then modified immediately. This likely means the loader is running twice. At the very least, the loader is running once, but the AssetServer loading code is writing to the Assets twice which can be undesirable.

I believe this is because the loaading code in AssetServer sees the asset is not loaded (for that asset path), so it kicks off a load. But since the paths are technically different, it kicks off two loads.

I also tested this with loading two subassets of the same asset, and it also kicks off two loads! Note this doesn't happen if the first load finishes before the second subasset is requested.

Contributor guide

Open the contributing guide

Research direction

Start with the AssetServer loading code and reproduce the issue using the example in the report, loading scene.gltf together with scene.gltf#Mesh0/Primitive0. Trace how concurrent requests for an asset and its subasset are handled. Done means the loader and corresponding asset writes and events occur only once, including when two subassets are requested before the first load finishes.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.