Skip to content

fix(setup): recover incomplete self-contained Builder runtimes - #2449

Merged
hckrman101 merged 5 commits into
NotRexed:mainfrom
Arkex-ai:fix/windows-runtime-recovery
Nov 11, 2026
Merged

hckrman101 merged 5 commits into
NotRexed:mainfrom
Arkex-ai:fix/windows-runtime-recovery

Conversation

@Arkex-ai

@Arkex-ai Arkex-ai commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Windows setup can accept a Builder executable and installed marker even when its private .NET runtime is missing. Incomplete installations now enter recovery, and incomplete staging stops before publication. The diagnostic keeps the affected paths and possible antivirus quarantine cause so retrying setup is actionable; the original cause in #2423 remains unconfirmed.

Technical changes

  • Use one startup-file check before installed reuse, staged publication and fast launch; reject missing/empty components and directories in place of files.
  • Preserve the accepted portable-home paths and rollback publication from feat(builder): add relocatable Windows portable installations #2367. Restore the quarantine/history hint, executable path and staging folder in the failure message.
  • Execute the actual recovery and portable-startup boundaries with authored files, including missing-runtime refusal followed by recovery. Keep checked downloads, explicit repair and the direct-game fallback.

Validation

Head 66f5ba8d8c89ba14330f8fbf118ff0d9b7ff5f47, rebased on main 6f4f28ac.

  • 56 real-Win32 file cases pass. Three independently removed entry guards are rejected by causal regressions; 14 portable-startup scenarios pass, including a missing runtime that cannot start a process and a restored runtime that can.
  • The complete Windows setup compiles and links with llvm-mingw. The refreshed native diagnostic below uses the actual readiness guard and message function with fictitious paths; no installation or game is involved.
  • Full Windows suite: 408 / 2 / 32 versus exact base 406 / 2 / 32 (passed / failed / skipped). Failing check and case identities match: NUP link tests and the VRAM-row fixture. The earlier portable fixture integration failure was corrected before this run. This is not an all-green local suite.
  • Current-head hosted CI is pending. Current Linux GPU/game, complete repair on the rebased source and the reporter's installation history are not validated. This checks the directory-based WPF startup contract, not every optional assembly or installed-file checksum.

Controlled incomplete-runtime diagnostic

Earlier-head validation

On 4171896d, all applicable hosted checks passed. A disposable controlled installation with EXE/marker present and coreclr.dll missing recovered through actual downloads, verified/unpacked pinned official v2.1.0, and ran its private .NET8.0.33 managed CLI help with exit0; original source files stayed unchanged. This was not the reporter's unconfirmed missing-file cause or a full game test, and has not been repeated on the rebased head.

Full suites on dead3fcd versus base 3e95ca68: Windows378/3/31 versus376/3/31; Linux385/2/25 versus385/2/23, with matching failing check identities. These are historical results, not checks of the current head.

Current-head workflow Result
Game-free source regressions Queued
Linux AppImage Running
PR title Queued
Windows builder Queued

@Joey-Magnus Joey-Magnus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builder_ready (setup.c:529) checks the 12 startup files, which matches the csproj (SelfContained=true, PublishSingleFile=false), and it's used in all three places that matter. The tests are thorough.

One fix before merge: the new error after unpacking (setup.c:776) drops the old antivirus hint and the folder path. Defender quarantining files is a known cause (the "Wacatac" worklist row), and in that case "Run the setup again" just loops. Please put the hint and the path back.

Validate required startup components before installed reuse, staged publication and fast launch. Exercise real Win32 file readiness and reject independent boundary-removal mutations without launching any Builder fixture.

Assisted-by: OpenAI Codex
Capture the native production error dialog using an authored missing-runtime fixture; distinguish it from complete installation validation.

Assisted-by: OpenAI Codex
Exercise the accepted home and publication helpers while checking the actual failure retains the antivirus hint and staging folder.

Assisted-by: OpenAI Codex
Refresh the authored native error-dialog capture and explain how the reported staging path helps investigate repeated quarantines.

Assisted-by: OpenAI Codex
Include the production readiness helper and authored required files; verify an incomplete portable runtime never starts a process and recovers once restored.

Assisted-by: OpenAI Codex
@Arkex-ai
Arkex-ai force-pushed the fix/windows-runtime-recovery branch from 4171896 to 66f5ba8 Compare November 11, 2026 22:03
@Arkex-ai

Copy link
Copy Markdown
Contributor Author

Restored the quarantine/history hint, affected executable and staging-folder paths, and refreshed the controlled native screenshot.

Rebased on 6f4f28ac, preserving #2367's portable-home paths and rollback publication. That integration also needed the portable startup fixture to include the production readiness helper and authored runtime files; its 14 scenarios now cover refusing an incomplete runtime and launching after restoration. The 56 file cases, three guard mutations and complete setup link pass. Full-suite comparison and current-head CI status are recorded in the updated description; the original reporter's cause remains unconfirmed.

@hckrman101 hckrman101 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. builder_ready is bounded correctly (path length checked before each copy, the EXE itself is checked at i=0, directories and zero-size files rejected) and it replaces the bare exists-check in all three places: installed reuse, the post-unpack gate before publish_install, and launch_installed. A missing runtime now falls through to recovery instead of launching a Builder that cannot start.

Joey-Magnus's point about the dropped antivirus hint and folder path is fixed: the new message names the staged exe, the staging folder and the quarantine/history check, and says nothing was published. The #2367 portable-home paths and rollback publication are untouched.

CI is green on this head (Python source checks on Linux and Windows, Windows builder package and setup, Windows Vulkan, AppImage). The PR body is upfront about what is not validated (reporter's real cause, Linux game, the 2 known local failures matching base).

Nit, no action needed: the 12-file list has to follow the csproj publish format; the comment says so, and the new tests would catch drift on the setup side but not a csproj change.

@hckrman101
hckrman101 merged commit 2dfe901 into NotRexed:main Nov 11, 2026
15 checks passed
hckrman101 pushed a commit that referenced this pull request Nov 12, 2026
The worklist was behind the forum and the merges. Since v2.1.0, many fix
PRs have merged, several rows already shipped, and the most-reported
problems in Discord #bug-reporting had no row. This PR brings
`docs/worklist.md` back in line, following the rules in the worklist and
in `docs/workflow.md`.

## Method
- **Forum snapshot.** All 409 #bug-reporting posts as of Nov 11, ~11:10
PM ET (Nov 7-11). Each post is dated by its thread ID, so the submit
time is in ET.
- **How dates were used.**
- v2.1.0 was cut from `main` at about 8:32 PM ET on Nov 10 and published
at 9:29 PM ET. A PR merged before the cut counts as shipped; I checked
this with `git merge-base --is-ancestor <merge commit> v2.1.0`.
- A report sent before a fix shipped and not repeated after it counts as
fixed.
- A report sent after v2.1.0, or before a fix that merged later, counts
as still open or waiting for a release.
- **Score.** Severity x reach x confidence.
- Reach comes from workflow.md's 2026-11-10 reporter shares. Where the
affected subset is unknown, it is marked as an upper bound.
- Confidence is 0.7 only where the GitHub tracker has logs from several
commenters; otherwise it is 0.4.
- **Owners.** New rows have no owner. Existing owners are kept.

## Changes
- **Added 20 rows (18 Open, 2 Fixed-waiting).**
- Open: RAM/VRAM fill-up to OOM (#993, 5.6; 13 threads after v2.1.0),
shader preparation stalls (3.2), AMD Windows crashes (#996, 2.9),
CPU-bound fps in Castle Town and Hyrule Field (#995), invisible objects
and doors (#1002), build.py stopped on v2.1.0, cutscene audio desync,
shadow artifacts, coloured lighting, HDR black screen and flicker, frame
generation stutter, the block grid around lights and fog, the v2.1.0
update failing, AF outlines, wrong button glyphs, Steam Deck at 6 fps,
Linux AMD slower than Windows, and the FSR 4 tick not rebuilding.
- Fixed-waiting: the pick-up counter above 60 fps (#2006) and RADV
device lost after the intro (#2362).
- **Updated 6 rows.**
- The Link-jump row is now the "above a 60 fps cap" row (#1742),
covering the Scarecrow's Song softlock, Gohma and the item hanging above
Link's head. It goes from S2 to S1 and is re-scored from 1.2 to 3.5.
- New forum links or scores on the antivirus, Intel black screen (0.11
to 0.2, #999 has logs), fairy grotto, voices (#2506) and RX 580 (#2343)
rows.
- **Moved 10 rows to Fixed, waiting for a release.** #2545 (ground
garbling), #2451 (RTX 30 crash), #2286, #2275, #2449, #2096, #2406,
#2515, #1954 and #2367.
- **Deleted 8 rows** whose fix shipped in v2.1.0: #1792, #1922, #1819,
#1863, #1447, #1451, #1769-#1810 and the HDR10 overlay.

## Not done
- PRs listed as "candidate" fixes are matched by title and description
only. None is confirmed against the reports.
- Long forum threads were judged from their summaries.
- `tests/run_all.py` was not run (docs-only change).

Co-authored-by: Joey Magnus <joey.magnus@cxalloy.com>
madebyjordan added a commit to madebyjordan/Longshot that referenced this pull request Nov 12, 2026
…ry button can be pressed

scripts/launcher/dummy.ps1 makes a world afresh at each start of scripts/launcher/live.ps1 (build/launcher/live): the
test rig's releases (rig.py) served on 127.0.0.1, v2.1.0 installed with the real setup beside it, a game folder holding
v2.1.0 whose game is a stand-in that says "Play works" (dummygame.c), and an empty game file chosen for Build. The
builders' python.exe is the rig's stand-in for make_game.py, so Update installs v2.2.0's builder from that server and
"builds" the folder in about 10 seconds; -Fail makes every build stop half way.

- Builders.DummyReleases (HOOKSHOT_DUMMY_RELEASES, development only): a release's builder is installed from
  <url>list-<tag>.txt, and the launcher's own downloads are refused (a first builder from GitHub, AMD's FSR runtime).
- rig.py: its releases and v2.1.0 have the runtime files the setup checks since NotRexed#2449 (builder_ready), without which
  the setup refused every made-up builder; tests/builder_launcher/rig/run.ps1's setup checks pass again.
- fakepy.c: FAKE_GAME_EXE, the game a build from game files makes.

Checked off-screen against the made-up releases: Update (v2.1.0 -> v2.2.0, builder installed from the local server),
Build (a new folder at v2.2.0 with the stand-in game) and a failing Update (the folder left at v2.1.0) all end as they
should, the real %LOCALAPPDATA%\HookshotBuilder is untouched, and no stand-in is left running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants