bevyengine / bevyengine/bevy

Multi-stage asset loading

Open
#1,833 13 comments 6 reactions 0 assignees View on GitHub
A-Assets C-Feature
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## What problem does this solve or what need does it fill?

Often, the result of an asset load that I'd like to pass around isn't just raw bytes, or some struct created by another library. For instance, I have a plugin that loads byes from the array and does some calculation--determines how many channels an audio file contains. My plugin then creates some sort of audio context, which in turn will load the bytes and create a buffer which my systems will later use directly.

Right now, my asset system loads the bytes, does any processing, and marks the asset as loaded. Then, a system listens to events, using the context resource and modifying the created struct with the type introduced by the context.

Unfortunately, this doesn't interact well with the asset loading system. Assets are marked as loaded, even though the real data I want hasn't been created yet. The startup system rushes to instantiate everything, and usually succeeds. But sometimes it fails, and while I can avoid a crash, I can't access the asset in the way I'd like. There's no easy way to tell whether an entire group of assets is fully loaded, in the same way I can with regular asset loaders.

What usually ends up happening is that the bytes of my game's background audio fully load, and the asset is marked complete. My startup OpenAL system detects the new asset and creates an OpenAL buffer. This almost always succeeds before the background audio starts playing, but occasionally it doesn't, and the game starts but my background audio doesn't play. I'm currently rolling my own custom Web Audio backend, and I expect this problem to be even worse given the general latency of loading things from the web.

## What solution would you like?

Two possibilities:

1. Make resources available to asset loaders somehow, so the loader can instantiate the asset in its final desired form. Alternately, create a different asset loader that has access to resources.
2. Create some sort of partial-loaded state which the asset loader can use to signal that it's done with the asset, but which doesn't report that the asset is fully loaded when groups are queried. Add an event for partial loads, and let systems indicate that they've either partially or completely finished an asset load in a way that integrates with the current load checks. Then the loader marks the asset as partially loaded, and systems can detect `PartialLoad` events and either finish the load or perform another step and re-emit the event to even more systems for processing.

## What alternative(s) have you considered?

I imagine I'll have to emit a custom event when I've loaded all my assets, but this further complicates the already non-straight-forward asset-loading process by requiring me to manually track when my custom processing step finishes. Given that I'm doing this in a plugin, whatever mechanism I create will be specific to that plugin. I'm open to other possibilities that I may be missing.

Thanks.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.