Bevy: Migrate Bevy Asset System to Atelier Assets

Created on 21 Oct 2020  路  7Comments  路  Source: bevyengine/bevy

this is a tracking issue for integrating atelier-assets into bevy

I've been working with "resident asset-expert" @kabergstrom for awhile now to figure out the future of the Bevy asset system. @kabergstrom built atelier-assets, which has basically everything a pro-grade engine needs from an asset system. While learning atelier, I decided to explore the space for a bit by experimenting with directly expanding the current bevy_asset with the features we were interested in. After much discussion about adopting atelier-assets vs expanding the current system, we agreed that atelier was the best long term bet. We merged a subset of my "bevy asset rework" in #693, just to unblock scenarios like GLTF loading and to prepare the way for an atelier migration.

Changes required for a merge

That being said, atelier needs a few features before it can be a drop in replacement for the current system. Atelier support shouldn't be merged until it has the following features:

  • [ ] A bevy_asset integration layer

    • This should be something like the current AssetServer, Assets<T>, and Handle<T>. Zero-api breakage is a nice-to-have, but I'm cool with breaking apis if they are significant improvements or they significantly improve the integration clarity / complexity.

  • [ ] All current Bevy AssetLoaders ported to Atelier Assets
  • [ ] Loading assets via their paths (https://github.com/amethyst/atelier-assets/pull/64)
  • [ ] Wasm publishing support (likely via pack files)

    • Currently, the only way to publish a game with the tools atelier provides is to host a daemon server in a separate process from the game. Wasm (and potentially other future platforms) can't host an in-process daemon server. We need some way to publish games on platforms like wasm. @kabergstrom is planning on adding "packfile" loading, which would drop imported assets into a "packfile" which could then be directly loaded (without a daemon server). This should make WASM support easier, but its also just a nice way to package an app on any platform.

  • [ ] Android publishing support (likely via pack files, but a daemon server might also work)
  • [ ] iOS publishing support (likely via pack files, but a daemon server might also work)

Given that Bevy's current asset system works for most current platforms/user-facing scenarios, I don't want to merge Atelier until we are sure it won't significantly block progress on things like building out platform support or publishing games.

Changes that are "nice to have"

There are also some "nice to have" items that I won't necessarily block a merge on, but should be addressed as soon as possible:

  • [ ] Reduce the number of dependencies used by atelier as much as possible / cutting clean compile time

    • This should include removing large or unnecessary dependencies, but it will also include aligning dependency versions as much as possible. I'm leaving this open-ended because theres a lot to discuss here and plenty of details that need to be handled on a case-by-case basis. For example, Atelier currently uses Tokio, which _does_ introduce a decent amount of dependencies. But Bevy currently doesn't have anything that handles "async io", so theres no way out of adding new dependencies there. We will evaluate all of the options in that space and pick the one that fits our constraints the best.

Changes without any time pressure

And then there are some fun things that have no particular timeline and will likely just get spun off into their own issues:

  • [ ] Wasm asset hot-reloading via something like websockets or WebRTC
assets enhancement third party / dependencies

Most helpful comment

Yeah we've talked a bit about that already. It's definitely on the table!

All 7 comments

Atelier currently uses Tokio, which does introduce a decent amount of dependencies.

I'm not sure about how stuck Atelier is on Tokio, but the smol async runtime is pretty amazing and ridiculously tiny. IMHO it's the best design for an async executor out there, but there could very well be reasons that Atelier can't swtich away from Tokio, and that's probably the topic of another thread.

Yeah we've talked a bit about that already. It's definitely on the table!

Eagerly waiting for the integration!

One note on wasm. While pack files are a simple option for small games, this would not work well for larger ones if each window refresh redownloads 1gb or more of assets. Larger web-based games use local storage to fetch assets just once. This would require some kind of cache layer, which looks for file in local storage and if it's not available uses HTTP to fetch it. If file-level caching is too difficult to implement, then maybe caching pack files would be easier (or just leave it up to the user to download it and provide in-memory file). But I believe with atelier "import and process before load" caching might be easy to implement. Which IIRC was one of the atelier goals to compile a fast asset storage optimized for production (without daemon). Maybe @kabergstrom could comment on this.

I'm not sure about how stuck Atelier is on Tokio, but the smol async runtime is pretty amazing and ridiculously tiny. IMHO it's the best design for an async executor out there, but there could very well be reasons that Atelier can't swtich away from Tokio, and that's probably the topic of another thread.

I want to move atelier-assets to bevy_task, which is based on crates also used by smol. There are a few things missing in bevy_task right now though, preventing the migration:

  • Task locals
  • Support for spawn_local and !Send + !Sync futures
  • file and TCP IO, maybe with async-fs+async-net?
  • for web, probably want websocket support for Daemon connectivity

Would be happy if someone helped on these parts.

One note on wasm. While pack files are a simple option for small games, this would not work well for larger ones if each window refresh redownloads 1gb or more of assets. Larger web-based games use local storage to fetch assets just once. This would require some kind of cache layer, which looks for file in local storage and if it's not available uses HTTP to fetch it. If file-level caching is too difficult to implement, then maybe caching pack files would be easier (or just leave it up to the user to download it and provide in-memory file). But I believe with atelier "import and process before load" caching might be easy to implement. Which IIRC was one of the atelier goals to compile a fast asset storage optimized for production (without daemon). Maybe @kabergstrom could comment on this.

I think web distribution can be done in a ton of ways, and hopefully it'll be simple to implement different approaches. Would love contributions on this front. The Loader API (LoaderIO) is here:
https://github.com/amethyst/atelier-assets/blob/indirect_handles/loader/src/io.rs

For the packaging step, you can imagine just a function that takes &[(AssetMetadata, ArtifactMetadata, Vec<u8>)] and outputs whatever is loaded by the LoaderIO impl.

I would be interested in helping to port current loaders to atelier-assets. Has this effort started? If not, where should it be hosted?

I started on an integration here: https://github.com/kabergstrom/bevy/tree/master/crates/bevy_atelier

It's based on pre-asset-rework code though, so might want to just start over.

If you want to help with porting loaders, you can probably pull in atelier-assets as a dependency and port them to work with the Importer trait.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Nickan picture Nickan  路  4Comments

TheArchitect4855 picture TheArchitect4855  路  3Comments

rod-salazar picture rod-salazar  路  4Comments

TehPers picture TehPers  路  4Comments

erlend-sh picture erlend-sh  路  5Comments