Skip to content

bevy-settings requires more validity - #25548

Open
DoubleThoughtTheProgrammer wants to merge 14 commits into
bevyengine:mainfrom
DoubleThoughtTheProgrammer:bevy-settings-require-validity
Open

bevy-settings requires more validity #25548
DoubleThoughtTheProgrammer wants to merge 14 commits into
bevyengine:mainfrom
DoubleThoughtTheProgrammer:bevy-settings-require-validity

Conversation

@DoubleThoughtTheProgrammer

Copy link
Copy Markdown

Objective

It took me half a day to get bevy-settings working. This is in part due to lacking documentation and in part due to it failing without any errors. In my first PR (#25547), I improved the situation by improving the documentation. However, even with the improved documentation, it's still possible to write a program that compiles and runs without any errors or warnings, but still is multiple lines annotations and trait implementations away from actually letting SettingsPlugin save and load the settings.

Solution

THIS IS A BREAKING CHANGE

This PR adds trait bounds so that types that implement the SettingsGroup trait must also implement Default and Reflect, which are both required for SettingsPlugin to save and load the settings. Furthermore, SettingsPlugin will now panic if a type is registered #[reflect(SettingsGroup)] but doesn't register #[reflect(Default)], since only types that are registered ReflectDefault and ReflectSettingsGroup will be saved and loaded by SettingsPlugin.

I justify these breaking changes by how only invalid code (that is, code that tries to use SettingsPlugin and SettingsGroup but does not manage to let SettingsPlugin save and load all the SettingsGroup types) can have compile errors.

Testing

  • Did you test these changes? Yes, the test suite passes like before.
  • Are there any parts that need more testing? Oh, absolutely. Since this is a breaking change, it should be determined how much code "in the wild" will be negatively affected by this change.
  • How can other people (reviewers) test your changes? Are there any applications of the SettingsGroup trait that the trait bounds are getting in the way of?
  • If relevant, what platforms did you test these changes on, and are there any important ones you can't test? I only tested this on Linux, as the changes were small enough and confined to cross-platform code so it shouldn't be affected by which platform the tests run on.

`SettingsGroup`s need to be `Resource + Default + Reflect` to actually
do anything with the `SettingsPlugin`, so they may as well be trait
bounds. Also, since `ReflectSettingsGroup` also needs `ReflectDefault`
to function, it may as well panic if that is missing.
@Zeophlite Zeophlite added A-Reflection Runtime information about types D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward A-Settings Related to the preferences and settings framework itself labels Aug 26, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Reflection Aug 26, 2026
@Zeophlite
Zeophlite requested a review from viridia August 26, 2026 08:25

@mnmaita mnmaita left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really thankful for changes in this crate, as I had some issues while trying to implement it in my projects. Leaving a few comments and suggestions.

Comment thread crates/bevy_settings/src/lib.rs Outdated
//!
//! Settings are loaded into resources that implement [`SettingsGroup`](trait@SettingsGroup),
//! which is best implemented using the derive macro [`SettingsGroup`](derive@SettingsGroup).
//! In addition, the resource have the `#[reflect(SettingsGroup, Default)]` annotation.

@mnmaita mnmaita Aug 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//! In addition, the resource have the `#[reflect(SettingsGroup, Default)]` annotation.
//! In addition, the resource should have the `#[reflect(SettingsGroup, Default)]` annotation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"should"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edited! Thanks for catching that one

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer "must have", since otherwise the settings plugin won't load and save that type.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense!

Comment thread crates/bevy_settings/src/lib.rs Outdated
//! In addition, the resource have the `#[reflect(SettingsGroup, Default)]` annotation.
//!
//! Once all these conditions are met, and when [`SettingsPlugin`] is added, systems can query
//! for settings using like any other resource.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//! for settings using like any other resource.
//! for settings as like any other resource.

Maybe a native can double check this, but I feel like this reads better.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, "just like"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally meant to do "for settings using Res and ResMut, like any other resource".

Comment thread crates/bevy_ecs/macros/src/lib.rs Outdated
/// ```
///
/// Note that it's possible to make multiple different types share the same group and file
/// using this, and that case isn't well tested

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add tests instead of documenting the lack of them. What would it take to create them?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it's Bevy house style not to editorialize in user-facing comments (I've tripped up on this myself - it's tempting to justify or hedge, but those discussions belong elsewhere.)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I don't think it's been decided what the expected behaviour is if multiple types have the same group or file - or even the same key, which (I checked) is in fact possible.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple types with the same group and/or file make total sense to me. You could have a "per field" type of configuration where each resource represents a single field in the file. This pattern is useful for change detection for example.

On the other hand, same key for different resources sounds problematic and I don't know how we could prevent that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, same key would produce a warning, but would be expensive to check since you'd have to keep a map of all keys that have been used up to this point. Whether it's worth it is a discussion to have.

Multiple types with the same group is an intentional feature: it's very common in Bevy that we have to split resources apart for technical reasons (change detection, etc.) that have nothing to do with categorization or logical grouping. Forcing each resource to be its own top-level TOML key would make the settings file less legible.

@viridia viridia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good generally, just a few nits.

@mnmaita mnmaita left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last minor thing I spotted. Approving anyway, but it should be fixed for correctness in the docs. Thanks for the changes!

///
/// Note that it's possible to make multiple different types share the same group and file
/// using this, and that case isn't well tested
/// Note that it's possible to make multiple different settings types share the same file,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "multiple different setting types" is correct here, instead of "settings types".

Comment thread crates/bevy_settings/src/lib.rs
Comment thread crates/bevy_settings/src/lib.rs Outdated
@kfc35 kfc35 added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Sep 4, 2026
@alice-i-cecile alice-i-cecile added M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it labels Sep 7, 2026

@alice-i-cecile alice-i-cecile left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite nice overall, but as this is a breaking change it needs a migration guide before merging.

@alice-i-cecile alice-i-cecile removed the S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged label Sep 12, 2026
@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Sep 12, 2026
@alice-i-cecile

Copy link
Copy Markdown
Member

LGTM once CI is green :)

@DoubleThoughtTheProgrammer

Copy link
Copy Markdown
Author

I'm gonna still need to delay this a bit since I need to rename the file. There's no way to rename files on the github app.

@DoubleThoughtTheProgrammer

Copy link
Copy Markdown
Author

The website has file renaming capabilities. So no need to delay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Reflection Runtime information about types A-Settings Related to the preferences and settings framework itself D-Straightforward Simple bug fixes and API improvements, docs, test and examples M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

6 participants