-
Notifications
You must be signed in to change notification settings - Fork 4
05 configuration
appsettings.json, settings.dat (SQLite), legacy settings.xml/system.xml, data-file locations, credentials. Related: 04 — Architecture · 12 — Data Formats
| Concern | Storage | Class |
|---|---|---|
| App-level keys (URLs, paths, lists) |
appsettings.json (copied to output) |
Microsoft.Extensions.Configuration |
| User preferences (UI, theme, gamepad, RA…) |
settings.dat (SQLite AppSettings table, both apps); legacy settings.xml (LINQ-to-XML) |
SettingsManagerService + UnifiedSettingsDatabase
|
| System/game definitions |
settings.dat (SQLite Systems table, both apps); legacy system.xml
|
SystemManagerService / SystemConfigurationWriterService
|
| Favorites / play history / RA data / MAME data | Favorites + play history in settings.dat (Favorites/PlayHistory tables); history.dat, mame.dat, RetroAchievements.dat (MessagePack) |
see 12 — Data Formats |
| Credentials (RA) | DPAPI-encrypted values inside settings.dat (AppSettings; legacy settings.xml) |
WindowsCredentialProtector |
| Emulator-specific settings | each emulator's own config file + samples\{Emulator}\* templates |
InjectEmulatorConfig services |
| Key | Read by | Purpose |
|---|---|---|
Urls:GameImageUrl |
App.xaml.cs:151-157 |
Game cover API base (GameImageClient, 20 s) |
Urls:EasyModeApi |
App.xaml.cs:159-169 |
Easy Mode component manifest API |
Urls:GameClassificationApi |
App.xaml.cs:171-177 |
Store-game classification API (30 s) |
Urls:ParameterResolverApi |
App.xaml.cs:179-190 |
AI parameter resolver API (60 s) |
Urls:RetroAchievementsApi, Urls:RetroAchievementsRequest, Urls:RetroAchievementsSite
|
RetroAchievementsService.cs:43-45 |
RA API base URLs (defaults to retroachievements.org) |
StatusBarTimeoutSeconds |
StartupInitializationService.cs:74-88 |
Status-bar auto-clear (default 3 s) |
RequiredFiles |
CheckForRequiredFilesService |
Startup file check list (note: GetValue<string[]> does not bind arrays — the hardcoded default list is used in practice; documented in CheckForRequiredFilesServiceTests) |
AdditionalFolders |
CreateDefaultSystemFoldersService |
Extra folders created per system |
SystemXmlPath |
DataFileLocation |
Override for system.xml location |
LogPath |
Serilog bootstrap | Log file directory override |
EmulatorsToSkipErrorChecking |
GameLauncherService.cs:1524 |
Exit-code check skip list |
EasyModeCacheDur* |
Easy Mode | Cache duration keys (research note — verify exact key names when editing) |
SimpleLauncher.Core\Services\DataFileLocation.cs decides where a data file lives:
-
Portable mode:
{AppBaseDir}\{fileName}— used if the portable file exists and is newer than the LocalAppData copy. -
LocalAppData:
%LocalAppData%\SimpleLauncher\{fileName}— fallback when the portable file is missing or older. -
TryFallbackToLocalAppData(:122-141) handles write failures by relocating.
Affected files (legacy): settings.xml, favorites.dat, playhistory.dat, RetroAchievements.dat, system.xml (via SystemXmlPath). The unified settings.dat has its own resolver (next section).
Since 5.8.0 both apps persist all user data in one SQLite database (settings.dat).
UnifiedSettingsDatabase.ResolveDatabasePath (Core) decides where it lives:
-
An existing database always wins: a portable
settings.datnext to the exe is kept; when both a portable and a per-user copy exist, the newest one is used. -
No database yet: Windows keeps portable mode for a writable exe folder (zip installs);
Linux/macOS always default to the per-user data folder (
~/.local/share/SimpleLauncher, XDG) because the extracted app folder is writable there and user data belongs in the per-user location (the same folder as logs, window bounds and the legacy backups).
See 12 — Data Formats for the schema, migration and merge behavior. The legacy files below are still read (first-launch migration) and can be exported, but the database is the live store.
SimpleLauncher.Core\Services\SettingsManager\SettingsManagerService.cs
-
File:
DefaultSettingsFilePath = "settings.xml"(:221); load:287-322, save:565-685. -
Load:
XElement.Load; missing or corrupt → defaults + save.LoadFromXml(:395-560) validates values against whitelists (:23-33) and reads both<Application>children and legacy root-level elements. -
Save: read-lock snapshot (
CopyFrom:324-393) → background thread →BuildXElement(:687-764) → temp file → atomicFile.Movewith 3 retries + exponential backoff; portable → LocalAppData fallback (:627-642); failure →FailedToSaveSettingsMessageBoxAsync(:683).
Persisted categories (:38-155): thumbnail sizes (games + system screen), GamesPerPage, ShowGames, ViewMode, EnableGamePadNavigation, VideoUrl/InfoUrl templates, BaseTheme/AccentColor/StyleVariant/Language, DeadZoneX/DeadZoneY, ButtonAspectRatio, FilenameDisplayMode, DisplayMachineName, filename/machine-name font sizes, EnableFuzzyMatching + FuzzyMatchingThreshold + EnableAnnotationStripping, notification sound setting, RA credentials (RaUsername/RaApiKey/RaPassword/RaToken, DPAPI-encrypted via EncryptString/DecryptString :225-264, written encrypted in BuildXElement :717-719), overlay-button booleans, emulator-section expansion states, SystemPlayTimes.
Plus 21 emulator settings classes (SettingsManager\EmulatorSettings\: Ares…Yumir incl. Xenia, Yumir, Mesen, Rpcs3…) used by the inject-config ViewModels.
SimpleLauncher.Core\Services\SystemConfiguration\SystemConfigurationWriterService.cs
Schema (as written by CreateSystemXElement, :250-303):
<SystemConfigs>
<SystemConfig>
<SystemName>Nintendo SNES</SystemName>
<SystemFolders><SystemFolder>.\roms\Nintendo SNES</SystemFolder>…</SystemFolders>
<SystemImageFolder>.\images\Nintendo SNES</SystemImageFolder>
<FileFormatsToSearch><FormatToSearch>zip</FormatToSearch>…</FileFormatsToSearch>
<GroupByFolder>false</GroupByFolder>
<DisableRecursiveSearch>false</DisableRecursiveSearch>
<ExtractFileBeforeLaunch>true</ExtractFileBeforeLaunch>
<FileFormatsToLaunch><FormatToLaunch>smc</FormatToLaunch>…</FileFormatsToLaunch>
<Emulators>
<Emulator>
<EmulatorName>RetroArch Snes9x</EmulatorName>
<EmulatorLocation>%BASEFOLDER%\emulators\RetroArch\retroarch.exe</EmulatorLocation>
<EmulatorParameters>-L "%EMULATORFOLDER%\cores\snes9x_libretro.dll" -f</EmulatorParameters>
<ReceiveANotificationOnEmulatorError>true</ReceiveANotificationOnEmulatorError>
<ImagePackDownloadLink1..5>…</ImagePackDownloadLink1..5>
<ImagePackDownloadExtractPath>…</ImagePackDownloadExtractPath>
</Emulator>
</Emulators>
</SystemConfig>
</SystemConfigs>Write behavior: alphabetically sorted (ordinal-ignore-case), XML-UTF8-indented, temp file + File.Move, 3 retries with 500 ms backoff, SystemExists case-insensitive. EmulatorXmlHelpers (SettingsManager\EmulatorXmlHelpers.cs) reads typed values with a fallback chain: section element → flattened root element ({SectionName}{PropertyName}) → default.
Interfaces: ISystemManager (SystemName, SystemFolders, PrimarySystemFolder, SystemImageFolder, FileFormatsToSearch, FileFormatsToLaunch, Emulators, GroupByFolder, DisableRecursiveSearch, ExtractFileBeforeLaunch) and IEmulator (EmulatorName, EmulatorLocation, EmulatorParameters, ReceiveANotificationOnEmulatorError, ImagePackDownloadLink1..5, ImagePackDownloadExtractPath).
Resolved at launch time by PathHelper/ResolveParameterString (GameLauncherService.cs:1063-1070):
| Placeholder | Meaning |
|---|---|
%BASEFOLDER% |
Directory of SimpleLauncher.exe
|
%SYSTEMFOLDER% |
First <SystemFolder> of the current system |
%EMULATORFOLDER% |
Directory of the emulator executable |
%ROM% |
Full path of the ROM (path + extension) |
%NAME% |
ROM name without path/extension |
%ROMSYSTEMFOLDER% |
The system folder that contains the selected ROM |
If none of the ROM placeholders is present, the ROM path is auto-appended (MAME/Raine get the bare machine name instead).
-
ICredentialProtector→WindowsCredentialProtector(DPAPI,DataProtectionScope.CurrentUser, fixed entropy"SimpleLauncher.Salt"; Base64 ciphertext; empty in → empty out; tampered data → null). Used for RA credentials and DuckStation token encryption. -
NoOpCredentialProtectorexists in tests.
- Home
- 01 Overview
- 02 Projects And Solution
- 03 Quickstart
- 04 Architecture
- 05 Configuration
- 06 Systems And Launch
- 07 Core Services
- 08 Ui Layer
- 09 Retroachievements
- 10 Game Scanning
- 11 Bundled Tools
- 12 Data Formats
- 13 Logging And Debug
- 14 Testing
- 15 Development
- 16 Updater
- 17 Release Notes
- 18 Emulator Parameters
- Manual Tests
- Parameters