Skip to content

settings.json is overwritten wholesale on every launch, discarding unmodelled fields, with no write lock #362

Description

@bobtista

Problem

Two independent defects in the same write path.

No read-merge. GameLauncher.cs:1422 builds a fresh GeneralsOnlineSettings;
GameSettingsService.cs:258-259 serializes it and calls File.WriteAllTextAsync.
LoadGeneralsOnlineSettingsAsync (:208-234) exists but the launch path never calls it, and
neither model declares [JsonExtensionData]. Any key the user set inside GeneralsOnline that
GenHub does not model is discarded on every Zero Hour launch.

No lock. The semaphore guarding LoadOptionsAsync/SaveOptionsAsync
(GameSettingsService.cs:64-145) does not cover the GeneralsOnline load/save at :208-269.
Concurrent launches race on a non-atomic WriteAllTextAsync.

The same class of loss exists on the INI side: ApplyToOptions builds a new dictionary at
GameSettingsMapper.cs:455 and replaces AdditionalSections["TheSuperHackers"] at :473,
dropping unknown keys — which contradicts the preservation behaviour documented in
docs/dev/game-settings-architecture.md:13-34.

Separately, GameSettingsViewModel.CreateGeneralsOnlineSettings (:1163-1194) populates only
the GeneralsOnline and nested properties, so a manual save writes defaults over the user's
inherited TheSuperHackers choices.

Approach

  • Load-merge-write for settings.json, or add [JsonExtensionData] so unknown keys survive.
  • Extend the existing semaphore to the GeneralsOnline path, and write via temp-file replace.
  • Decide what profile isolation should mean for keys GenHub has no opinion on. The current
    answer is "discard them", which reads as accidental rather than chosen.
  • Same treatment for the TheSuperHackers INI section, or correct the doc to match the code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ArchitectureHigher level designBugSomething isn't working rightCore-serviceMajorSeverity: minor < major < criticalWIP

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions