Skip to content

First-class multi-world support #18884

Open
@djeedai

Description

@djeedai

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

Support for multiple Worlds in a clean and easy to use way.

The fact that Bevy uses a main world to store everything the app needs means that this world mixes various unrelated things: some low-level management systems (windowing), some core engine functionalities (animation graph, asset loading, etc.), and some game/app specific logic (for game, the actual game data saved/loaded as part of a game save). This means a developer has to maintain those distinctions in others ways, for example to determine what to save in a game save. It's very easy to mix things, especially if the game itself should simulate with a fixed timestep/tick (e.g. strategy games) while the rest of the app uses variable timestep (rendering). The existing fixed timestep functionality is at best clunky, and doesn't solve the problem of mixing.

What solution would you like?

  • The user can add additional Worlds corresponding to different encapsulated hierarchies.
  • The additional worlds can be simulated (= the systems executed) in a controlled and ordered way.
  • The user has tools to extract data between all worlds.

What alternative(s) have you considered?

There's a long list of limitations that make working with multiple works currently impractical:

  • There's a sub-app concept but sub-apps run one by one after the main app finished ticking. There's no way to e.g. run the game world in the middle of the frame, after the main world has read user inputs but before the main world processes various things leading to rendering.
  • Extraction from main to render world has immutable access to main world, which forces jumping through hoops when e.g. using ping-pong buffers to prevent allocations.
  • There's no equivalent for render-to-main extraction. This may make sense for the render world, but for another custom world I this makes it useless.

Additional context

Conceptually a lot of games would want to run things in that order, where brackets show the world they operate on:

  • [main] read user inputs
  • [main] process asset changes or other "engine" operations
  • [game] consume user inputs to produce game actions
  • [game] simulate the game, updating its state
  • [game] produce game "outputs", which in turn will trigger engine actions, like loading a new asset or level
  • [main] execute post-game processing like running new animations or physics based on the new game state post-tick
  • [main] prepare rendering for current frame

This is currently almost impossible with a separate game world, without copy/pasting almost the entire world management (sub-apps, render extract, etc.) because they're too specific to rendering.

I really want the game itself to have its own world and not know about the main app world. The separation of concern is critical to ensure:

  1. not mixing game data with app/engine data especially in game save files
  2. making it impossible for a game system to access some engine parts, for correctness and safety (can't load arbitrary resources, can't trigger animations without letting the animation system know, can't mistakenly run a game system against another clock than the game one (especially critical for strategy/RTS games or anything where per-tick actions matter), etc.).

Another obvious use case is in-game editor, or in-process editor, where you want to make absolutely sure editor data and logic doesn't leak into the game itself. I'm sure there are other examples in non-game apps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-AppBevy apps and pluginsA-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleC-UsabilityA targeted quality-of-life change that makes Bevy easier to useS-Needs-DesignThis issue requires design work to think about how it would best be accomplished

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions