fix(update): an update stays in its build's folder, and a new build's is named after its channel #104

Merged
HumanBean merged 6 commits from HumanBean/LongshotLauncher:feat/update-in-place into main 2026-11-15 17:34:55 +00:00
Owner

Every update built the new version into a new folder named after it and left the old one on the disk, so each update added a whole copy of the game (and moved the game's path, which the GPU driver's settings follow). This lands #57: an update now builds over its build in the same folder, and each new build gets its channel's folder (stable, rc, nightly), so one build per channel is kept up to date in place.

Supersedes #57: it's Victor's commit (authorship kept) with the review fixes from review/pr57, rebased onto main, plus the fixes below for what landed since.

What changed

From #57 (see its description for the details):

  • BuildRegistry.FolderOf: an update or a rebuild is built in its build's own folder; a new build goes in NewFolder, named after its channel (LauncherSettings.FolderFor), past folders other builds have or that hold other things.
  • BuildRegistry.PickedFolder: step 2's folder picker rule, moved into Core so the tests reach it.
  • BuildRegistry.Replace: a row named after its version takes the new version's name when the folder stays.
  • Step 2 won't start a build over a game while Longshot runs, and make_game's "still running from this folder" at the swap is now a known problem (Problems.GameRunning).
  • A folder a stopped build left (.longshot_exefs / .longshot_romfs) is built in again, not passed over for nightly (2).
  • README: "An update stays in its build's folder" (the only way back is to build the old version again) and "A new build's folder is named after its channel"; the Settings hint.

New here, for what landed on main after #57:

  • The Ready page's "updated from": BuildJob.From read Replaces.Version live, and Replace sets it to the new version first (Anarkkie's finding on #57). It's read once when the job is made.
  • #78 shader caches: Seed no longer runs ShaderCaches.Keep from a folder into itself; an update in place keeps cache/ where it is (logged). Keep still applies when the player moves an update to another folder in step 2. The README entry says so.
  • #58 game-file links: SameGameFiles gives none when the build's own folder already holds the .nup's unpacked game files, so an update in place isn't pointed at another build's copy. The check that expected the other build there is updated, and the "never its own folder" case is still checked.
  • README and docs/saves.md no longer say an update makes a new folder.
  • AGENTS.md: how to sign in to git.magicbean.dev (Longshot's scripts/forge.py login, its CONTRIBUTING.md step 2), and that its pr commands are for Longshot only.

Testing

Linux (CachyOS), .NET SDK 10.0.404.

  • python -I tests/test_launcher_core.py: 1203 checks passed (rebased on main @ 395578bf). With the SameGameFiles guard removed, the run stops at the new check.
  • python -I tests/test_release.py: 29 tests, OK.
  • dotnet build App/LongshotLauncher.csproj: 0 warnings, 0 errors.
  • scripts/translations.py: the 5 missing texts per catalog are #78's and #87's, already on main.

Not tested: no real update was run here (no game dump on this PC). Anarkkie's Windows run on #57 (nightly 148 to 153 in builds/nightly, NVIDIA 3080 Ti) covers the in-place flow. Unrelated and already broken on main: tools/screenshots doesn't compile since #87 made LauncherService.Gpus read-only, so there's no screenshot of the Settings hint.

Follow-ups (from #57): deleting the version-named folders that earlier updates left; step 2 still asks for 45 GB for an update in place.

Issue: MagicBeanDev/Longshot#224

🤖 Generated with Claude Code

Every update built the new version into a new folder named after it and left the old one on the disk, so each update added a whole copy of the game (and moved the game's path, which the GPU driver's settings follow). This lands #57: an update now builds over its build in the same folder, and each new build gets its channel's folder (`stable`, `rc`, `nightly`), so one build per channel is kept up to date in place. Supersedes #57: it's Victor's commit (authorship kept) with the review fixes from `review/pr57`, rebased onto main, plus the fixes below for what landed since. ## What changed From #57 (see its description for the details): - `BuildRegistry.FolderOf`: an update or a rebuild is built in its build's own folder; a new build goes in `NewFolder`, named after its channel (`LauncherSettings.FolderFor`), past folders other builds have or that hold other things. - `BuildRegistry.PickedFolder`: step 2's folder picker rule, moved into Core so the tests reach it. - `BuildRegistry.Replace`: a row named after its version takes the new version's name when the folder stays. - Step 2 won't start a build over a game while Longshot runs, and make_game's "still running from this folder" at the swap is now a known problem (`Problems.GameRunning`). - A folder a stopped build left (`.longshot_exefs` / `.longshot_romfs`) is built in again, not passed over for `nightly (2)`. - README: "An update stays in its build's folder" (the only way back is to build the old version again) and "A new build's folder is named after its channel"; the Settings hint. New here, for what landed on main after #57: - **The Ready page's "updated from"**: `BuildJob.From` read `Replaces.Version` live, and `Replace` sets it to the new version first (Anarkkie's finding on #57). It's read once when the job is made. - **#78 shader caches**: `Seed` no longer runs `ShaderCaches.Keep` from a folder into itself; an update in place keeps `cache/` where it is (logged). Keep still applies when the player moves an update to another folder in step 2. The README entry says so. - **#58 game-file links**: `SameGameFiles` gives none when the build's own folder already holds the `.nup`'s unpacked game files, so an update in place isn't pointed at another build's copy. The check that expected the other build there is updated, and the "never its own folder" case is still checked. - README and docs/saves.md no longer say an update makes a new folder. - AGENTS.md: how to sign in to git.magicbean.dev (Longshot's `scripts/forge.py login`, its CONTRIBUTING.md step 2), and that its `pr` commands are for Longshot only. ## Testing Linux (CachyOS), .NET SDK 10.0.404. - `python -I tests/test_launcher_core.py`: 1203 checks passed (rebased on main @ 395578bf). With the `SameGameFiles` guard removed, the run stops at the new check. - `python -I tests/test_release.py`: 29 tests, OK. - `dotnet build App/LongshotLauncher.csproj`: 0 warnings, 0 errors. - `scripts/translations.py`: the 5 missing texts per catalog are #78's and #87's, already on main. Not tested: no real update was run here (no game dump on this PC). Anarkkie's Windows run on #57 (nightly 148 to 153 in `builds/nightly`, NVIDIA 3080 Ti) covers the in-place flow. Unrelated and already broken on main: `tools/screenshots` doesn't compile since #87 made `LauncherService.Gpus` read-only, so there's no screenshot of the Settings hint. Follow-ups (from #57): deleting the version-named folders that earlier updates left; step 2 still asks for 45 GB for an update in place. Issue: https://git.magicbean.dev/MagicBeanDev/Longshot/issues/224 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Stops each update from making a new folder named after its version, which changed the game's path and left its settings, mods and the version before behind. Names a new build's folder after its channel, and waits for Longshot to be closed before building over a game.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
The update no longer leaves the old version's folder on the disk, so a broken nightly can only be undone by building the
version before again. README.md's design decisions say so.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The running check is made only when Start is pressed, and the game can be started during the build (a shortcut starts the
default). On Windows make_game.py checks again just before its swap and stops with "Longshot is still running from this
folder"; the problem screen showed it as an unknown failure. It is now GameRunning: close Longshot and build again, what
was built is kept. The swap's own "Could not replace" stays unknown, since a folder that can't be written says it too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
make_game.py reads the game files into the game folder (romfs, .longshot_exefs, .longshot_romfs) long before it writes its
stamp and the game. NewFolder took such a folder for one that holds other things, so the next build after a stopped one went
to "nightly (2)", left tens of GB behind and read the game files again.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
BuildJob.From read Replaces.Version, which BuildRegistry.Replace sets to the new version before the Ready page reads it
(found by Anarkkie in #57). Seed (#78) skips an update in its own folder: its caches are where they are already.
SameGameFiles (#58) gives none for a folder that has the .nup's game files unpacked already. The README and docs/saves.md
no longer say an update makes a new folder.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
docs(agents): sign in to git.magicbean.dev with Longshot's forge.py login
All checks were successful
CI / Compile and test (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 13s
bfc04149ff
Co-Authored-By: Claude Opus 5.5 <[email protected]>
HumanBean deleted branch feat/update-in-place 2026-11-15 17:34:55 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/LongshotLauncher!104
No description provided.