beyond-all-reason / bar-lobby

BAR Lobby Client
https://beyond-all-reason.github.io/bar-lobby/
MIT License
38 stars 36 forks source link

User settings management #104

Open Jazcash opened 1 year ago

Jazcash commented 1 year ago

Lobby needs to be able to save user's game and engine settings, including hotkeys. Some requirements:

A possible way I see this working could be as follows:

lobby-default-settings.json:

{
    "fullscreen": true
    "displayIndex": 0,
    "skipIntro": false,
    "sfxVolume": 5,
    "musicVolume": 5,
    "loginAutomatically": true,
}

user-settings.json:

[
    {
        "accountId": 1234,
        "lobby": {
            "skipIntro": true,
            "musicVolume": 0
        },
        "engine": {},
        "game": {},
        "hotkeys": {}
    }
]

An interface would need to be written for all the different parts of infra to be able to read and write their relevant settings to this file.

Random ramblings:

Migrations

When a particular setting format is changed, the interface will need to either invalidate the previous setting or migrate it in some way. Some examples of how a setting's format might change:

For key renames, this could simply be a map lookup from old names to new names. This gets slightly more complicated however if old setting names get reused for other purposes later on. For data format changes, logic would need to be written to convert the old format to the new format. Migrations would need to be written for specific versions and all run sequentially when jumping from one version to another. Things could also get messy when watching old replays.

The easiest solution would be to invalidate any changed settings when moving from one version to another where the setting format differs. So long as we keep format changes to the absolute minimum, and account for future possibilities where we can, I think this is ok.

Setting definitions

We already have definitions very similar to this in certain places, but it should follow a standard and be the same everywhere. Recommend following JSONSchema.

[
    {
        "id": "lobby_volume_music",
        "name": "Music Volume",
        "description": "The volume level for the music played in the lobby",
        "type": "integer",
        "min": 0,
        "max": 100,
        "step": 1,
        "default": 5
    }
]

Validation

Both default and user settings should be validated against their relevant definitions. Actions can be taken depending on the type of invalidation found, e.g.

Similar to migrations, it may just be easiest to clear settings if they're not valid, needs discussion.

Cloud backup

If we're backing settings up to Teiserver, they'll probably need to be timestamped with last modified date, e.g. in case users change them offline and don't want their settings in the cloud to override their changes, or vice-versa if they change them on one PC and then log into their account on another.

WatchTheFort commented 1 year ago

All components should read the values of the settings from the same file(s), otherwise we run the risk of data conflicts, where the lobby will have one value for a setting and the game will have another.

I agree with the settings definition file, as we will need to implement identical UIs using multiple frameworks, and this is the best way we can automate as much as possible. I'm not sure if the JSON standard requires parsers to read in deterministic order, but if not we can also include hierarchy and ordering with the setting data.