Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement preferences system #61

Open
NthTensor opened this issue Oct 3, 2024 · 3 comments
Open

Implement preferences system #61

NthTensor opened this issue Oct 3, 2024 · 3 comments
Labels
S-Needs-Triage This issue needs to be labelled

Comments

@NthTensor
Copy link

Users need a way to configure personal (and perhaps project level) settings and preferences.

This is a WIP tracking issue for this bundle of features. Living design-doc is available here: https://hackmd.io/@bevy/editor_prefs.

@NthTensor NthTensor added the S-Needs-Triage This issue needs to be labelled label Oct 3, 2024
@viridia
Copy link

viridia commented Oct 4, 2024

I would add a bit more detail to the "preferences easily definable by plugins" bullet point. Specifically, we want plugins to be able to save data that is important to them, but ultimately it's the app that decides where (on the filesystem) these preferences get written to. Otherwise you'd end up with the problem that two different apps using the same third-party crate might overwrite each other's settings. So it's the app's job to define one or more abstract "buckets" where preferences live, and individual preference users can pick which bucket they want.

The approach I have taken is that preferences are "just resources" - this means you get a lot of things like change detection for free, and plugins can register their own preference types using the standard Bevy APIs. Of course, we don't want to serialize every resource, so an annotation is used to mark which resources are to be saved. Iterating through all resources and serializing the marked ones is relatively straightforward.

Game states are also "just resources", but require a bit of extra plumbing in order to be able to properly handle state transitions.

The simplest approach is to make each resource a separate preference group, but this leads to serialized files that are more complex than they need to be. The reason is because when designing resources in a game, often the way that things are grouped is constrained by technical and performance considerations - for example a property which changes frequently might be placed in it's own resource so that the changes don't effect readers of other properties. So my annotations also provide a way to override the grouping of properties, allowing values that are thematically related to be placed together even if they are in different resources.

@NthTensor
Copy link
Author

(You should be able to edit that hackMD doc btw).

@viridia
Copy link

viridia commented Oct 6, 2024

A few more comments, based on recent discord discussions.

I honestly think that we shouldn't be building "editor prefs". We should be building "game and editor prefs". Being able to persistently save things like character name, audio volume, graphics settings and so on are a fundamental feature of just about every A-level game. In my opinion, this is absolutely a feature that Bevy should provide out of the box.

I understand the desire to scope things narrowly so as to build the editor as quickly as possible. The argument is that by trying to serve both the needs of the editor and the needs of games, that it will take longer to develop. I don't believe this is true, and in fact I think it's the other way around: the requirements for game preferences are relatively modest and easy to meet, whereas the (to my eyes) increasing complexity of the preferences requirements are all being driven on the editor side.

Nor am I convinced that these additional features (like merging preferences from different sources) are actually necessary. The use cases are hypothetical and speculative. We don't even know, yet, what kinds of settings we will be storing (coming up with a doc of known settings would be a good first step).

A lot of Bevy developers are used to the hierarchical settings of VSCode, but VSCode is a programmer's editor, and is targeted towards people who understand overlays and hierarchies and such. Moreover, VSCode is unusual in that it is meant for (a) large numbers of projects which are (b) created frequently, and which (c) have a huge set of customization options that are different per-project.

Most apps don't do this, and some users would find it confusing to have settings in multiple places. The kinds of users who use the Bevy editor aren't necessarily the same set of people that would use VSCode. This is exactly the kind of argument that the "user stories" for the editor should resolve.

What's the alternative, then? The answer is to do what most apps do: you have some settings which are per-user, and some settings which are per-project. After all, there are some settings - like key bindings - that don't make sense on a per-project basis. Other settings don't make sense per-user. Are there some settings which make sense for both? Maybe, but is that a small number or a large number? We don't know yet.

The way I had envisioned this working is that there would be an additional annotation, such as @PreferencesSet(User) (the default) or @PreferencesSet(Custom("project")) which would be used to mark a resource as belonging to one set or the other. At the app level, we would define mappings from preferences set to specific file locations, so Custom("project") might map to $PROJECT_ROOT/.bevy_editor/project.toml. But each preference property would be loaded and saved to a single location.

In the case where you want to be able to set a "project default", this can be done as a special case: either by saving a blank, empty project (like Blender does), or by bespoke logic in the app itself for just those properties that can be defaulted.

What about the case of multiple instances of the Bevy editor customized for different games? The answer is, how many instances is the typical editor user likely to have? If the answer is one or two, then it's not that much of a burden for the user to set up their per-user preferences manually for each instance of the editor. If it's more than that, then perhaps an explicit "export/import settings" feature might make sense. It also depends on how many per-user preferences we expect to have. If there's less than a dozen fields, it's probably less work for the user to set those fields by hand than to go through a complex export/import process.

Implementation note: per-user preferences are stored in a file whose name is configured by the app at initialization time, in the standard location for preferences on that platform. This means that each variation of the Bevy editor should have a unique name, so that preferences don't get overwritten.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-Needs-Triage This issue needs to be labelled
Projects
None yet
Development

No branches or pull requests

2 participants