Replies: 2 comments 1 reply
-
There's an asset system rework happening here: #8624 which may be relevant. |
Beta Was this translation helpful? Give feedback.
-
So I want to clarify something. The feature that I am proposing is not a build-time process. In other words, I'm not talking about a build pipeline which generates asset files from other asset files. When I speak of "derived assets" I'm talking about a runtime synthesis: objects which are created at runtime using information from one or more "real" assets, and which notify changes whenever any of the source dependencies change. This would be useful for many different kinds of games, but they are particularly useful for the kinds of games I create, which are "quasi-procedural", that is, they are a hybrid of both algorithmic and manual content generation. Minecraft is a good example, Sim City is another: the human author creates modular "lego bricks" - 3d models, textures, sounds, music and so on - and then the algorithm assembles various combinations of those assets as it generates the game world. Creating the world is not a build-time operation, because the world is dynamic and different with every game instance. During development, those "lego bricks" are constantly being modified by the game creators. Ideally, then, you want the procedurally-generated content in the world to update when that data changes. For low-level resources such as textures, Bevy does this automatically, such as when you assign a texture handle to a shader - changing the texture causes the shader uniforms to be recomputed. Doing this with custom game resources such as maps, dialogues, recipes or quests is much more difficult. You can detect when assets change using an asset event reader, but when multiple assets are involved now things get very complicated. You end up having to keep around a lot of state variables to say which assets are "dirty". Reactive frameworks have solved this problem a long time ago - computing a memoized value which depends on other values is trivial in frameworks like Solid, MobX or Leptos - it's like 3 lines of code. I recognize of course that Bevy doesn't work that way - but Bevy assets could. We already have the notion of asset change events. Extending the idea to asset dependencies isn't that big of a conceptual hurdle, I think. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Something that would be very useful would be a way to have an asset which is a composite or derivation of other assets. If you've used Solid or MobX, you are familiar with the concept: a computed value which reacts whenever any of its dependencies change.
Here's an example: in my game each world map has a "biomes" asset, which affect the appearance of the terrain. The biome data is an asset - a 2D array of u8 - which specifies, for each terrain sector, what biome type should be used by the the shader to render the terrain mesh. However, this array can't be used by the shader directly, it has to be converted into a form that the shader can consume. The easiest way to do this is to transform the biome array into a monochrome texture with smoothing disabled and pass that as a uniform.
However, there are more complex scenarios in which you have an object which combines data from several assets. Ideally, you would want to recompute this object whenever any of the assets it depends on changes; and by the same token, you'd want anything that depends on that object to recompute when the object changes. Also, it would be nice for these updates to be debounced - if the source assets all change within the same update cycle, you'd like the object to be computed only once.
Doing this right now involves a lot of asset event readers: you have to create an event reader for each of the dependency types, and the correlate the results.
Maybe there's a simpler way to do this using resources and components; if there is I'd love to hear about it.
However, the approach I am thinking of is that the derived "object" would be a type of asset, one that is added programmatically to the asset server. There would be some way to indicate that the object depends on other assets, and you'd get a "changed dependency" event whenever one or more of these dependencies changes.
Users of the object would access via handle, just like any other asset. They would get asset change events when the object is recomputed.
Beta Was this translation helpful? Give feedback.
All reactions