feat(build): the build tools start downloading as soon as the update check answers, and step 1 joins that download #61

Open
madebyjordan wants to merge 1 commit from madebyjordan/LongshotLauncher:feat/tools-early into main
First-time contributor

Why

A first build waited in step 1 for the builder tools, ~500 MB on Windows: a minute or more on a good connection, about 7 minutes on a slow day. The launcher could have fetched them while the player was still finding their game file. Now the download starts as soon as the update check answers, and step 1 joins it.

What changed

  • Core/ToolsPrefetch.cs (new):
    • each version's tools are fetched once for whoever wants them (Get), and anyone can watch a fetch (Watch: the last progress at once, then each one after);
    • a fetch that failed or was stopped starts again on the next Get;
    • Likely() picks the version to fetch early. With no builds yet, it's the newest on the channel new builds start on (a first build). Otherwise it's the default build's update. It returns null when that's already on this PC;
    • LONGSHOT_LAUNCHER_NO_PREFETCH=1 turns the early start off.
  • App/LauncherService.cs: PrefetchLikely() after a successful update check. PruneTools() waits while a fetch runs, because pruning deleted its <tag>.part staging folder and downloads, and it keeps the versions fetched this session.
  • App/ViewModels/WizardViewModel.cs: step 1 joins Service.Prefetch.Get(version) instead of starting its own ToolsSource.EnsureAsync. Leaving the wizard stops watching the download, not the download itself, so the next build finds it done. Retry starts a failed one again.
  • README.md: the LONGSHOT_LAUNCHER_NO_PREFETCH row.
  • tests/launcher_core/PrefetchChecks.cs:
    • one fetch per version, joined by later callers;
    • watchers get the last progress, then the rest;
    • a failed fetch is retried;
    • Busy and Tags;
    • Likely()'s choice: first build, the default build's update, already installed, none;
    • the opt-out.

Behaviour change to weigh

When an update or a first version is available, the launcher now downloads its tools, ~500 MB, in the background at start, before the player asks to build:

  • They're kept for that session.
  • A later build or removal prunes them if no build uses them. If that update is still the likely one, the next start fetches them again.
  • On a metered connection this is data the player may not have meant to use. LONGSHOT_LAUNCHER_NO_PREFETCH=1 turns it off. A setting in the UI would be the friendlier switch if reviewers want one.

Testing

  • tests/test_launcher_core.py on Windows (.NET 10.0.404), rebased on main @ 9b3d202. Every check up to SavesChecks passes, PrefetchChecks among them (Require throws on the first failure).
  • The run can't finish on this PC on launcher main either:
    • main stops at ReleaseChecks: the signed release fixtures, checked out with Windows line endings;
    • with the Windows fixes of a separate branch merged for the run, it stops at SavesChecks, which makes a symbolic link, and this Windows user has no right to (no Developer Mode).
  • Not run: a first build through the launcher's window with the tools fetched early. What step 1 does with an early fetch is what PrefetchChecks covers, through ToolsPrefetch itself.
## Why A first build waited in step 1 for the builder tools, ~500 MB on Windows: a minute or more on a good connection, about 7 minutes on a slow day. The launcher could have fetched them while the player was still finding their game file. Now the download starts as soon as the update check answers, and step 1 joins it. ## What changed - `Core/ToolsPrefetch.cs` (new): - each version's tools are fetched once for whoever wants them (`Get`), and anyone can watch a fetch (`Watch`: the last progress at once, then each one after); - a fetch that failed or was stopped starts again on the next `Get`; - `Likely()` picks the version to fetch early. With no builds yet, it's the newest on the channel new builds start on (a first build). Otherwise it's the default build's update. It returns null when that's already on this PC; - `LONGSHOT_LAUNCHER_NO_PREFETCH=1` turns the early start off. - `App/LauncherService.cs`: `PrefetchLikely()` after a successful update check. `PruneTools()` waits while a fetch runs, because pruning deleted its `<tag>.part` staging folder and downloads, and it keeps the versions fetched this session. - `App/ViewModels/WizardViewModel.cs`: step 1 joins `Service.Prefetch.Get(version)` instead of starting its own `ToolsSource.EnsureAsync`. Leaving the wizard stops watching the download, not the download itself, so the next build finds it done. Retry starts a failed one again. - `README.md`: the `LONGSHOT_LAUNCHER_NO_PREFETCH` row. - `tests/launcher_core/PrefetchChecks.cs`: - one fetch per version, joined by later callers; - watchers get the last progress, then the rest; - a failed fetch is retried; - `Busy` and `Tags`; - `Likely()`'s choice: first build, the default build's update, already installed, none; - the opt-out. ## Behaviour change to weigh When an update or a first version is available, the launcher now downloads its tools, ~500 MB, in the background at start, before the player asks to build: - They're kept for that session. - A later build or removal prunes them if no build uses them. If that update is still the likely one, the next start fetches them again. - On a metered connection this is data the player may not have meant to use. `LONGSHOT_LAUNCHER_NO_PREFETCH=1` turns it off. A setting in the UI would be the friendlier switch if reviewers want one. ## Testing - `tests/test_launcher_core.py` on Windows (.NET 10.0.404), rebased on main @ 9b3d202. Every check up to `SavesChecks` passes, `PrefetchChecks` among them (`Require` throws on the first failure). - The run can't finish on this PC on launcher main either: - main stops at `ReleaseChecks`: the signed release fixtures, checked out with Windows line endings; - with the Windows fixes of a separate branch merged for the run, it stops at `SavesChecks`, which makes a symbolic link, and this Windows user has no right to (no Developer Mode). - Not run: a first build through the launcher's window with the tools fetched early. What step 1 does with an early fetch is what `PrefetchChecks` covers, through `ToolsPrefetch` itself.
feat(build): the build tools start downloading as soon as the update check answers, and step 1 joins that download
Some checks failed
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Compile and test (pull_request) Has been cancelled
99cf5a162f
A first build waited in step 1 for ~500 MB of builder tools (7 minutes on a slow day, a minute or more otherwise) that the
launcher could have fetched while the player was still finding their game file. Now, once the update check answers, the
launcher starts the tools of the version the player is most likely to build next: with no builds yet, the newest on the
channel new builds start on; else the default build's update (ToolsPrefetch.Likely). The wizard's step 1 joins that
fetch (ToolsPrefetch.Get), showing how far it is, rather than starting its own; Retry starts a failed one again. Leaving
the wizard stops watching the download, not the download.

Pruning the tools of unused versions now waits while a fetch runs (it deleted the .part staging folder and the downloads
under it) and keeps the versions fetched this session. LONGSHOT_LAUNCHER_NO_PREFETCH=1 turns the early start off.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
madebyjordan force-pushed feat/tools-early from 99cf5a162f
Some checks failed
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Compile and test (pull_request) Has been cancelled
to 20521448bc
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Compile and test (pull_request) Blocked by required conditions
2026-11-14 06:07:12 +00:00
Compare
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Compile and test (pull_request) Blocked by required conditions
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
Some workflows are waiting to be reviewed.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'feat/tools-early:madebyjordan-feat/tools-early'
git switch 'madebyjordan-feat/tools-early'
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!61
No description provided.