WIP: feat(ui): add an opt-in Hidden HUD mode #774

Draft
simonwjackson wants to merge 6 commits from simonwjackson/Longshot:feat/hud-hidden into main
Contributor

Type: feat · Risk: medium · Tested on: Linux, RX 7900 XT · Needs: Windows and item-message testing

Why

Players who want an unobstructed game view cannot hide the gameplay HUD today. This adds an opt-in Hidden mode while keeping Normal as the default.

See #95. I searched the open and closed PRs and issues; #95 owns HUD layout, not visibility.

What changed

Graphics → Screen gains HUD mode, Hidden/Normal, saved as hud_mode. The choice applies on the next start, not live. The existing restart indicator and confirmation explain this before the player restarts.

  • Menu: menu_hud_mode() in gpu/vk/vk_menu.cpp reads the existing restart state's startup value. The saved row can change without changing any canvas in the running session, including a canvas created later. There is no separate HUD latch.
  • Visibility: nx2/oot_wide.py collapses only six recognized gameplay canvases when they are constructed. Normal adds no guest reads. It does not change the layout's source projection.
  • Shared map: hos_oot_hud_screen() in host/oot_hud.c, installed by patch_hud_screen() in nx2/oot_patches.py, distinguishes the minimap from the full map using MapMenu_00:N_MapIcon_00, as #95 does. It temporarily collapses the map canvas only during its minimap update and restores every coefficient before returning. The update always runs; skipping it would also stop the transition to the full map. No saved-state writes, retained guest pointers or visibility cache.
  • #95 merged during this work. This branch includes main 53f96d7805 and preserves its X/Y scales. There is no new docking, sizing, Double mode, renderer tag or dependency on unmerged #142. The unpublished branch was then rebased linearly onto that same main; its source tree did not change. Llun agreed to separate visibility work in #95 comment 20344.
  • Tests execute the injected C, the actual host helper and the menu's actual restart-state logic. The map fixture checks scoped restoration across ordinary, early and tail returns. Existing source-reading checks remain intact. README and the options-file reference document the restart requirement.

Measurements

Verdict: The listed visibility/restart checks pass. Normal-mode median FPS is within 1% of main at both shapes. Two narrow-screen PR runs were much slower; a third complete interleaved triplet returned near the first round. The cause was not isolated; all runs, including the slow ones, are retained. No general speed or zero-cost claim.

Before: main @ 53f96d7805
After: this PR @ cdc248dc0c

Source identity: the executable was built from pre-rebase 08db9fd8214ca875d14dadeb657640b67a9c9f5f, and its build stamp still says that. git rev-parse 08db9fd^{tree} cdc248d^{tree} gives 34b68817a2 for both that commit and cdc248dc0c29725b022fe7d8aa0be675ca3a739a. Head d3ceb71287310c4de5bce309600f258d19342d70 adds only the fifteen tested-run records after that code commit. The rebase changed history only; all tracked file contents and modes are byte-identical. The proofs, suite and timings therefore cover the rebased source without a rebuild.

Hardware: NixOS 26.11, Linux 7.2.7; AMD Radeon RX 7900 XT (RADV, Mesa 26.2.3); Ryzen 5 7600X, 30.56 GiB Linux MemTotal (32,048,408 KiB); private headless Sway/Xwayland.
Scene: copied Castle Town gatehouse save, stationary by the wooden door; output/drawable 1920x1080 and 2448x1848. Upscaler Off, render resolution 100%, FG/HDR off, uncapped, audio off, compute mesh fallback, udmabuf access.
Method: main / PR Normal / PR Hidden, interleaved twice at 1920x1080 and three times at 2448x1848; 30 s warm-up after reaching the scene, then 45 s of native FPS log samples. The table reports each run's median and the median of runs. The third narrow triplet followed the slow second-round PR samples; it does not replace them. Those slow runs show higher render-thread job elapsed time (not CPU-cycle measurements), while GPU time stays around 10.4–10.6 ms. Normal still has host-call overhead.
How to reproduce: use the same save and options in separate main/PR folders; set HUD mode before each PR launch, not during a sample.

Shape / round Before: main @ 53f96d7 After: this PR @ cdc248d (Normal) After, Hidden: this PR @ cdc248d
1920x1080, run 1 59.50 60.10 60.70
1920x1080, run 2 60.00 60.30 58.80
1920x1080, median of runs 59.75 60.20 59.75
2448x1848, run 1 58.80 58.35 58.95
2448x1848, run 2 58.45 22.70 33.30
2448x1848, run 3 59.10 59.25 58.70
2448x1848, median of runs 58.80 58.35 58.70

1920x1080: Normal +0.75%, Hidden +0.00% relative to main.

2448x1848: Normal -0.77%, Hidden -0.17% relative to main.

All FPS samples and original first/last log lines per run

1920x1080-r1-main — 59.50 FPS median; 21 samples.

45.4, 44.2, 38.1, 53.3, 60.6, 61.4, 59.9, 60.3, 60.2, 60.1, 61.0, 59.3, 59.8, 59.4, 60.6, 59.5, 58.1, 58.6, 56.6, 59.4, 61.1
[hos host] vk: 26520 presents, 45.4 fps; a frame: 1297 draws (0 skipped), 107 dispatches, 161 passes, 160 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (2159 ms), 0 programs (10 failed), 1416 textures (3439 MB)
[hos host] vk: 28920 presents, 61.1 fps; a frame: 1281 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (2159 ms), 0 programs (10 failed), 1380 textures (3166 MB)

1920x1080-r1-normal — 60.10 FPS median; 21 samples.

59.0, 60.3, 59.9, 59.6, 59.8, 61.1, 60.4, 52.0, 59.4, 58.8, 53.3, 51.9, 31.3, 60.4, 61.4, 62.1, 62.2, 60.1, 61.5, 62.2, 62.0
[hos host] vk: 18000 presents, 59.0 fps; a frame: 1285 draws (0 skipped), 103 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1389 ms), 0 programs (10 failed), 1324 textures (3117 MB)
[hos host] vk: 20400 presents, 62.0 fps; a frame: 1271 draws (0 skipped), 102 dispatches, 161 passes, 155 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1389 ms), 0 programs (10 failed), 1323 textures (3108 MB)

1920x1080-r1-hidden — 60.70 FPS median; 23 samples.

61.0, 59.9, 60.7, 60.2, 60.3, 58.9, 59.8, 60.3, 60.7, 60.9, 61.0, 61.0, 61.0, 61.1, 60.6, 60.7, 61.7, 60.5, 61.9, 61.8, 61.5, 60.9, 59.4
[hos host] vk: 4200 presents, 61.0 fps; a frame: 1286 draws (0 skipped), 103 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (7368 ms), 0 programs (10 failed), 1325 textures (3211 MB)
[hos host] vk: 6840 presents, 59.4 fps; a frame: 1287 draws (0 skipped), 102 dispatches, 161 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (7368 ms), 0 programs (10 failed), 1315 textures (3093 MB)

1920x1080-r2-main — 60.00 FPS median; 22 samples.

60.8, 60.6, 59.6, 60.1, 60.2, 60.7, 61.0, 60.0, 60.6, 58.6, 59.5, 59.4, 59.7, 60.7, 58.1, 58.6, 59.2, 60.0, 60.0, 61.0, 60.0, 60.5
[hos host] vk: 30240 presents, 60.8 fps; a frame: 1292 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.1 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1308 ms), 0 programs (10 failed), 1323 textures (3097 MB)
[hos host] vk: 32760 presents, 60.5 fps; a frame: 1295 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1308 ms), 0 programs (10 failed), 1348 textures (3140 MB)

1920x1080-r2-normal — 60.30 FPS median; 22 samples.

59.7, 60.0, 60.6, 61.1, 60.5, 59.9, 60.2, 60.6, 60.0, 60.3, 60.0, 60.3, 60.8, 60.9, 59.8, 59.7, 61.5, 60.4, 60.3, 59.7, 60.9, 59.7
[hos host] vk: 30120 presents, 59.7 fps; a frame: 1295 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1352 ms), 0 programs (10 failed), 1301 textures (3091 MB)
[hos host] vk: 32640 presents, 59.7 fps; a frame: 1292 draws (0 skipped), 105 dispatches, 162 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1352 ms), 0 programs (10 failed), 1334 textures (3116 MB)

1920x1080-r2-hidden — 58.80 FPS median; 22 samples.

59.5, 59.9, 60.6, 60.5, 59.9, 59.8, 60.7, 59.1, 58.9, 52.6, 54.4, 57.2, 59.3, 55.8, 58.5, 59.3, 58.1, 58.7, 57.6, 56.1, 57.5, 56.0
[hos host] vk: 16200 presents, 59.5 fps; a frame: 1291 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1318 ms), 0 programs (10 failed), 1309 textures (3178 MB)
[hos host] vk: 18720 presents, 56.0 fps; a frame: 1297 draws (0 skipped), 105 dispatches, 162 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1318 ms), 0 programs (10 failed), 1345 textures (3122 MB)

2448x1848-r1-main — 58.80 FPS median; 22 samples.

57.1, 57.2, 59.5, 59.6, 58.2, 57.7, 58.6, 58.6, 57.3, 59.0, 60.9, 58.3, 59.3, 58.1, 60.2, 58.3, 59.6, 59.8, 59.3, 59.0, 58.6, 59.0
[hos host] vk: 25080 presents, 57.1 fps; a frame: 1112 draws (0 skipped), 105 dispatches, 154 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1421 ms), 0 programs (10 failed), 1322 textures (3578 MB)
[hos host] vk: 27600 presents, 59.0 fps; a frame: 1108 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1421 ms), 0 programs (10 failed), 1297 textures (3359 MB)

2448x1848-r1-normal — 58.35 FPS median; 22 samples.

57.8, 58.3, 57.0, 57.5, 57.9, 59.0, 59.6, 58.4, 59.9, 56.7, 58.4, 59.5, 57.8, 56.8, 58.5, 59.8, 58.4, 58.0, 56.9, 57.1, 59.6, 59.0
[hos host] vk: 25320 presents, 57.8 fps; a frame: 1109 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1432 ms), 0 programs (10 failed), 1304 textures (3365 MB)
[hos host] vk: 27840 presents, 59.0 fps; a frame: 1105 draws (0 skipped), 104 dispatches, 154 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1432 ms), 0 programs (10 failed), 1296 textures (3272 MB)

2448x1848-r1-hidden — 58.95 FPS median; 22 samples.

57.2, 59.8, 58.6, 59.3, 58.9, 59.5, 57.8, 59.0, 59.1, 58.2, 58.0, 57.9, 59.5, 58.9, 59.6, 57.3, 59.2, 59.6, 58.8, 59.3, 58.6, 59.7
[hos host] vk: 27000 presents, 57.2 fps; a frame: 1120 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1387 ms), 0 programs (10 failed), 1322 textures (3482 MB)
[hos host] vk: 29520 presents, 59.7 fps; a frame: 1106 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1387 ms), 0 programs (10 failed), 1296 textures (3258 MB)

2448x1848-r2-main — 58.45 FPS median; 22 samples.

56.2, 58.9, 58.4, 58.9, 58.3, 58.5, 58.9, 59.0, 60.4, 58.5, 57.8, 58.3, 58.1, 57.4, 59.0, 58.3, 60.8, 60.9, 59.0, 57.6, 58.4, 57.0
[hos host] vk: 26400 presents, 56.2 fps; a frame: 1125 draws (0 skipped), 105 dispatches, 155 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1363 ms), 0 programs (10 failed), 1298 textures (3275 MB)
[hos host] vk: 28920 presents, 57.0 fps; a frame: 1110 draws (0 skipped), 104 dispatches, 155 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1363 ms), 0 programs (10 failed), 1302 textures (3277 MB)

2448x1848-r2-normal — 22.70 FPS median; 9 samples.

23.2, 23.0, 22.4, 22.7, 22.2, 22.6, 23.1, 22.1, 24.5
[hos host] vk: 5280 presents, 23.2 fps; a frame: 1105 draws (0 skipped), 112 dispatches, 149 passes, 176 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (1457 ms), 0 programs (10 failed), 1305 textures (3672 MB)
[hos host] vk: 6240 presents, 24.5 fps; a frame: 1112 draws (0 skipped), 111 dispatches, 150 passes, 175 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (1457 ms), 0 programs (10 failed), 1259 textures (3280 MB)

2448x1848-r2-hidden — 33.30 FPS median; 12 samples.

27.6, 26.3, 33.5, 33.9, 33.6, 33.2, 33.3, 33.2, 33.0, 33.6, 33.7, 33.3
[hos host] vk: 3000 presents, 27.6 fps; a frame: 1111 draws (0 skipped), 110 dispatches, 152 passes, 171 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (5775 ms), 0 programs (10 failed), 1309 textures (3628 MB)
[hos host] vk: 4320 presents, 33.3 fps; a frame: 1102 draws (0 skipped), 106 dispatches, 152 passes, 166 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (5775 ms), 0 programs (10 failed), 1266 textures (3246 MB)

2448x1848-r3-main — 59.10 FPS median; 22 samples.

59.4, 59.1, 61.4, 60.4, 59.0, 58.0, 60.3, 59.1, 58.3, 56.9, 59.2, 58.6, 59.1, 59.6, 58.3, 58.7, 57.2, 60.0, 58.7, 59.0, 60.5, 60.3
[hos host] vk: 29640 presents, 59.4 fps; a frame: 1121 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (3386 ms), 0 programs (10 failed), 1320 textures (3504 MB)
[hos host] vk: 32160 presents, 60.3 fps; a frame: 1121 draws (0 skipped), 105 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (3386 ms), 0 programs (10 failed), 1298 textures (3291 MB)

2448x1848-r3-normal — 59.25 FPS median; 22 samples.

58.5, 58.3, 59.2, 58.3, 60.3, 61.6, 59.6, 59.7, 60.9, 59.3, 60.3, 59.2, 58.3, 58.8, 57.7, 58.3, 61.0, 59.0, 59.1, 60.2, 60.0, 61.1
[hos host] vk: 29160 presents, 58.5 fps; a frame: 1116 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1258 ms), 0 programs (10 failed), 1314 textures (3458 MB)
[hos host] vk: 31680 presents, 61.1 fps; a frame: 1108 draws (0 skipped), 105 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1258 ms), 0 programs (10 failed), 1294 textures (3259 MB)

2448x1848-r3-hidden — 58.70 FPS median; 19 samples.

58.6, 58.7, 59.5, 57.5, 57.5, 56.9, 59.0, 59.2, 59.3, 58.6, 59.0, 58.8, 60.2, 59.2, 58.6, 59.3, 57.6, 53.2, 29.5
[hos host] vk: 21720 presents, 58.6 fps; a frame: 1107 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (2036 ms), 0 programs (10 failed), 1299 textures (3292 MB)
[hos host] vk: 23880 presents, 29.5 fps; a frame: 1112 draws (0 skipped), 110 dispatches, 151 passes, 168 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (2036 ms), 0 programs (10 failed), 1298 textures (3291 MB)

All original log lines and measured JSON remain in the isolated aka evidence directories. The list above includes every FPS sample; the raw lines shown are the first and last of each interval.

Flags and settings

One menu row and ini key. No new environment switch.

Flag What it is Before this PR After this PR Effect Helps / doesn't help / untested Recommendation
HUD mode; hud_mode 0 Hidden, 1 Normal No row; gameplay HUD visible 1 Normal After a restart, Hidden removes gameplay health, action prompts and minimap. Normal plus a restart restores them. Helps an unobstructed view; does not position or enlarge the HUD. Windows and other GPUs remain untested. Keep Normal as default; Hidden is opt-in because it removes health and navigation information.

Testing

Tested:

  • Both full Linux native builds, at the named SHAs above. No Windows build inferred from Linux.
  • Inspected restart proof on aka at both exact drawable sizes: Normal → choose Hidden (Restart needed, HUD unchanged) → unrelated sharpness save → restart (HUD and minimap gone; pause, all panel pages, full map and world map visible) → choose Normal (HUD remains hidden) → restart (HUD restored). The selected row's next-start hint and restart confirmation were inspected in both directions. The harness chose Later and relaunched the isolated process; this does not claim a new test of the existing Restart Now relaunch implementation.
  • In Hidden at 1920x1080, the Hyrule Castle guard's dialogue, “Princess Zelda?” / “No.” choices and Hide / Conversation Log footer are visible. The guard conversation was checked at 1920x1080; it was not verified at 2448x1848.
  • Paired Normal/Hidden loading transitions from the same copied Market save to Kokiri Forest at both shapes: inspected all 48 transition frames and the arrival capture per arm (196 PNGs total). Fade coverage, loading icon, area-name message and arrival remain visible; only Hidden omits the gameplay HUD/minimap.
  • GCC/Clang host fixtures, g++/clang++ restart-state fixture, 13 focused checks including upstream HUD layout, and seven related patch checks pass. Tests cover missing/default/Hidden/Normal options, range handling, unrelated saves, retained canvases, restart tracking, map/menu transitions, unknown layouts/projections, exact restoration and no extra guest reads/writes in Normal.
  • One full suite on 08db9fd, required environment and lock, 8 jobs / 1200 s timeout: 567 passed, 12 failed, 16 skipped in 892 s. Every failure reproduces on exact untouched main 53f96d7; there are no new failures. The twelve are test_lift_cleanup_error, test_make_game_cache, test_appimage_player_build, test_cpm_discovery, test_crash_dialog, test_env_on, test_linux_preflight, test_pipeline_tour, test_readback_late, test_vk_pgo, test_vram_budget_row, test_walk_key. The untouched-main focused comparison is 12 failed and one incidental passing menu_env_on check. Main's fixtures include missing _lift_store, missing toolchain.find, unexpected PGO compiler probes, Clang's trailing -x none warning, the RX_VK_PRESENT_AFTER_SIGNAL presence check, stale source assertions and missing hos_oot_autoload_input.
  • git diff --check passes. No separate formatter/typechecker exists; the native build, warning-enabled fixtures and suite's Python compilation cover the changed languages.

Not tested: Item message: the final interactive attempt ended at its enforced 10-minute GPU cap before an item was obtained; no item-message result is claimed. Also untested: dialogue at 2448x1848, Windows/llvm-mingw, other GPUs, HDR/FG, physical handhelds, other languages' new label/hint, and a full playthrough. The timing variability above was not isolated to a cause.

Must be tested:

  • Windows, any GPU: build with llvm-mingw and UTF-8 paths; verify restart-applied Normal/Hidden/Normal, full map, dialogue choices and an item message, expecting HUD changes only after restart and the full map, dialogue choices and item message to remain visible. By hand: Windows volunteers through test request T-GJPR, pinned to head d3ceb71287310c4de5bce309600f258d19342d70. The request is open but cannot be claimed until a maintainer adds the existing testing wanted label.

Screenshots

Ten original PNGs are attachments on this PR. All ten were fetched without authentication or cookies: HTTP 200, PNG signature and SHA-256 matched the inspected originals. Local copies were then deleted.

1920x1080

Before: main @ 53f96d7 After: this PR @ cdc248d, Normal After: this PR @ cdc248d, Hidden
main 1920x1080 Normal 1920x1080 Hidden 1920x1080

Full map remains visible in Hidden (1920x1080):
Full map, Hidden 1920x1080

2448x1848

Before: main @ 53f96d7 After: this PR @ cdc248d, Normal After: this PR @ cdc248d, Hidden
main 2448x1848 Normal 2448x1848 Hidden 2448x1848

Full map remains visible in Hidden (2448x1848):
Full map, Hidden 2448x1848

Restart indicator and dialogue choices

HUD mode requires a restart

Guard dialogue choices in Hidden

Risks

What could break: A screen identity or shared map classification could hide required information. Unknown layouts/projections stay visible. Hidden deliberately removes health and action/navigation information. The visibility wrappers add host calls. Median default-mode FPS stayed within 1% here, but the unexplained slow samples limit that conclusion; other PCs and scenes need their own checks.

Turning it off: Choose Normal, save progress and restart. This is not a live toggle. Restarting loses progress since the last save, as the existing confirmation warns.

Compatibility: hud_mode is a saved menu option (0 Hidden, 1 Normal, default 1). No save-data schema or shader change. No MkwVkHost or MkwVkRenderer layout change, so no ABI version bump. Existing main #95 owns all layout behavior.

Issues

See #95.

Checklist

Everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description) of the status line's type.
  • Why gives the reason plainly and links the issues that fit (the tracker searched).
  • Measurements has a verdict, or one line saying why there is nothing to measure.
  • Testing names what was tested, what wasn't, and what must still be tested, where and how.
  • Rebased on current main. Onto 53f96d7805; verified identical source tree, as noted above.
  • python -I -B tests/run_all.py passes (any failure that also fails on main is named). All 12 failures reproduce on the exact base, named above.
  • 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.

When it applies

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • Numbers from the same PC, scene and settings, at least 2 interleaved runs each, the median reported.
  • Switches documented (docs/development.md; the README for a menu row) and shipped at their recommended value.
  • Screenshots of the same spot, captioned like the Measurements columns, for a change that shows on screen.
  • A file in docs/tested/ for each new measured run (format in docs/tested-configurations.md). Fifteen individual run files, including the slow samples.
  • A game-free test added for the fix, failing on main and passing here.
  • A check under tests/ that reads changed source updated in this PR, not weakened.
  • Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths. Linux built; Windows not available and not claimed. T-GJPR requests that build and run.
  • Docs updated.
**Type:** feat · **Risk:** medium · **Tested on:** Linux, RX 7900 XT · **Needs:** Windows and item-message testing ## Why Players who want an unobstructed game view cannot hide the gameplay HUD today. This adds an opt-in Hidden mode while keeping Normal as the default. See #95. I searched the open and closed PRs and issues; #95 owns HUD layout, not visibility. ## What changed Graphics → Screen gains **HUD mode**, Hidden/Normal, saved as `hud_mode`. **The choice applies on the next start, not live.** The existing restart indicator and confirmation explain this before the player restarts. - Menu: `menu_hud_mode()` in `gpu/vk/vk_menu.cpp` reads the existing restart state's startup value. The saved row can change without changing any canvas in the running session, including a canvas created later. There is no separate HUD latch. - Visibility: `nx2/oot_wide.py` collapses only six recognized gameplay canvases when they are constructed. Normal adds no guest reads. It does not change the layout's source projection. - Shared map: `hos_oot_hud_screen()` in `host/oot_hud.c`, installed by `patch_hud_screen()` in `nx2/oot_patches.py`, distinguishes the minimap from the full map using `MapMenu_00:N_MapIcon_00`, as #95 does. It temporarily collapses the map canvas only during its minimap update and restores every coefficient before returning. The update always runs; skipping it would also stop the transition to the full map. No saved-state writes, retained guest pointers or visibility cache. - #95 merged during this work. This branch includes main **53f96d780588832401eadfc27c9cb41b2c2ae25c** and preserves its X/Y scales. There is no new docking, sizing, Double mode, renderer tag or dependency on unmerged #142. The unpublished branch was then rebased linearly onto that same main; its source tree did not change. Llun agreed to separate visibility work in [#95 comment 20344](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/95#issuecomment-20344). - Tests execute the injected C, the actual host helper and the menu's actual restart-state logic. The map fixture checks scoped restoration across ordinary, early and tail returns. Existing source-reading checks remain intact. README and the options-file reference document the restart requirement. ## Measurements **Verdict:** The listed visibility/restart checks pass. Normal-mode median FPS is within 1% of main at both shapes. Two narrow-screen PR runs were much slower; a third complete interleaved triplet returned near the first round. **The cause was not isolated; all runs, including the slow ones, are retained. No general speed or zero-cost claim.** Before: main @ **53f96d780588832401eadfc27c9cb41b2c2ae25c** After: this PR @ **cdc248dc0c29725b022fe7d8aa0be675ca3a739a** **Source identity:** the executable was built from pre-rebase `08db9fd8214ca875d14dadeb657640b67a9c9f5f`, and its build stamp still says that. `git rev-parse 08db9fd^{tree} cdc248d^{tree}` gives **34b68817a2b2c55982251c576af8486f730465c7** for both that commit and `cdc248dc0c29725b022fe7d8aa0be675ca3a739a`. Head `d3ceb71287310c4de5bce309600f258d19342d70` adds only the fifteen tested-run records after that code commit. The rebase changed history only; all tracked file contents and modes are byte-identical. The proofs, suite and timings therefore cover the rebased source without a rebuild. Hardware: NixOS 26.11, Linux 7.2.7; AMD Radeon RX 7900 XT (RADV, Mesa 26.2.3); Ryzen 5 7600X, 30.56 GiB Linux MemTotal (32,048,408 KiB); private headless Sway/Xwayland. Scene: copied Castle Town gatehouse save, stationary by the wooden door; output/drawable 1920x1080 and 2448x1848. Upscaler Off, render resolution 100%, FG/HDR off, uncapped, audio off, compute mesh fallback, udmabuf access. Method: main / PR Normal / PR Hidden, interleaved twice at 1920x1080 and three times at 2448x1848; 30 s warm-up after reaching the scene, then 45 s of native FPS log samples. The table reports each run's median and the median of runs. The third narrow triplet followed the slow second-round PR samples; it does not replace them. Those slow runs show higher render-thread job elapsed time (not CPU-cycle measurements), while GPU time stays around 10.4–10.6 ms. Normal still has host-call overhead. How to reproduce: use the same save and options in separate main/PR folders; set HUD mode before each PR launch, not during a sample. | Shape / round | Before: main @ 53f96d7 | After: this PR @ cdc248d (Normal) | After, Hidden: this PR @ cdc248d | |---|---|---|---| | 1920x1080, run 1 | 59.50 | 60.10 | 60.70 | | 1920x1080, run 2 | 60.00 | 60.30 | 58.80 | | **1920x1080, median of runs** | **59.75** | **60.20** | **59.75** | | 2448x1848, run 1 | 58.80 | 58.35 | 58.95 | | 2448x1848, run 2 | 58.45 | 22.70 | 33.30 | | 2448x1848, run 3 | 59.10 | 59.25 | 58.70 | | **2448x1848, median of runs** | **58.80** | **58.35** | **58.70** | 1920x1080: Normal +0.75%, Hidden +0.00% relative to main. 2448x1848: Normal -0.77%, Hidden -0.17% relative to main. <details><summary>All FPS samples and original first/last log lines per run</summary> **1920x1080-r1-main** — 59.50 FPS median; 21 samples. ```text 45.4, 44.2, 38.1, 53.3, 60.6, 61.4, 59.9, 60.3, 60.2, 60.1, 61.0, 59.3, 59.8, 59.4, 60.6, 59.5, 58.1, 58.6, 56.6, 59.4, 61.1 [hos host] vk: 26520 presents, 45.4 fps; a frame: 1297 draws (0 skipped), 107 dispatches, 161 passes, 160 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (2159 ms), 0 programs (10 failed), 1416 textures (3439 MB) [hos host] vk: 28920 presents, 61.1 fps; a frame: 1281 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (2159 ms), 0 programs (10 failed), 1380 textures (3166 MB) ``` **1920x1080-r1-normal** — 60.10 FPS median; 21 samples. ```text 59.0, 60.3, 59.9, 59.6, 59.8, 61.1, 60.4, 52.0, 59.4, 58.8, 53.3, 51.9, 31.3, 60.4, 61.4, 62.1, 62.2, 60.1, 61.5, 62.2, 62.0 [hos host] vk: 18000 presents, 59.0 fps; a frame: 1285 draws (0 skipped), 103 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1389 ms), 0 programs (10 failed), 1324 textures (3117 MB) [hos host] vk: 20400 presents, 62.0 fps; a frame: 1271 draws (0 skipped), 102 dispatches, 161 passes, 155 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1389 ms), 0 programs (10 failed), 1323 textures (3108 MB) ``` **1920x1080-r1-hidden** — 60.70 FPS median; 23 samples. ```text 61.0, 59.9, 60.7, 60.2, 60.3, 58.9, 59.8, 60.3, 60.7, 60.9, 61.0, 61.0, 61.0, 61.1, 60.6, 60.7, 61.7, 60.5, 61.9, 61.8, 61.5, 60.9, 59.4 [hos host] vk: 4200 presents, 61.0 fps; a frame: 1286 draws (0 skipped), 103 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (7368 ms), 0 programs (10 failed), 1325 textures (3211 MB) [hos host] vk: 6840 presents, 59.4 fps; a frame: 1287 draws (0 skipped), 102 dispatches, 161 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (7368 ms), 0 programs (10 failed), 1315 textures (3093 MB) ``` **1920x1080-r2-main** — 60.00 FPS median; 22 samples. ```text 60.8, 60.6, 59.6, 60.1, 60.2, 60.7, 61.0, 60.0, 60.6, 58.6, 59.5, 59.4, 59.7, 60.7, 58.1, 58.6, 59.2, 60.0, 60.0, 61.0, 60.0, 60.5 [hos host] vk: 30240 presents, 60.8 fps; a frame: 1292 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.1 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1308 ms), 0 programs (10 failed), 1323 textures (3097 MB) [hos host] vk: 32760 presents, 60.5 fps; a frame: 1295 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1308 ms), 0 programs (10 failed), 1348 textures (3140 MB) ``` **1920x1080-r2-normal** — 60.30 FPS median; 22 samples. ```text 59.7, 60.0, 60.6, 61.1, 60.5, 59.9, 60.2, 60.6, 60.0, 60.3, 60.0, 60.3, 60.8, 60.9, 59.8, 59.7, 61.5, 60.4, 60.3, 59.7, 60.9, 59.7 [hos host] vk: 30120 presents, 59.7 fps; a frame: 1295 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1352 ms), 0 programs (10 failed), 1301 textures (3091 MB) [hos host] vk: 32640 presents, 59.7 fps; a frame: 1292 draws (0 skipped), 105 dispatches, 162 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1352 ms), 0 programs (10 failed), 1334 textures (3116 MB) ``` **1920x1080-r2-hidden** — 58.80 FPS median; 22 samples. ```text 59.5, 59.9, 60.6, 60.5, 59.9, 59.8, 60.7, 59.1, 58.9, 52.6, 54.4, 57.2, 59.3, 55.8, 58.5, 59.3, 58.1, 58.7, 57.6, 56.1, 57.5, 56.0 [hos host] vk: 16200 presents, 59.5 fps; a frame: 1291 draws (0 skipped), 105 dispatches, 161 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1318 ms), 0 programs (10 failed), 1309 textures (3178 MB) [hos host] vk: 18720 presents, 56.0 fps; a frame: 1297 draws (0 skipped), 105 dispatches, 162 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1318 ms), 0 programs (10 failed), 1345 textures (3122 MB) ``` **2448x1848-r1-main** — 58.80 FPS median; 22 samples. ```text 57.1, 57.2, 59.5, 59.6, 58.2, 57.7, 58.6, 58.6, 57.3, 59.0, 60.9, 58.3, 59.3, 58.1, 60.2, 58.3, 59.6, 59.8, 59.3, 59.0, 58.6, 59.0 [hos host] vk: 25080 presents, 57.1 fps; a frame: 1112 draws (0 skipped), 105 dispatches, 154 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1421 ms), 0 programs (10 failed), 1322 textures (3578 MB) [hos host] vk: 27600 presents, 59.0 fps; a frame: 1108 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1421 ms), 0 programs (10 failed), 1297 textures (3359 MB) ``` **2448x1848-r1-normal** — 58.35 FPS median; 22 samples. ```text 57.8, 58.3, 57.0, 57.5, 57.9, 59.0, 59.6, 58.4, 59.9, 56.7, 58.4, 59.5, 57.8, 56.8, 58.5, 59.8, 58.4, 58.0, 56.9, 57.1, 59.6, 59.0 [hos host] vk: 25320 presents, 57.8 fps; a frame: 1109 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1432 ms), 0 programs (10 failed), 1304 textures (3365 MB) [hos host] vk: 27840 presents, 59.0 fps; a frame: 1105 draws (0 skipped), 104 dispatches, 154 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1432 ms), 0 programs (10 failed), 1296 textures (3272 MB) ``` **2448x1848-r1-hidden** — 58.95 FPS median; 22 samples. ```text 57.2, 59.8, 58.6, 59.3, 58.9, 59.5, 57.8, 59.0, 59.1, 58.2, 58.0, 57.9, 59.5, 58.9, 59.6, 57.3, 59.2, 59.6, 58.8, 59.3, 58.6, 59.7 [hos host] vk: 27000 presents, 57.2 fps; a frame: 1120 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1387 ms), 0 programs (10 failed), 1322 textures (3482 MB) [hos host] vk: 29520 presents, 59.7 fps; a frame: 1106 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1387 ms), 0 programs (10 failed), 1296 textures (3258 MB) ``` **2448x1848-r2-main** — 58.45 FPS median; 22 samples. ```text 56.2, 58.9, 58.4, 58.9, 58.3, 58.5, 58.9, 59.0, 60.4, 58.5, 57.8, 58.3, 58.1, 57.4, 59.0, 58.3, 60.8, 60.9, 59.0, 57.6, 58.4, 57.0 [hos host] vk: 26400 presents, 56.2 fps; a frame: 1125 draws (0 skipped), 105 dispatches, 155 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1363 ms), 0 programs (10 failed), 1298 textures (3275 MB) [hos host] vk: 28920 presents, 57.0 fps; a frame: 1110 draws (0 skipped), 104 dispatches, 155 passes, 157 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (1363 ms), 0 programs (10 failed), 1302 textures (3277 MB) ``` **2448x1848-r2-normal** — 22.70 FPS median; 9 samples. ```text 23.2, 23.0, 22.4, 22.7, 22.2, 22.6, 23.1, 22.1, 24.5 [hos host] vk: 5280 presents, 23.2 fps; a frame: 1105 draws (0 skipped), 112 dispatches, 149 passes, 176 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (1457 ms), 0 programs (10 failed), 1305 textures (3672 MB) [hos host] vk: 6240 presents, 24.5 fps; a frame: 1112 draws (0 skipped), 111 dispatches, 150 passes, 175 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (1457 ms), 0 programs (10 failed), 1259 textures (3280 MB) ``` **2448x1848-r2-hidden** — 33.30 FPS median; 12 samples. ```text 27.6, 26.3, 33.5, 33.9, 33.6, 33.2, 33.3, 33.2, 33.0, 33.6, 33.7, 33.3 [hos host] vk: 3000 presents, 27.6 fps; a frame: 1111 draws (0 skipped), 110 dispatches, 152 passes, 171 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (5775 ms), 0 programs (10 failed), 1309 textures (3628 MB) [hos host] vk: 4320 presents, 33.3 fps; a frame: 1102 draws (0 skipped), 106 dispatches, 152 passes, 166 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.1 ms (recording slots only); 32523 pipelines (5775 ms), 0 programs (10 failed), 1266 textures (3246 MB) ``` **2448x1848-r3-main** — 59.10 FPS median; 22 samples. ```text 59.4, 59.1, 61.4, 60.4, 59.0, 58.0, 60.3, 59.1, 58.3, 56.9, 59.2, 58.6, 59.1, 59.6, 58.3, 58.7, 57.2, 60.0, 58.7, 59.0, 60.5, 60.3 [hos host] vk: 29640 presents, 59.4 fps; a frame: 1121 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (3386 ms), 0 programs (10 failed), 1320 textures (3504 MB) [hos host] vk: 32160 presents, 60.3 fps; a frame: 1121 draws (0 skipped), 105 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32390 pipelines (3386 ms), 0 programs (10 failed), 1298 textures (3291 MB) ``` **2448x1848-r3-normal** — 59.25 FPS median; 22 samples. ```text 58.5, 58.3, 59.2, 58.3, 60.3, 61.6, 59.6, 59.7, 60.9, 59.3, 60.3, 59.2, 58.3, 58.8, 57.7, 58.3, 61.0, 59.0, 59.1, 60.2, 60.0, 61.1 [hos host] vk: 29160 presents, 58.5 fps; a frame: 1116 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1258 ms), 0 programs (10 failed), 1314 textures (3458 MB) [hos host] vk: 31680 presents, 61.1 fps; a frame: 1108 draws (0 skipped), 105 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (1258 ms), 0 programs (10 failed), 1294 textures (3259 MB) ``` **2448x1848-r3-hidden** — 58.70 FPS median; 19 samples. ```text 58.6, 58.7, 59.5, 57.5, 57.5, 56.9, 59.0, 59.2, 59.3, 58.6, 59.0, 58.8, 60.2, 59.2, 58.6, 59.3, 57.6, 53.2, 29.5 [hos host] vk: 21720 presents, 58.6 fps; a frame: 1107 draws (0 skipped), 104 dispatches, 154 passes, 156 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (2036 ms), 0 programs (10 failed), 1299 textures (3292 MB) [hos host] vk: 23880 presents, 29.5 fps; a frame: 1112 draws (0 skipped), 110 dispatches, 151 passes, 168 barriers, 6 submits, 0.0 uploads (0.0 MB), 82 ub updates (57 overlays), GPU-bound wait 0.0 ms (recording slots only); 32523 pipelines (2036 ms), 0 programs (10 failed), 1298 textures (3291 MB) ``` </details> All original log lines and measured JSON remain in the isolated aka evidence directories. The list above includes every FPS sample; the raw lines shown are the first and last of each interval. ### Flags and settings One menu row and ini key. No new environment switch. | Flag | What it is | Before this PR | After this PR | Effect | Helps / doesn't help / untested | Recommendation | |---|---|---|---|---|---|---| | HUD mode; `hud_mode` | 0 Hidden, 1 Normal | No row; gameplay HUD visible | 1 Normal | After a restart, Hidden removes gameplay health, action prompts and minimap. Normal plus a restart restores them. | Helps an unobstructed view; does not position or enlarge the HUD. Windows and other GPUs remain untested. | Keep Normal as default; Hidden is opt-in because it removes health and navigation information. | ## Testing **Tested:** - Both full Linux native builds, at the named SHAs above. No Windows build inferred from Linux. - Inspected restart proof on aka at both exact drawable sizes: Normal → choose Hidden (Restart needed, HUD unchanged) → unrelated sharpness save → restart (HUD and minimap gone; pause, all panel pages, full map and world map visible) → choose Normal (HUD remains hidden) → restart (HUD restored). The selected row's next-start hint and restart confirmation were inspected in both directions. The harness chose Later and relaunched the isolated process; this does not claim a new test of the existing Restart Now relaunch implementation. - In Hidden at 1920x1080, the Hyrule Castle guard's dialogue, “Princess Zelda?” / “No.” choices and Hide / Conversation Log footer are visible. The guard conversation was checked at 1920x1080; it was not verified at 2448x1848. - Paired Normal/Hidden loading transitions from the same copied Market save to Kokiri Forest at both shapes: inspected all 48 transition frames and the arrival capture per arm (196 PNGs total). Fade coverage, loading icon, area-name message and arrival remain visible; only Hidden omits the gameplay HUD/minimap. - GCC/Clang host fixtures, g++/clang++ restart-state fixture, 13 focused checks including upstream HUD layout, and seven related patch checks pass. Tests cover missing/default/Hidden/Normal options, range handling, unrelated saves, retained canvases, restart tracking, map/menu transitions, unknown layouts/projections, exact restoration and no extra guest reads/writes in Normal. - One full suite on 08db9fd, required environment and lock, 8 jobs / 1200 s timeout: **567 passed, 12 failed, 16 skipped in 892 s**. Every failure reproduces on exact untouched main 53f96d7; there are no new failures. The twelve are `test_lift_cleanup_error`, `test_make_game_cache`, `test_appimage_player_build`, `test_cpm_discovery`, `test_crash_dialog`, `test_env_on`, `test_linux_preflight`, `test_pipeline_tour`, `test_readback_late`, `test_vk_pgo`, `test_vram_budget_row`, `test_walk_key`. The untouched-main focused comparison is 12 failed and one incidental passing `menu_env_on` check. Main's fixtures include missing `_lift_store`, missing `toolchain.find`, unexpected PGO compiler probes, Clang's trailing `-x none` warning, the `RX_VK_PRESENT_AFTER_SIGNAL` presence check, stale source assertions and missing `hos_oot_autoload_input`. - `git diff --check` passes. No separate formatter/typechecker exists; the native build, warning-enabled fixtures and suite's Python compilation cover the changed languages. **Not tested:** **Item message**: the final interactive attempt ended at its enforced 10-minute GPU cap before an item was obtained; no item-message result is claimed. Also untested: dialogue at 2448x1848, Windows/llvm-mingw, other GPUs, HDR/FG, physical handhelds, other languages' new label/hint, and a full playthrough. The timing variability above was not isolated to a cause. **Must be tested:** - Windows, any GPU: build with llvm-mingw and UTF-8 paths; verify restart-applied Normal/Hidden/Normal, full map, dialogue choices and an item message, expecting HUD changes only after restart and the full map, dialogue choices and item message to remain visible. By hand: Windows volunteers through [test request T-GJPR](https://matrix.to/#/!14jpKFbJsiUJm1txmITRIb1dIAjiKhTSITKCiqSV3Xc/$kaOndDM8v9EcTR0ebXZHCHPTyBuEPWOAKyiEwIixZkc), pinned to head `d3ceb71287310c4de5bce309600f258d19342d70`. The request is open but cannot be claimed until a maintainer adds the existing `testing wanted` label. ## Screenshots Ten original PNGs are [attachments on this PR](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/774#issuecomment-24184). All ten were fetched without authentication or cookies: HTTP 200, PNG signature and SHA-256 matched the inspected originals. Local copies were then deleted. ### 1920x1080 | Before: main @ 53f96d7 | After: this PR @ cdc248d, Normal | After: this PR @ cdc248d, Hidden | |---|---|---| | ![main 1920x1080](https://git.magicbean.dev/attachments/84628e97-5019-4d47-825c-fb0ad27d82c4) | ![Normal 1920x1080](https://git.magicbean.dev/attachments/377acf5c-cac8-4381-9a17-454885d6b19e) | ![Hidden 1920x1080](https://git.magicbean.dev/attachments/e3ff7518-a67c-42fd-8418-135f6a8548c8) | Full map remains visible in Hidden (1920x1080): ![Full map, Hidden 1920x1080](https://git.magicbean.dev/attachments/1dba60cc-0cfb-4e85-8563-340fec6daa6c) ### 2448x1848 | Before: main @ 53f96d7 | After: this PR @ cdc248d, Normal | After: this PR @ cdc248d, Hidden | |---|---|---| | ![main 2448x1848](https://git.magicbean.dev/attachments/201fb10c-19e5-426a-bc37-724cd2c6be3b) | ![Normal 2448x1848](https://git.magicbean.dev/attachments/9a9e72df-dc8b-43be-bf45-e2c3d06c32f9) | ![Hidden 2448x1848](https://git.magicbean.dev/attachments/72b1150e-e830-4742-a910-5f300084ec46) | Full map remains visible in Hidden (2448x1848): ![Full map, Hidden 2448x1848](https://git.magicbean.dev/attachments/db132bff-ea41-4a03-8461-ffa32d052f5e) ### Restart indicator and dialogue choices ![HUD mode requires a restart](https://git.magicbean.dev/attachments/aee4a2e3-ac78-4b65-8994-1d871ad2d713) ![Guard dialogue choices in Hidden](https://git.magicbean.dev/attachments/63588c69-d989-4710-8173-d063e49d7ca8) ## Risks **What could break:** A screen identity or shared map classification could hide required information. Unknown layouts/projections stay visible. Hidden deliberately removes health and action/navigation information. The visibility wrappers add host calls. Median default-mode FPS stayed within 1% here, but the unexplained slow samples limit that conclusion; other PCs and scenes need their own checks. **Turning it off:** Choose Normal, save progress and restart. This is not a live toggle. Restarting loses progress since the last save, as the existing confirmation warns. **Compatibility:** `hud_mode` is a saved menu option (0 Hidden, 1 Normal, default 1). No save-data schema or shader change. No `MkwVkHost` or `MkwVkRenderer` layout change, so no ABI version bump. Existing main #95 owns all layout behavior. ## Issues See #95. ## Checklist ### Everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`) of the status line's type. - [x] Why gives the reason plainly and links the issues that fit (the tracker searched). - [x] Measurements has a verdict, or one line saying why there is nothing to measure. - [x] Testing names what was tested, what wasn't, and what must still be tested, where and how. - [x] Rebased on current `main`. Onto 53f96d780588832401eadfc27c9cb41b2c2ae25c; verified identical source tree, as noted above. - [x] `python -I -B tests/run_all.py` passes (any failure that also fails on `main` is named). All 12 failures reproduce on the exact base, named above. - [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. ### When it applies - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] Numbers from the same PC, scene and settings, at least 2 interleaved runs each, the median reported. - [x] Switches documented (docs/development.md; the README for a menu row) and shipped at their recommended value. - [x] Screenshots of the same spot, captioned like the Measurements columns, for a change that shows on screen. - [x] A file in `docs/tested/` for each new measured run (format in `docs/tested-configurations.md`). Fifteen individual run files, including the slow samples. - [x] A game-free test added for the fix, failing on `main` and passing here. - [x] A check under `tests/` that reads changed source updated in this PR, not weakened. - [ ] Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths. Linux built; Windows not available and not claimed. [T-GJPR](https://matrix.to/#/!14jpKFbJsiUJm1txmITRIb1dIAjiKhTSITKCiqSV3Xc/$kaOndDM8v9EcTR0ebXZHCHPTyBuEPWOAKyiEwIixZkc) requests that build and run. - [x] Docs updated.
Extract the owner plugin’s Hidden/Normal values and gameplay-screen identities without its docking, Double scaling or Window code. Normal bypasses the visibility hook’s guest reads. Hidden collapses only allowlisted canvas triangles, leaving layout, menus and unknown screens untouched.

Assisted-by: OpenAI GPT-6 Astra
Co-Authored-By: OpenAI GPT-6 Astra <[email protected]>
Use the existing restart state for the applied value as well as the Restart needed indicator. New canvases in the same session retain the startup choice. Document the restart and test retained canvas construction rather than claiming live restoration.

Assisted-by: OpenAI GPT-6 Astra
Co-Authored-By: OpenAI GPT-6 Astra <[email protected]>
The shared map canvas cannot be hidden at construction. Scope its visibility to the screen update, using the map-icon origin distinction from #95 and the stored projection offsets checked in the running game. Always run the update, and restore every projection bit before returning. Normal performs no added guest reads; no renderer metadata or layout planner is introduced.

Assisted-by: OpenAI GPT-6 Astra
Co-Authored-By: OpenAI GPT-6 Astra <[email protected]>
Keep restart helpers private but define menu_hud_mode in the public mkwvk namespace. The native shared-library link check caught the unresolved callback; add a source-scope regression check.

Assisted-by: OpenAI GPT-6 Astra
Co-Authored-By: OpenAI GPT-6 Astra <[email protected]>
Main now includes #95. Accept its matching scaled X/Y projection pair and restore the exact coefficients after a minimap update. Keep its source-reading layout assertions intact in Normal and cover non-default Y scale in the scoped map fixture.

Assisted-by: OpenAI GPT-6 Astra
Co-Authored-By: OpenAI GPT-6 Astra <[email protected]>
docs(ui): record the interleaved HUD mode measurements
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 5s
Website / Website on Cloudflare (pull_request_target) Has been skipped
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Guide screenshots / Guide images and local UI source review (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
Website / Website on Cloudflare (pull_request) Has been cancelled
d3ceb71287
Keep all fifteen runs, including both slow narrow-screen samples. Record the actual pre-rebase build and its exact source-tree equality with the rebased code. Screenshots were inspected; no general performance claim.

Assisted-by: OpenAI GPT-6 Astra
Co-Authored-By: OpenAI GPT-6 Astra <[email protected]>
Author
Contributor

Inspected Linux captures. Main is 53f96d7; this PR is cdc248d, whose source tree exactly matches native build 08db9fd (the build stamp visible in the menu). HUD mode applies after restart. Item messages remain untested; see request T-GJPR.

1920x1080

Before: main @ 53f96d7 After: this PR @ cdc248d, Normal After: this PR @ cdc248d, Hidden
main 1920x1080 Normal 1920x1080 Hidden 1920x1080

Full map remains visible in Hidden (1920x1080):
Full map, Hidden 1920x1080

2448x1848

Before: main @ 53f96d7 After: this PR @ cdc248d, Normal After: this PR @ cdc248d, Hidden
main 2448x1848 Normal 2448x1848 Hidden 2448x1848

Full map remains visible in Hidden (2448x1848):
Full map, Hidden 2448x1848

Restart indicator and dialogue choices

HUD mode requires a restart

Guard dialogue choices in Hidden

Inspected Linux captures. Main is `53f96d7`; this PR is `cdc248d`, whose source tree exactly matches native build `08db9fd` (the build stamp visible in the menu). HUD mode applies after restart. Item messages remain untested; see request T-GJPR. ### 1920x1080 | Before: main @ 53f96d7 | After: this PR @ cdc248d, Normal | After: this PR @ cdc248d, Hidden | |---|---|---| | ![main 1920x1080](https://git.magicbean.dev/attachments/84628e97-5019-4d47-825c-fb0ad27d82c4) | ![Normal 1920x1080](https://git.magicbean.dev/attachments/377acf5c-cac8-4381-9a17-454885d6b19e) | ![Hidden 1920x1080](https://git.magicbean.dev/attachments/e3ff7518-a67c-42fd-8418-135f6a8548c8) | Full map remains visible in Hidden (1920x1080): ![Full map, Hidden 1920x1080](https://git.magicbean.dev/attachments/1dba60cc-0cfb-4e85-8563-340fec6daa6c) ### 2448x1848 | Before: main @ 53f96d7 | After: this PR @ cdc248d, Normal | After: this PR @ cdc248d, Hidden | |---|---|---| | ![main 2448x1848](https://git.magicbean.dev/attachments/201fb10c-19e5-426a-bc37-724cd2c6be3b) | ![Normal 2448x1848](https://git.magicbean.dev/attachments/9a9e72df-dc8b-43be-bf45-e2c3d06c32f9) | ![Hidden 2448x1848](https://git.magicbean.dev/attachments/72b1150e-e830-4742-a910-5f300084ec46) | Full map remains visible in Hidden (2448x1848): ![Full map, Hidden 2448x1848](https://git.magicbean.dev/attachments/db132bff-ea41-4a03-8461-ffa32d052f5e) ### Restart indicator and dialogue choices ![HUD mode requires a restart](https://git.magicbean.dev/attachments/aee4a2e3-ac78-4b65-8994-1d871ad2d713) ![Guard dialogue choices in Hidden](https://git.magicbean.dev/attachments/63588c69-d989-4710-8173-d063e49d7ca8)
HumanBean force-pushed feat/hud-hidden from d3ceb71287
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 5s
Website / Website on Cloudflare (pull_request_target) Has been skipped
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Guide screenshots / Guide images and local UI source review (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
Website / Website on Cloudflare (pull_request) Has been cancelled
to 8ddce2f013
Some checks failed
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
PR description / Description follows the template (pull_request_target) Successful in 4s
CI / Conventional Commit title (pull_request) Successful in 3s
CI / Workflow lint (actionlint) (pull_request) Successful in 4s
Guide screenshots / Guide images and local UI source review (pull_request) Failing after 3s
Third-party parts / As their notes say (pull_request) Successful in 7s
2026-11-15 18:43:25 +00:00
Compare
Some checks failed
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
PR description / Description follows the template (pull_request_target) Successful in 4s
CI / Conventional Commit title (pull_request) Successful in 3s
CI / Workflow lint (actionlint) (pull_request) Successful in 4s
Guide screenshots / Guide images and local UI source review (pull_request) Failing after 3s
Third-party parts / As their notes say (pull_request) Successful in 7s
This pull request is marked as a work in progress.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'feat/hud-hidden:simonwjackson-feat/hud-hidden'
git switch 'simonwjackson-feat/hud-hidden'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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!774
No description provided.