chore(builder): the Builder is command-line only; the launcher is the app #181

Merged
HumanBean merged 8 commits from HumanBean/Longshot:chore/builder-cli into main 2026-11-13 11:37:56 +00:00
Owner

Why

Players should only need the Longshot Launcher. The Builder's own windows (the WPF app on Windows, the Tk window in the Linux AppImage) were a second app to keep working beside the launcher, while the launcher only takes each version's Builder for its Python, its tools and make_game.py. This makes the Builder a command-line package: the launcher and RecompLauncher see the same entry points, arguments, @@ lines and exit codes as before, and started by hand it says to get the launcher.

What changed

What the launcher runs, checked in MagicBeanDev/LongshotLauncher's Core/: never LongshotBuilder.exe or AppRun. It runs the release's own Python on make_game.py directly (Core/MakeGameCommand.cs; Core/Toolchains.cs: LongshotBuilder/tools/python/python.exe and LongshotBuilder/tools/nx2/make_game.py on Windows, usr/python/bin/python3 and usr/share/longshot/nx2/make_game.py from the unpacked AppImage on Linux, which must hold AppRun and usr/share/longshot/tools.lock). None of those paths change, and nx2/make_game.py is untouched. The Builder entry points are RecompLauncher's (recomplauncher.json): --cli --prepare --game {game} and --play {home}/Games/Longshot, on LongshotBuilder.exe (the setup) and Longshot.AppImage.

  • Windows Builder (builder/LongshotBuilder): no WPF any more.

    • Removed: MainWindow.xaml(.cs), App.xaml(.cs), Strings.cs, Glass.cs, Finder.cs, Disk.cs, Storage.cs, ShaderStep.cs, BuilderSettings.cs, BuildWorkers.cs, Updater.cs, the Inter fonts and the image. Also PortableArchive.cs, which nothing called.
    • New Program.cs. --cli is App.Cli moved over: the same home check first, the same Tools.Find, the same lines to stdout and the same error line and exit code. The one change in Cli: failure == "cancelled" is gone, because nothing can cancel a --cli run. Anything else (a double-click) shows the launcher message and its link (https://longshot.magicbean.dev/download) in a message box, also on stderr, and exits 1.
    • Runner.cs: what --cli used, with its environment unchanged. That means PYTHONIOENCODING, the home, LONGSHOT_BUILDER_EXE, LONGSHOT_NGX_SDK/LONGSHOT_FFX_SDK removed, EMSDK/RX_CPM/WGPU_NATIVE, and LONGSHOT_JOBS/LONGSHOT_MEM_LIMIT_GB as inherited. Check and Cancel (window only) are gone.
    • BuilderHome.cs loses DefaultGame, SavePath and LoadPath (window only).
    • LongshotBuilder.csproj: still WinExe, so it opens no console window under the setup or RecompLauncher, and still net8.0-windows self-contained, but without UseWPF. The published folder goes from 243 files (147 MB) to 186 (72 MB).
  • Windows setup (builder/setup/setup.c): kept. It is the zip's LongshotBuilder.exe, which RecompLauncher runs with --cli and --play, and make_game.py copies it into every game folder as longshot.exe, including the launcher's builds.

    • --cli, --play and a game folder's longshot.exe are unchanged.
    • Started any other way, it shows the launcher message and exits, before anything is installed.
    • builder_ready no longer requires WPF's files.
    • --repair is gone, in a later commit (below).
    • The home error is always a stderr line now.
  • Linux AppImage (builder/linux):

    • Removed: longshot_builder.py (the Tk window), linux_update.py (its version buttons), play-diagnostics.sh (its Play), and linux_tools.py --gui's Tk download window.
    • AppRun: --cli, --play and <folder> are unchanged. --cli still runs linux_tools.py env --install with no other argument. --launch <folder> now plays that folder through longshot-launch, for a game folder's longshot (longshot-folder) when --cli built it. Anything else prints the launcher message on stderr, plus a zenity/kdialog box when started outside a terminal with a display, and exits 1.
    • longshot-launch and longshot-folder name the launcher in their messages.
    • The .desktop entry stays, because the AppImage format needs one.
  • Packaging and CI:

    • scripts/check_windows_files.py expects no WPF and fails on one.
    • scripts/builder_package.py and build-windows.yml comments.
    • ci.yml's worker check is now tests/builder_cli (below).
  • Tests:

    • Deleted, because they check the windows only:
      • test_builder_details_hitbox.py and builder_details_hitbox_test.cs
      • test_builder_dlss_update.py, test_builder_update_back.py
      • test_builder_scale.py, test_builder_free_space.py, test_builder_log_read_only.py
      • test_desktop_exec.py
      • test_linux_builder_clock.py, test_linux_builder_jobs.py, test_linux_builder_stop_reason.py
      • test_linux_play_diagnostics.py, test_linux_play_scope.py
      • test_portable_archive.py
    • Trimmed to their non-window parts:
      • test_builder_status.py, test_disk_warning.py, test_ffx_sdk.py, test_make_game_ngx.py
      • test_pipeline_share.py, test_prepare_at_build.py
      • test_linux_update.py, test_linux_downgrade.py (now the folder launcher's dispatch only)
      • test_builder_own_python.py, test_builder_xml_valid.py
      • test_portable_builder_home.py with portable_builder_home_test.cs, test_portable_builder_startup.py
    • test_no_release_lookup.py now also checks that the windows are gone.
    • tests/builder_workers became tests/builder_cli. It runs the actual Runner against an authored make_game.py and checks the arguments, the environment it passes on, the inherited workers and memory, the SDK folders dropped, the lines in order, and each way a run ends: done, @@error, silent failure, no Python, the package's Python removed.
    • test_linux_tools.py gains --launch and the no-window message.
  • Docs:

    • README: Compile shaders, the AppImage, Updating, where the files go, DLSS and FSR 4 (the launcher's switches), the pipeline list, Build from source.
    • CONTRIBUTING: the Builder section and NVIDIA's license text, now in the launcher.
    • docs/windows-portable-builder.md: now for --portable --cli.
    • docs/windows-builder-runtime.md, docs/development.md, docs/forgejo-runners.md, RELEASING.md (the Windows tester's steps).
    • docs/releases.md, which is byte-identical with the launcher's: 3 lines. The launcher's copy needs the same edit.
    • The two screenshots of the windows are removed.
  • Follow-ups after review (new commits on top; the first two are unchanged):

    • Merge main (d956c9ea), which brings in #176, #178 and #179.
    • No Tcl/Tk in the AppImage (build(linux)):
      • deps.sh no longer builds Tk with Xft.
      • appimage.sh no longer copies libtcl9tk9.0.so, libXft, libXrender or their licences.
      • python-build-standalone's own Tcl/Tk, _tkinter, tkinter and turtle are deleted. Its mark changes, so an existing build-linux/deps installs it again.
      • libxft-dev and libfontconfig1-dev leave build-linux.yml and the Dockerfile, which test_linux_docker_packages.py keeps the same.
      • test_appimage_licenses.py now checks that none of this comes back.
    • What was kept only for the 2.x Builder is dropped:
      • setup.c: a game folder's longshot.exe starts bin\longshot.exe itself. launch_installed is gone (it opened an installed Builder with --launch), and so are the setup's --launch and --repair, the old window's Repair.
      • The portable game association (.longshot_builder_home, builder_local=1): only that Builder launch read it. It is gone from portable_home.h (hb_home_game, HB_GAME_HOME) and from make_game.py (portable_game_home, write_game_home), with test_portable_game_home.py.
      • The Windows Builder's --launch is gone.
      • longshot-launch: no folder now means ~/Games/Longshot instead of the old window's builder.ini. It starts only bin/longshot, never the folder's longshot (the folder launcher, which would start it again).
      • make_game.reported(), which only the Linux window read, goes with its test.
    • The antivirus advice names the launcher's folders, in docs/common-issues.md, the README and the website's antivirus guide:
      • %LOCALAPPDATA%\LongshotLauncher (with toolchains) and %LOCALAPPDATA%\Programs\LongshotLauncher, or LongshotLauncher-data for the portable launcher (Core/LauncherHome.cs, LauncherLayout.cs).
      • Instead of the 2.x Repair: build again, and delete the version's toolchains folder if a file is still missing.
    • Leftovers:
      • tests/builder_dlss_update_test.cs, the fixture of the deleted test_builder_dlss_update.py. #179 fixed it on main.
      • scripts/ngx_sdk.py's mention of the Builder's DLSS tick.
    • Self-review fixes:
      • The README's RecompLauncher link anchor, #recomplauncher-longshot, already broken on main.
      • An unused name lookup in init_home.
      • BuilderHome.cs's "ZIP fallback" comment.

Flags and settings

Flag What it does Default now Recommendation Helps on Doesn't help on Untested on
None added. Removed: linux_tools.py env --gui (the AppImage's Tk download window), the setup's --repair and --launch, the Windows Builder's --launch. The Builders' --update <folder> without --cli now gives the launcher message; --cli --update <folder> does what it did - - - - - -

Measurements

main: d956c9ea (2026-11-13; the first two commits were measured against c67cd4a0, the main they were made on)
this PR: chore/builder-cli @ 35eabb8e (the suite ran at 7cbb2168; 35eabb8e changes only a README anchor, a comment and setup.c, which Linux does not compile in the suite)
Hardware: Ryzen desktop, CachyOS Linux (game-free checks and cross-built Windows files only)
Scene: none, no game run
Method:

  • python -I -B tests/run_all.py --jobs 6 under nice -n 19, once on each side.
  • The Windows files: built as build-windows.yml builds them (dotnet publish -r win-x64 -p:EnableWindowsTargeting=true, with SDK 10 here targeting net8.0), then builder_package.py package/zip with the same setup exe on both sides, then check_windows_files.py.
  • The AppImage's Python: built with this branch's scripts/linux/deps.sh into a scratch folder. Its Tk share was measured on the same python-build-standalone download, tar | zstd -19 for the compressed size. main's own Tk build (from source, with Debian's libXft) could not be repeated here, so its libtcl9tk9.0.so, libXft and libXrender are not counted.
  • Line counts: jj diff --stat.

Nothing here is a performance change.
How to reproduce: the same commands in a checkout of each commit

main @ d956c9ea this PR @ 35eabb8e
run_all.py (one run each) 464 passed, 3 failed, 69 skipped (d956c9ea) 454 passed, 2 failed, 65 skipped
LongshotBuilder-<v>-windows-x64.zip 76,166,401 bytes, 1608 files (c67cd4a0) 43,118,369 bytes, 1551 files (9f0a3aa8; unchanged since in what the zip holds)
published Windows Builder folder 243 files, 147 MB 186 files, 72 MB
AppImage's usr/python: Tcl/Tk, _tkinter, tkinter, turtle 9,682,524 bytes (2,907,139 as zstd -19), plus main's own Tk and X libraries 0
lines, whole diff (102 files) +669 / -8267
main @ d956c9ea:    464 passed, 3 failed, 69 skipped in 82 s (linux, 6 at once)
this PR @ 7cbb2168: 454 passed, 2 failed, 65 skipped in 81 s (linux, 6 at once)
FAIL  tests/test_bake_portability.py      (both: no zstandard module on this PC)
FAIL  tests/test_display_pointer.py       (both: win::rx_option undefined at link, from #178 on main; not touched here)
FAIL  tests/test_builder_log_read_only.py (main only: no Tk on this PC; removed with the Tk window)
521 = 536 - the 15 deleted tests (13 of the windows, test_builder_status.py, test_portable_game_home.py)

Testing

Tested:

  • The whole game-free suite on Linux, on main and on this PR (above).
  • The Windows Builder's --cli, on Linux. Its framework-dependent Debug build ran under dotnet (roll-forward to .NET 10), with tools/ the repository and the PC's Python, against the real make_game.py:
    • --cli --check --nup <missing>: @@error, then one error line on stdout and stderr, exit 1.
    • --cli --prepare --game <missing>: make_game's own error line passed through once, exit 1.
    • --cli with no tools beside it: exit 1, with the right error line.
    • --cli with a bad home: exit 1, with the right error line.
    • No arguments, or --update x: the launcher message, exit 1.
  • tests/builder_cli as ci.yml runs it: 187 assertions pass.
  • The Windows Builder builds with warnings as errors.
  • The Windows zip, built as CI builds it, passes check_windows_files.py.
  • setup.c compiles with tools.lock's llvm-mingw, CI's flags and -Wall, with no warnings. Every Windows-only setup check compiles with llvm-mingw, though none can run here: test_setup_runtime.py, test_setup_runtime_paths.py, test_portable_setup_paths.py, test_portable_setup_transaction.py, test_portable_setup_start.py and tests/portable_setup_home_test.c.
  • The AppImage's Python without Tcl/Tk, built by deps.sh:
    • numpy, capstone, unicorn, zstandard, lz4, ssl, sqlite3 and lzma import.
    • import tkinter fails.
    • make_game.py --help and linux_tools.py --help run.
  • AppRun in a stand-in image (test_linux_tools.py):
    • --cli stops without the tools, and runs make_game.py once they are found.
    • --play and --launch need no build tool.
    • Anything else gives the message and downloads nothing.
  • longshot-launch (test_longshot_launch.py):
    • It starts bin/longshot, and only that.
    • No folder means ~/Games/Longshot.
    • Relative folders work.
    • A folder without bin/longshot is refused.
  • LongshotLauncher's core checks, with the companion commit: tests/test_launcher_core.py --strict --longshot <this branch>, 632 checks pass. They read make_game.py, which changed.

Not tested:

  • Nothing ran on Windows or under Wine (none here): the setup's --cli install and build, its message box, a game folder's longshot.exe, and check_windows_files.py --wine.
  • No AppImage was packed: appimage.sh and check_player_build.sh need the build tools and the Vulkan back end.
  • No game run.

Needs other testers:

  • Windows 10/11, with a release zip built from this commit: LongshotBuilder.exe --cli --prepare --game <your copy> installs the tools, builds and exits 0, the folder's longshot.exe starts the game, and double-clicking LongshotBuilder.exe or LongshotBuilder\LongshotBuilder.exe shows only the launcher message, with no console window and nothing installed (T-TS6P).
  • Linux: the nightly AppImage built from this commit. Run --cli --prepare --game <copy>, then start the folder's longshot, expecting the build and the game, with no Tk error (T-ZMS7).

Screenshots

Nothing on screen, apart from the new message box and dialog, which were not captured.

Risk and rollback

  • Someone who starts the Builder by hand gets the message instead of the window. That is the intent.
  • Game folders from 2.x Builders lose their launcher page:
    • On Windows, a 2.x folder's own old longshot.exe still opens an installed Builder with --launch, which now gives the message. Folders made from now on start their game themselves.
    • On Linux, longshot-folder still starts its builder= with --launch: the launcher, or the AppImage for a --cli build, which plays it.
    • A 2.x Linux folder whose game is longshot itself (no bin/) is no longer started by --play.
  • A portable (--portable --cli) build no longer ties the game folder to that Builder. Nothing reads the tie any more.
  • The AppImage has no Tk. Anything that imported tkinter would fail; nothing in the repository does.
  • Reverting the commits restores everything. Nothing is migrated or deleted on players' PCs.

Reviewer notes

Start with builder/LongshotBuilder/Program.cs against the old App.xaml.cs, then builder/linux/AppRun and setup.c's wWinMain.

Other PRs:

  • #179 (merged on main) fixed tests/builder_dlss_update_test.cs. This PR deletes that fixture, and test_builder_dlss_update.py with it, because they checked the WPF window's update decision. The merge commit brings #179 in, so there is no conflict.
  • #176 (merged on main) changed only gpu/vk/vk_main.cpp, which this PR does not touch.
  • #175 (merged): its estimates in Strings.cs, MainWindow.xaml(.cs) and longshot_builder.py go with those files. Its recomplauncher.json and make_game.py changes stay.
  • The LongshotLauncher companion, branch docs/builder-no-window, makes the same docs/releases.md edit (cmp-identical). Merge them together.

Kept on purpose (borderline):

  • The portable Builder home (--portable --cli, .longshot-portable, BuilderHome.cs, portable_home.h). RecompLauncher never asks for it, but it still works headless.
  • AppRun --launch: a Linux game folder built with --cli names the AppImage as its builder=.
  • make_game.py's clean-up of a folder from before the bin/ layout (old DLLs beside the launcher). It runs in the launcher's --update of such a folder.
  • make_game.py's antivirus messages, which name "the Longshot Builder folder" and "the zip". They are @@error text the launcher shows, so they are left as they were.
  • ngx_built() in make_game.py, which nothing calls. It was already so on main.

Issues

None.

Checklist

For everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description).
  • Rebased on current main.
  • python -I -B tests/run_all.py run and passing (any failure that also fails on main is named above).
  • Tested in the game, or what wasn't is named under Testing.
  • Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests).
  • Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. (Not a performance change: one suite run each, sizes from one build each.)
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

If applicable

  • Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths. setup.c (Windows only) builds with tools.lock's llvm-mingw and CI's flags, with no -Wall warnings; host/hos_paths.h changes only a comment.
  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • A check under tests/ that reads changed source updated in this PR, not weakened.
  • Docs updated.
## Why Players should only need the Longshot Launcher. The Builder's own windows (the WPF app on Windows, the Tk window in the Linux AppImage) were a second app to keep working beside the launcher, while the launcher only takes each version's Builder for its Python, its tools and `make_game.py`. This makes the Builder a command-line package: the launcher and RecompLauncher see the same entry points, arguments, `@@` lines and exit codes as before, and started by hand it says to get the launcher. ## What changed What the launcher runs, checked in MagicBeanDev/LongshotLauncher's `Core/`: never `LongshotBuilder.exe` or `AppRun`. It runs the release's own Python on `make_game.py` directly (`Core/MakeGameCommand.cs`; `Core/Toolchains.cs`: `LongshotBuilder/tools/python/python.exe` and `LongshotBuilder/tools/nx2/make_game.py` on Windows, `usr/python/bin/python3` and `usr/share/longshot/nx2/make_game.py` from the unpacked AppImage on Linux, which must hold `AppRun` and `usr/share/longshot/tools.lock`). None of those paths change, and `nx2/make_game.py` is untouched. The Builder entry points are RecompLauncher's (`recomplauncher.json`): `--cli --prepare --game {game}` and `--play {home}/Games/Longshot`, on `LongshotBuilder.exe` (the setup) and `Longshot.AppImage`. - **Windows Builder** (`builder/LongshotBuilder`): no WPF any more. - Removed: `MainWindow.xaml(.cs)`, `App.xaml(.cs)`, `Strings.cs`, `Glass.cs`, `Finder.cs`, `Disk.cs`, `Storage.cs`, `ShaderStep.cs`, `BuilderSettings.cs`, `BuildWorkers.cs`, `Updater.cs`, the Inter fonts and the image. Also `PortableArchive.cs`, which nothing called. - New `Program.cs`. `--cli` is `App.Cli` moved over: the same home check first, the same `Tools.Find`, the same lines to stdout and the same `error` line and exit code. The one change in `Cli`: `failure == "cancelled"` is gone, because nothing can cancel a `--cli` run. Anything else (a double-click) shows the launcher message and its link (`https://longshot.magicbean.dev/download`) in a message box, also on stderr, and exits 1. - `Runner.cs`: what `--cli` used, with its environment unchanged. That means `PYTHONIOENCODING`, the home, `LONGSHOT_BUILDER_EXE`, `LONGSHOT_NGX_SDK`/`LONGSHOT_FFX_SDK` removed, `EMSDK`/`RX_CPM`/`WGPU_NATIVE`, and `LONGSHOT_JOBS`/`LONGSHOT_MEM_LIMIT_GB` as inherited. `Check` and `Cancel` (window only) are gone. - `BuilderHome.cs` loses `DefaultGame`, `SavePath` and `LoadPath` (window only). - `LongshotBuilder.csproj`: still `WinExe`, so it opens no console window under the setup or RecompLauncher, and still `net8.0-windows` self-contained, but without `UseWPF`. The published folder goes from 243 files (147 MB) to 186 (72 MB). - **Windows setup** (`builder/setup/setup.c`): kept. It is the zip's `LongshotBuilder.exe`, which RecompLauncher runs with `--cli` and `--play`, and `make_game.py` copies it into every game folder as `longshot.exe`, including the launcher's builds. - `--cli`, `--play` and a game folder's `longshot.exe` are unchanged. - Started any other way, it shows the launcher message and exits, before anything is installed. - `builder_ready` no longer requires WPF's files. - `--repair` is gone, in a later commit (below). - The home error is always a stderr line now. - **Linux AppImage** (`builder/linux`): - Removed: `longshot_builder.py` (the Tk window), `linux_update.py` (its version buttons), `play-diagnostics.sh` (its Play), and `linux_tools.py --gui`'s Tk download window. - `AppRun`: `--cli`, `--play` and `<folder>` are unchanged. `--cli` still runs `linux_tools.py env --install` with no other argument. `--launch <folder>` now plays that folder through `longshot-launch`, for a game folder's `longshot` (`longshot-folder`) when `--cli` built it. Anything else prints the launcher message on stderr, plus a zenity/kdialog box when started outside a terminal with a display, and exits 1. - `longshot-launch` and `longshot-folder` name the launcher in their messages. - The `.desktop` entry stays, because the AppImage format needs one. - **Packaging and CI**: - `scripts/check_windows_files.py` expects no WPF and fails on one. - `scripts/builder_package.py` and `build-windows.yml` comments. - `ci.yml`'s worker check is now `tests/builder_cli` (below). - **Tests**: - Deleted, because they check the windows only: - `test_builder_details_hitbox.py` and `builder_details_hitbox_test.cs` - `test_builder_dlss_update.py`, `test_builder_update_back.py` - `test_builder_scale.py`, `test_builder_free_space.py`, `test_builder_log_read_only.py` - `test_desktop_exec.py` - `test_linux_builder_clock.py`, `test_linux_builder_jobs.py`, `test_linux_builder_stop_reason.py` - `test_linux_play_diagnostics.py`, `test_linux_play_scope.py` - `test_portable_archive.py` - Trimmed to their non-window parts: - `test_builder_status.py`, `test_disk_warning.py`, `test_ffx_sdk.py`, `test_make_game_ngx.py` - `test_pipeline_share.py`, `test_prepare_at_build.py` - `test_linux_update.py`, `test_linux_downgrade.py` (now the folder launcher's dispatch only) - `test_builder_own_python.py`, `test_builder_xml_valid.py` - `test_portable_builder_home.py` with `portable_builder_home_test.cs`, `test_portable_builder_startup.py` - `test_no_release_lookup.py` now also checks that the windows are gone. - `tests/builder_workers` became `tests/builder_cli`. It runs the actual `Runner` against an authored `make_game.py` and checks the arguments, the environment it passes on, the inherited workers and memory, the SDK folders dropped, the lines in order, and each way a run ends: done, `@@error`, silent failure, no Python, the package's Python removed. - `test_linux_tools.py` gains `--launch` and the no-window message. - **Docs**: - README: Compile shaders, the AppImage, Updating, where the files go, DLSS and FSR 4 (the launcher's switches), the pipeline list, Build from source. - CONTRIBUTING: the Builder section and NVIDIA's license text, now in the launcher. - `docs/windows-portable-builder.md`: now for `--portable --cli`. - `docs/windows-builder-runtime.md`, `docs/development.md`, `docs/forgejo-runners.md`, RELEASING.md (the Windows tester's steps). - `docs/releases.md`, which is byte-identical with the launcher's: 3 lines. The launcher's copy needs the same edit. - The two screenshots of the windows are removed. - **Follow-ups after review** (new commits on top; the first two are unchanged): - **Merge main** (d956c9ea), which brings in #176, #178 and #179. - **No Tcl/Tk in the AppImage** (`build(linux)`): - `deps.sh` no longer builds Tk with Xft. - `appimage.sh` no longer copies `libtcl9tk9.0.so`, libXft, libXrender or their licences. - python-build-standalone's own Tcl/Tk, `_tkinter`, `tkinter` and turtle are deleted. Its mark changes, so an existing `build-linux/deps` installs it again. - `libxft-dev` and `libfontconfig1-dev` leave `build-linux.yml` and the Dockerfile, which `test_linux_docker_packages.py` keeps the same. - `test_appimage_licenses.py` now checks that none of this comes back. - **What was kept only for the 2.x Builder is dropped:** - **setup.c:** a game folder's `longshot.exe` starts `bin\longshot.exe` itself. `launch_installed` is gone (it opened an installed Builder with `--launch`), and so are the setup's `--launch` and `--repair`, the old window's Repair. - **The portable game association** (`.longshot_builder_home`, `builder_local=1`): only that Builder launch read it. It is gone from `portable_home.h` (`hb_home_game`, `HB_GAME_HOME`) and from `make_game.py` (`portable_game_home`, `write_game_home`), with `test_portable_game_home.py`. - **The Windows Builder's `--launch`** is gone. - **`longshot-launch`:** no folder now means `~/Games/Longshot` instead of the old window's `builder.ini`. It starts only `bin/longshot`, never the folder's `longshot` (the folder launcher, which would start it again). - **`make_game.reported()`**, which only the Linux window read, goes with its test. - **The antivirus advice names the launcher's folders**, in `docs/common-issues.md`, the README and the website's antivirus guide: - `%LOCALAPPDATA%\LongshotLauncher` (with `toolchains`) and `%LOCALAPPDATA%\Programs\LongshotLauncher`, or `LongshotLauncher-data` for the portable launcher (`Core/LauncherHome.cs`, `LauncherLayout.cs`). - Instead of the 2.x **Repair**: build again, and delete the version's `toolchains` folder if a file is still missing. - **Leftovers:** - `tests/builder_dlss_update_test.cs`, the fixture of the deleted `test_builder_dlss_update.py`. #179 fixed it on main. - `scripts/ngx_sdk.py`'s mention of the Builder's DLSS tick. - **Self-review fixes:** - The README's RecompLauncher link anchor, `#recomplauncher-longshot`, already broken on main. - An unused name lookup in `init_home`. - `BuilderHome.cs`'s "ZIP fallback" comment. ## Flags and settings | Flag | What it does | Default now | Recommendation | Helps on | Doesn't help on | Untested on | |---|---|---|---|---|---|---| | None added. Removed: `linux_tools.py env --gui` (the AppImage's Tk download window), the setup's `--repair` and `--launch`, the Windows Builder's `--launch`. The Builders' `--update <folder>` without `--cli` now gives the launcher message; `--cli --update <folder>` does what it did | - | - | - | - | - | - | ## Measurements main: d956c9ea (2026-11-13; the first two commits were measured against c67cd4a0, the main they were made on) this PR: chore/builder-cli @ 35eabb8e (the suite ran at 7cbb2168; 35eabb8e changes only a README anchor, a comment and setup.c, which Linux does not compile in the suite) Hardware: Ryzen desktop, CachyOS Linux (game-free checks and cross-built Windows files only) Scene: none, no game run Method: - `python -I -B tests/run_all.py --jobs 6` under `nice -n 19`, once on each side. - The Windows files: built as `build-windows.yml` builds them (`dotnet publish -r win-x64 -p:EnableWindowsTargeting=true`, with SDK 10 here targeting net8.0), then `builder_package.py package`/`zip` with the same setup exe on both sides, then `check_windows_files.py`. - The AppImage's Python: built with this branch's `scripts/linux/deps.sh` into a scratch folder. Its Tk share was measured on the same python-build-standalone download, `tar | zstd -19` for the compressed size. main's own Tk build (from source, with Debian's libXft) could not be repeated here, so its `libtcl9tk9.0.so`, libXft and libXrender are not counted. - Line counts: `jj diff --stat`. Nothing here is a performance change. How to reproduce: the same commands in a checkout of each commit | | main @ d956c9ea | this PR @ 35eabb8e | |---|---|---| | run_all.py (one run each) | 464 passed, 3 failed, 69 skipped (d956c9ea) | 454 passed, 2 failed, 65 skipped | | `LongshotBuilder-<v>-windows-x64.zip` | 76,166,401 bytes, 1608 files (c67cd4a0) | 43,118,369 bytes, 1551 files (9f0a3aa8; unchanged since in what the zip holds) | | published Windows Builder folder | 243 files, 147 MB | 186 files, 72 MB | | AppImage's `usr/python`: Tcl/Tk, `_tkinter`, tkinter, turtle | 9,682,524 bytes (2,907,139 as zstd -19), plus main's own Tk and X libraries | 0 | | lines, whole diff (102 files) | | +669 / -8267 | ``` main @ d956c9ea: 464 passed, 3 failed, 69 skipped in 82 s (linux, 6 at once) this PR @ 7cbb2168: 454 passed, 2 failed, 65 skipped in 81 s (linux, 6 at once) FAIL tests/test_bake_portability.py (both: no zstandard module on this PC) FAIL tests/test_display_pointer.py (both: win::rx_option undefined at link, from #178 on main; not touched here) FAIL tests/test_builder_log_read_only.py (main only: no Tk on this PC; removed with the Tk window) 521 = 536 - the 15 deleted tests (13 of the windows, test_builder_status.py, test_portable_game_home.py) ``` ## Testing **Tested:** - The whole game-free suite on Linux, on main and on this PR (above). - The Windows Builder's `--cli`, on Linux. Its framework-dependent Debug build ran under `dotnet` (roll-forward to .NET 10), with `tools/` the repository and the PC's Python, against the real `make_game.py`: - `--cli --check --nup <missing>`: `@@error`, then one `error` line on stdout and stderr, exit 1. - `--cli --prepare --game <missing>`: make_game's own `error` line passed through once, exit 1. - `--cli` with no tools beside it: exit 1, with the right `error` line. - `--cli` with a bad home: exit 1, with the right `error` line. - No arguments, or `--update x`: the launcher message, exit 1. - `tests/builder_cli` as `ci.yml` runs it: 187 assertions pass. - The Windows Builder builds with warnings as errors. - The Windows zip, built as CI builds it, passes `check_windows_files.py`. - `setup.c` compiles with tools.lock's llvm-mingw, CI's flags and `-Wall`, with no warnings. Every Windows-only setup check compiles with llvm-mingw, though none can run here: `test_setup_runtime.py`, `test_setup_runtime_paths.py`, `test_portable_setup_paths.py`, `test_portable_setup_transaction.py`, `test_portable_setup_start.py` and `tests/portable_setup_home_test.c`. - The AppImage's Python without Tcl/Tk, built by `deps.sh`: - numpy, capstone, unicorn, zstandard, lz4, ssl, sqlite3 and lzma import. - `import tkinter` fails. - `make_game.py --help` and `linux_tools.py --help` run. - `AppRun` in a stand-in image (`test_linux_tools.py`): - `--cli` stops without the tools, and runs `make_game.py` once they are found. - `--play` and `--launch` need no build tool. - Anything else gives the message and downloads nothing. - `longshot-launch` (`test_longshot_launch.py`): - It starts `bin/longshot`, and only that. - No folder means `~/Games/Longshot`. - Relative folders work. - A folder without `bin/longshot` is refused. - LongshotLauncher's core checks, with the companion commit: `tests/test_launcher_core.py --strict --longshot <this branch>`, 632 checks pass. They read `make_game.py`, which changed. **Not tested:** - Nothing ran on Windows or under Wine (none here): the setup's `--cli` install and build, its message box, a game folder's `longshot.exe`, and `check_windows_files.py --wine`. - No AppImage was packed: `appimage.sh` and `check_player_build.sh` need the build tools and the Vulkan back end. - No game run. **Needs other testers:** - Windows 10/11, with a release zip built from this commit: `LongshotBuilder.exe --cli --prepare --game <your copy>` installs the tools, builds and exits 0, the folder's `longshot.exe` starts the game, and double-clicking `LongshotBuilder.exe` or `LongshotBuilder\LongshotBuilder.exe` shows only the launcher message, with no console window and nothing installed (T-TS6P). - Linux: the nightly AppImage built from this commit. Run `--cli --prepare --game <copy>`, then start the folder's `longshot`, expecting the build and the game, with no Tk error (T-ZMS7). ## Screenshots Nothing on screen, apart from the new message box and dialog, which were not captured. ## Risk and rollback - Someone who starts the Builder by hand gets the message instead of the window. That is the intent. - Game folders from 2.x Builders lose their launcher page: - On Windows, a 2.x folder's own old `longshot.exe` still opens an installed Builder with `--launch`, which now gives the message. Folders made from now on start their game themselves. - On Linux, `longshot-folder` still starts its `builder=` with `--launch`: the launcher, or the AppImage for a `--cli` build, which plays it. - A 2.x Linux folder whose game is `longshot` itself (no `bin/`) is no longer started by `--play`. - A portable (`--portable --cli`) build no longer ties the game folder to that Builder. Nothing reads the tie any more. - The AppImage has no Tk. Anything that imported `tkinter` would fail; nothing in the repository does. - Reverting the commits restores everything. Nothing is migrated or deleted on players' PCs. ## Reviewer notes Start with `builder/LongshotBuilder/Program.cs` against the old `App.xaml.cs`, then `builder/linux/AppRun` and `setup.c`'s `wWinMain`. Other PRs: - **#179** (merged on main) fixed `tests/builder_dlss_update_test.cs`. This PR deletes that fixture, and `test_builder_dlss_update.py` with it, because they checked the WPF window's update decision. The merge commit brings #179 in, so there is no conflict. - **#176** (merged on main) changed only `gpu/vk/vk_main.cpp`, which this PR does not touch. - **#175** (merged): its estimates in `Strings.cs`, `MainWindow.xaml(.cs)` and `longshot_builder.py` go with those files. Its `recomplauncher.json` and `make_game.py` changes stay. - **The LongshotLauncher companion**, branch `docs/builder-no-window`, makes the same `docs/releases.md` edit (`cmp`-identical). Merge them together. Kept on purpose (borderline): - **The portable Builder home** (`--portable --cli`, `.longshot-portable`, `BuilderHome.cs`, `portable_home.h`). RecompLauncher never asks for it, but it still works headless. - **`AppRun --launch`**: a Linux game folder built with `--cli` names the AppImage as its `builder=`. - **`make_game.py`'s clean-up of a folder from before the `bin/` layout** (old DLLs beside the launcher). It runs in the launcher's `--update` of such a folder. - **`make_game.py`'s antivirus messages**, which name "the Longshot Builder folder" and "the zip". They are `@@error` text the launcher shows, so they are left as they were. - **`ngx_built()` in `make_game.py`**, which nothing calls. It was already so on main. ## Issues None. ## Checklist ### For everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`). - [x] Rebased on current `main`. - [x] `python -I -B tests/run_all.py` run and passing (any failure that also fails on `main` is named above). - [x] Tested in the game, or what wasn't is named under Testing. - [x] Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests). - [x] Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. (Not a performance change: one suite run each, sizes from one build each.) - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### If applicable - [x] Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths. setup.c (Windows only) builds with tools.lock's llvm-mingw and CI's flags, with no -Wall warnings; host/hos_paths.h changes only a comment. - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] A check under `tests/` that reads changed source updated in this PR, not weakened. - [x] Docs updated.
Players only need the Longshot Launcher, which runs each version's own Python on
nx2/make_game.py and never starts the Builder. The Builder keeps what
RecompLauncher and old game folders start (--cli, --play, a game folder's
longshot.exe) and loses its windows:

- Windows: the WPF window and everything only it used are gone; Program.cs has
  App's --cli as it was, --launch <folder> starts that folder's game, and
  anything else shows the launcher message. No WPF in the package: 41 MB zip
  instead of 72.
- The setup shows the same message, and installs nothing, unless it is started
  with --cli; builder_ready no longer asks for WPF's files.
- Linux: the Tk window (longshot_builder.py, linux_update.py, its Play's
  play-diagnostics.sh) and linux_tools.py --gui are gone; AppRun --launch plays
  the folder, anything but --cli, --play and a folder prints the message.
- Tests of the windows removed, mixed ones trimmed; tests/builder_cli checks
  the actual Runner as --cli runs it.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
docs: the Builder has no window; players use the launcher
All checks were successful
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 7s
CI / Conventional Commit title (pull_request) Successful in 5s
CI / Workflow lint (actionlint) (pull_request) Successful in 9s
Third-party parts / As their notes say (pull_request) Successful in 14s
9f0a3aa801
The README, CONTRIBUTING, RELEASING and docs/ no longer describe the Builder's
windows, ticks and buttons: the launcher's settings, the command line
(--cli, --cli --update) and the portable setup's --portable --cli instead.
docs/releases.md, kept byte-identical with LongshotLauncher's, changes in
three lines; the launcher's copy needs the same edit.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
Co-Authored-By: Claude Fable 5.2 <[email protected]>
Nothing in the AppImage has a window any more, so deps.sh no longer builds Tk
with Xft, appimage.sh no longer copies libtcl9tk9.0.so, libXft and libXrender
or their licences, and python-build-standalone's own Tcl/Tk, _tkinter,
tkinter and turtle are deleted with idlelib. libxft-dev and libfontconfig1-dev
leave the CI image and the Dockerfile (only Tk used them). The Python's mark
changes so an existing build-linux/deps installs it again.

About 9.7 MB less uncompressed in usr/python (2.9 MB as zstd -19).

Co-Authored-By: Claude Fable 5.2 <[email protected]>
- setup.c: a game folder's longshot.exe starts bin\longshot.exe itself; it no
  longer opens an installed Builder with --launch (launch_installed), and the
  setup no longer takes --launch or --repair (the old window's Repair).
- portable_home.h and make_game.py: the game folder's association with a
  portable Builder (.longshot_builder_home, builder_local=1) is gone; only the
  Builder's launch from a game folder read it. A portable --cli home stays.
- The Windows Builder's --launch is gone; AppRun keeps it, since a Linux game
  folder built with --cli names the AppImage as its builder=.
- longshot-launch: no folder means ~/Games/Longshot, not the old window's
  builder.ini, and it starts only bin/longshot, never the folder's own
  longshot (that is the folder launcher, which would start this again).
- make_game.reported(), which only the Linux window read, and its test.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
common-issues, the README and the website's antivirus guide told players to
exclude %LOCALAPPDATA%\LongshotBuilder and press Repair, both the 2.x
Builder's. The launcher keeps each version's builder and tools in
%LOCALAPPDATA%\LongshotLauncher\toolchains (LauncherHome.cs), the installed
program in %LOCALAPPDATA%\Programs\LongshotLauncher and a portable one's data
in LongshotLauncher-data beside it (LauncherLayout.cs). Instead of Repair:
build again, and delete the version's toolchains folder if a file is still
missing. The README's file table and uninstall line follow.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
- tests/builder_dlss_update_test.cs: the C# fixture of
  test_builder_dlss_update.py, deleted with the WPF window; #179's fix to it
  came in with main.
- scripts/ngx_sdk.py: --accept-nvidia-license is the launcher's DLSS switch,
  not the Builder's tick.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
chore(builder): self-review fixes
All checks were successful
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
Website / Website on Cloudflare (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 5s
CI / Workflow lint (actionlint) (pull_request) Successful in 12s
Third-party parts / As their notes say (pull_request) Successful in 12s
PR description / Description follows the template (pull_request_target) Successful in 3s
35eabb8e29
- README: the RecompLauncher link's anchor is #recomplauncher-longshot (the
  heading's own; broken on main already).
- setup.c: init_home no longer works out the exe's name, which only the game
  folder's Builder launch used.
- BuilderHome.cs: no "ZIP fallback" (PortableArchive, gone) in its comment.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
HumanBean changed title from WIP: chore(builder): the Builder is command-line only; the launcher is the app to chore(builder): the Builder is command-line only; the launcher is the app 2026-11-13 11:35:06 +00:00
Author
Owner

New commits (on top of 9f0a3aa8; main merged in at 2d604928, with #176, #178 and #179):

  • c404e5ae: the AppImage's Python ships without Tcl/Tk: about 9.7 MB less in usr/python, and libXft/libXrender are gone too.
  • 14b9a8b5: drops everything that was kept only for the 2.x Builder (a game folder's longshot.exe starts bin/longshot.exe itself; no --launch, no --repair, no portable game-home link).
  • 7bcb46ad: the antivirus advice names the launcher's folders.
  • 7cbb2168: the window's last leftovers.
  • 35eabb8e: fixes from self-review (a broken README anchor that is also broken on main, a dead lookup, a stale comment).

Companion PR: MagicBeanDev/LongshotLauncher#34 (docs/releases.md stays identical in both repos). Test requests: T-TS6P (Windows), T-ZMS7 (Linux).

New commits (on top of 9f0a3aa8; main merged in at 2d604928, with #176, #178 and #179): - c404e5ae: the AppImage's Python ships without Tcl/Tk: about 9.7 MB less in usr/python, and libXft/libXrender are gone too. - 14b9a8b5: drops everything that was kept only for the 2.x Builder (a game folder's longshot.exe starts bin/longshot.exe itself; no --launch, no --repair, no portable game-home link). - 7bcb46ad: the antivirus advice names the launcher's folders. - 7cbb2168: the window's last leftovers. - 35eabb8e: fixes from self-review (a broken README anchor that is also broken on main, a dead lookup, a stale comment). Companion PR: https://git.magicbean.dev/MagicBeanDev/LongshotLauncher/pulls/34 (docs/releases.md stays identical in both repos). Test requests: T-TS6P (Windows), T-ZMS7 (Linux).
HumanBean deleted branch chore/builder-cli 2026-11-13 11:37:56 +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/Longshot!181
No description provided.