Builder: say how much space it keeps and where, let the player choose the place, and free it #623

Closed
amaralthalesalves wants to merge 5 commits from fix/builder-disk-space into main
amaralthalesalves commented 2026-11-08 14:45:16 +00:00 (Migrated from github.com)

Refs #600

The builder left 5 GB and more in %LOCALAPPDATA%\HookshotBuilder without telling the player (#600: "Don't put 5GB+ anywhere without telling me how much and where first", "allow people to choose where it goes"). On one PC: versions\ 3.0 GB (the current and previous builder), sa\ 2.8 GB (translated code and objects), objcache\ 620 MB, downloads\ 453 MB, exefs\ 86 MB.

What changes

  • Before the build (files page): a line under "Install the game to" says the build files take about 4 GB and where they are kept. Change puts them in <chosen>\Hookshot build files (passed as make_game.py --work, for builds and for the game's in-place updates; the path is kept in HookshotBuilder\work.txt). Default brings them back. The old place's build files are deleted on a move. The line turns red when that drive has less than 4 GB free.
  • After the build (ready page): how much the builder keeps in all (naming both folders when the build files were moved) and how much only makes the next update quicker, with Free up space and Show folder. Free up space deletes objcache, sa, exefs, probe, the setup's downloads and update, and builder versions other than current.txt's and the running one. The game keeps playing; the next update compiles everything again.
  • make_game.py: deletes the work folder's exefs at the end of a successful build: every build deletes it and copies it again from the game folder's .hookshot_exefs. sa\gen stays, so an update with the same translator still skips the lift (lifted_before, #728). Skipped in a development checkout (<repo>\work).
  • Sizes count a hard-linked object (sa\build\obj ↔ objcache) once.

Not covered from #600

  • The setup still installs the builder itself (versions\, ~1.5 GB a version, two kept) in %LOCALAPPDATA% without asking where; choosing that place belongs in builder/setup/setup.c.
  • The executable's place ("somewhat buried") is unchanged.

For the reviewer

  • Free up space also drops the setup's cached part zips, so the next builder update downloads every part again rather than only the changed ones.
  • Deleting a builder version other than the current and running one can leave an older game folder's builder= path pointing at nothing; hos_update.c already handles a missing builder.
  • Five commits, each builds on its own: Storage, the make_game.py cleanup, the files page, the ready page, and naming both folders on the ready page.

Tested

  • dotnet build builder/HookshotBuilder/HookshotBuilder.csproj -c Debug: 0 warnings, 0 errors (and at each commit)
  • tests/builder_workers: 69 assertions passed
  • tests/test_lift_cache.py: ok; tests.test_make_game_cache, tests.test_builder_status: OK
  • tests/run_all.py: the same 38 failures as upstream main on this PC (missing g++, Vulkan and SPIR-V headers), none new
  • Storage.Measure() against a real %LOCALAPPDATA%\HookshotBuilder: 6.1 GB in all, 4.6 GB freeable, ~4 s (run in the background on the ready page)

Not tested: the new rows in the running app, Free up space on a real folder, a full build with --work elsewhere, and the end-of-build cleanup in a release build.

🤖 Generated with Claude Code

Refs #600 The builder left 5 GB and more in `%LOCALAPPDATA%\HookshotBuilder` without telling the player (#600: "Don't put 5GB+ anywhere without telling me how much and where first", "allow people to choose where it goes"). On one PC: `versions\` 3.0 GB (the current and previous builder), `sa\` 2.8 GB (translated code and objects), `objcache\` 620 MB, `downloads\` 453 MB, `exefs\` 86 MB. ## What changes - **Before the build** (files page): a line under "Install the game to" says the build files take about 4 GB and where they are kept. **Change** puts them in `<chosen>\Hookshot build files` (passed as `make_game.py --work`, for builds and for the game's in-place updates; the path is kept in `HookshotBuilder\work.txt`). **Default** brings them back. The old place's build files are deleted on a move. The line turns red when that drive has less than 4 GB free. - **After the build** (ready page): how much the builder keeps in all (naming both folders when the build files were moved) and how much only makes the next update quicker, with **Free up space** and **Show folder**. Free up space deletes `objcache`, `sa`, `exefs`, `probe`, the setup's `downloads` and `update`, and builder versions other than `current.txt`'s and the running one. The game keeps playing; the next update compiles everything again. - **`make_game.py`**: deletes the work folder's `exefs` at the end of a successful build: every build deletes it and copies it again from the game folder's `.hookshot_exefs`. `sa\gen` stays, so an update with the same translator still skips the lift (`lifted_before`, #728). Skipped in a development checkout (`<repo>\work`). - Sizes count a hard-linked object (`sa\build\obj` ↔ `objcache`) once. ## Not covered from #600 - The setup still installs the builder itself (`versions\`, ~1.5 GB a version, two kept) in `%LOCALAPPDATA%` without asking where; choosing that place belongs in `builder/setup/setup.c`. - The executable's place ("somewhat buried") is unchanged. ## For the reviewer - Free up space also drops the setup's cached part zips, so the next builder update downloads every part again rather than only the changed ones. - Deleting a builder version other than the current and running one can leave an older game folder's `builder=` path pointing at nothing; `hos_update.c` already handles a missing builder. - Five commits, each builds on its own: `Storage`, the `make_game.py` cleanup, the files page, the ready page, and naming both folders on the ready page. ## Tested - `dotnet build builder/HookshotBuilder/HookshotBuilder.csproj -c Debug`: 0 warnings, 0 errors (and at each commit) - `tests/builder_workers`: 69 assertions passed - `tests/test_lift_cache.py`: ok; `tests.test_make_game_cache`, `tests.test_builder_status`: OK - `tests/run_all.py`: the same 38 failures as upstream `main` on this PC (missing g++, Vulkan and SPIR-V headers), none new - `Storage.Measure()` against a real `%LOCALAPPDATA%\HookshotBuilder`: 6.1 GB in all, 4.6 GB freeable, ~4 s (run in the background on the ready page) Not tested: the new rows in the running app, Free up space on a real folder, a full build with `--work` elsewhere, and the end-of-build cleanup in a release build. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
NotRexed (Migrated from github.com) reviewed 2026-11-08 14:45:16 +00:00
shayderrr commented 2026-11-08 18:27:50 +00:00 (Migrated from github.com)

Fix conflicts please

Fix conflicts please
amaralthalesalves commented 2026-11-08 19:13:41 +00:00 (Migrated from github.com)

Fix conflicts please

done!

> Fix conflicts please done!
amaralthalesalves commented 2026-11-08 19:46:59 +00:00 (Migrated from github.com)

The error comes from main and its not related with my work.

The error comes from main and its not related with my work.
NotRexed commented 2026-11-09 05:29:50 +00:00 (Migrated from github.com)

Closing to keep the queue clear — please rebase on current main and reopen; thanks!

Closing to keep the queue clear — please rebase on current main and reopen; thanks!
amaralthalesalves commented 2026-11-09 10:13:47 +00:00 (Migrated from github.com)

This couldn't be reopened, so the rebased remainder is #1079. Most of this PR is already on main (f39868e, then 55abe59); #1079 holds only the change main doesn't have: the ready page names both places when the build files are in a folder the player chose, and Show folder opens that folder.

This couldn't be reopened, so the rebased remainder is #1079. Most of this PR is already on main (f39868e, then 55abe59); #1079 holds only the change main doesn't have: the ready page names both places when the build files are in a folder the player chose, and Show folder opens that folder.
Commenting is not possible because the repository is archived.
No description provided.