Repository navigation
device settings: find a game's settings by what they hold, and give back what is a save - #118
ChakraFusion wants to merge 7 commits into
Conversation
…ack what is a save The game database names the settings files of the games it knows (Liquid-co#84). For the rest, a file is now taken for a game's settings by its contents (presets/detectsettings.go): the vocabulary of one machine's display - resolution, vsync, shadow quality, upscaler - matched inside identifiers split at case changes and separators ("_enableFrameGeneration", "r_materialAniso"), in UTF-8 or UTF-16. Unreal Engine's Config/<platform> folder is taken by convention. Names only add weight, by how reliably the game database's own labels show them to mean settings: over its 16,700 settings and 9,000 save entries, "settings" names 1,521 settings files and 70 saves, ".ini" 1,831 and 137, so a name never decides on its own. A name with a save word in it rules a file out unless the contents are overwhelming; the game database's save locations are never taken, and nor are logs, binaries, long files that are only partly settings, or Syncthing's conflict copies. A file taken for settings that changes like a save is given back for good (verdict "save", which also overrules the game database): - before it is left out, and at every later run, the game's snapshots are asked whether it changed in most of the snapshots in which the rest of the save changed (snapshot/history.go); - while it is left out, every change here and every manifest another device sends count whether it changed when the rest of the save did; three such changes, outnumbering the times it stayed put, give it back (daemon/detectsettings.go). Detected files and verdicts are kept per game (migration 0042: settings_files, settings_observations, and marks for when each game was last judged) and applied through the device settings, so hashes recorded under the old list are carried over as before. The game's file list says why each excluded file is excluded, and unticking one there syncs it. The configuration tab's new text is in the catalogs (en, zh-Hans, zh-Hant). Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
@ChakraFusion is attempting to deploy a commit to the sivadaboi's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Thanks, the detection and the give-back checks are thorough. Two changes before we can merge:
|
…y-content # Conflicts: # cmd/opensave-app/frontend/src/locales/en.json # cmd/opensave-app/frontend/src/locales/zh-Hans.json # cmd/opensave-app/frontend/src/locales/zh-Hant.json
Asked in review: builds of the earlier draft of this change made
settings_files and settings_observations (0043) and marks (0041) with the
same schema, and a database from one of them would not start under a
plain CREATE TABLE ("table already exists"), as happened with
sync_device_settings. IF NOT EXISTS for all three, and a test that opens a
database holding them with 0042 unrecorded; it fails without.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
…c until confirmed
Asked in review: a wrong guess would stop part of a save syncing without
anyone knowing, a bigger risk than the game database's listed files. So a
file found by its contents is now only suggested (verdict "suggested"): it
keeps syncing, and the game's configuration tab lists it with "Keep on
this device" and "Keep syncing". Keeping it on this device leaves it out
of syncing as the database's files are, and the give-back checks watch it
as before; keeping it syncing records "declined", and it is not suggested
again. A suggestion that the snapshots show changing with the save is
withdrawn. The game database's files stay automatic.
POST /api/games/{id}/suggested-settings {path, keepHere} answers one; the
game's JSON carries suggestedSettings. The tab's new text is in the
catalogs (en, zh-Hans, zh-Hant).
TestSuggestedSettings_SyncUntilConfirmed: detection suggests the settings
files and leaves them syncing, an answer each way does what it says, and
detecting again changes neither.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Thanks, both done:
The branch also has today's 🤖 Generated with Claude Code |
Asked about in Liquid-co#106's review for its own lookup: a large save must not be read into memory snapshot by snapshot. ChangesLikeASave read every file of each of a game's last 40 snapshots to tell whether the rest of the save changed - some ten million rows for a quarter-million-file save, each time detection ran - and for a snapshot without a recorded file list it unpacked and hashed the whole archive. Now the database compares two snapshots (store.SnapshotsDiffer, stopping at the first difference), only the files being judged are read (SnapshotPathHashes), and a snapshot with no recorded list is left out (SnapshotHasFiles). ArchiveFiles and filesOf, used only here, are gone. TestSnapshotsDiffer covers the comparison; TestChangesLikeASave passes unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The fixes.9 test build made peer_links, with the same schema, as 0038. A
database from it would not start under a plain CREATE TABLE ("table
already exists"), the problem the review on Liquid-co#118 found for its tables.
IF NOT EXISTS, and a test that opens a database holding it with 0039
unrecorded; it fails without.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
One more change, in the spirit of your review on #106: In 899ccce it changed:
🤖 Generated with Claude Code |
A game cannot replace a file another program has open - Windows refuses the rename whatever share mode the reader asked for - and many games save by writing a new file and renaming it over the old. Detection read every candidate file at each run, with os.ReadFile, whose handle on Windows also keeps the game from deleting it. Now: - it reads through fsx.OpenShared, so deleting is never blocked; - a file that already has a verdict is not opened again: after the first run, only new files are read; - it does not run while a session of the game is open, when the game writes its saves; that game's turn comes after the session. Tests: a judged file is left alone; while a file is being judged the game can delete it (Windows; fails with os.Open); no detection while the game is played, and detection after it (fails without the check). Co-Authored-By: Claude Opus 5.5 <[email protected]>
The follow-up #84 left out: settings files the game database doesn't list are recognised by their contents.
Detection (
presets/detectsettings.go):_enableFrameGeneration,r_materialAniso), in UTF-8 or UTF-16. Unreal Engine'sConfig/<platform>folder is taken by convention.Giving back what is a save: a file taken for settings that changes like a save is given back for good (verdict "save", which also overrules the game database):
snapshot/history.go);daemon/detectsettings.go).Storage and UI: verdicts are kept per game (migration 0042:
settings_files,settings_observations, andmarksfor when each game was last judged). They're applied through the device settings from #84, so hashes recorded under the old list are carried over as before. The game's file list says why each excluded file is excluded, and unticking one syncs it. The configuration tab's new text is in the catalogs: en, plus zh-Hans and zh-Hant as a first attempt for @Janlhin to correct.SyncIgnoreEditorisn't extracted yet, so its new labels are plain English like the rest of it.On my machine: 74 files in 25 games detected, among them Crimson Desert's, DOOM Eternal's and Elden Ring's settings, and 12 games the game database doesn't cover. None of them is a file the snapshot history shows changing with the save.
Tests:
presets/detectsettings_test.go,snapshot/history_test.go,daemon/devicesettings_test.go(TestObserveSettings_GivesBackWhatChangesLikeASave).Checks: the full unit and e2e suites pass locally on today's
dev-public.🤖 Generated with Claude Code