Prerequisite plugins and resources / dependency handling: `.require_plugin()` and `.require_resource()`.
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## What problem does this solve or what need does it fill?
Bevy does not currently provide an ergonomic way to handle prerequisite plugins / resources in the same fashion of similar initialisation / configuration concerns of apps.
Adding plugins and resources that may or may not already be added to the app requires condition checking outside of the usual chain of `app.add_plugin(...).insert_resource(...).` etc. that you would have in `Plugin::build()` or `main()`.
Often this is done for setting up prerequisites, such as plugins which rely on `egui` checking to make sure `EguiPlugin` is added.
In these cases, a bit of semantics is lost in the code, which may obfuscate the code-writer's intent. It also unnecessarily separates initialisation logic into multiple parts of your code.
For example, the following patterns are very common:
```rs
fn build(app: &mut App) {
app.add_systems(Update, ui_update);
if !app.world.contains_resource::() {
panic!("UI Settings not present. Please provide a UiSettings resource!");
}
if !app.is_plugin_added::() {
app.add_plugins(EguiPlugin);
}
}
```
## What solution would you like?
I propose `App::require_plugin::(auto_init: bool) -> ?` and `App::require_resource::(auto_init: bool) -> ?`. The `?` type here _could be, for example,_ a `Result` for better error checking.
These functions would perform the same sort of checking in the code above, but making the code more concise and better preserving semantics / intent.
Example:
```rs
fn build(app: &mut App) {
app.add_systems(Update, ui_update)
.require_resource::(false)
.require_plugin::(true);
}
```
Additionally, `.require_*` functions may be able to _log_ that a panic was caused due to a dependency error, which may or may not happen when using the current method of manually checking - particularly if dependency checking is done many times throughout the code and the developer has forgotten to write sufficient logging logic.
## Issues with this solution
- **Running additional code along side requirement checks.** *Example: Attempting to manually initialise a resource/plugin outside of its `Default` constructor, altering the app initialisation if a resource/plugin is not present, etc.*
- **Does not work with Plugin sets.** I'm not a pro Rust developer, but I'm pretty sure the following, although pretty, would not be possible: `app.require_plugins::<(EguiPlugin, PlayerPlugin, ClientPlugin)>()`. Maybe another solution than the one proposed would allow similarly ergonomic code.
- **Is this in the scope of Bevy's concerns?** Although this is a very declarative approach, and does provide an ergonomic benefit to the developer, whether or not this is bloat or is better left to a third-party crate is questionable.
## Additional context
Many other languages and frameworks such as [PHP](https://www.php.net/manual/en/function.require.php), [NodeJS](https://nodejs.org/api/modules.html#requireid), [Lua](https://www.lua.org/pil/8.1.html), [Elixir](https://hexdocs.pm/elixir/main/alias-require-and-import.html), etc. have implemented requirement handling for conditional initialisation of external code.
This too alleviates the need for manual checking, and makes the intent of the code more clear.
## Additional additional context
If this gets accepted and the behaviour / implementation details are decided upon, I'd be more than happy to create a PR with my implementation :)
Contributor guide
Research direction
Start by reviewing the proposed App::require_plugin and App::require_resource entry points and the example dependency-checking patterns in the issue. Clarify the return type, auto-initialization behavior, plugin-set support, logging, and whether this belongs in Bevy before identifying implementation files. Done means an agreed API and scope, rather than only a patch for the examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100