fix(runtime): let the floor web react above 60 fps #49

Open
mooki wants to merge 3 commits from mooki/Longshot:fix/web-floor-step-carry into main
First-time contributor

Why

The Deku Tree floor web stops reacting when Link jumps on it above 60 fps. This restores its movement in the Linux/RTX 4090 test, not every above-60 gameplay issue.

What changed

  • runtime: f_80652cb0 truncates elapsed time divided by 1/60 to whole simulation steps, so a sub-one update becomes zero.
  • lift: one WHOLE_SITES entry in nx2/oot_patches.py uses the existing fractional carry to retain that remainder per web object before the unchanged 0..3 clamp; no new runtime helper, switch or logging.
  • tests: tests/test_web_floor_steps.py is an authored game-free test of the selected site, independent objects, the clamp and long pauses.
  • docs: docs/tested-configurations.md records each measured run and the rejected attempt; the earlier Hookshot row is unchanged.

Flags and settings

No game flags or settings are added or changed. The new authored test exposes only this compiler selector, documented in its own usage text; the existing gameplay/testing switches below are not changed.

Flag What it does Default now Recommendation Helps on Doesn't help on Untested on
tests/test_web_floor_steps.py --cc New test-only CLI option: Chooses the C compiler for the authored fixture gcc Not applicable: a test compiler choice, not a game default Running the fixture with GCC or Clang Gameplay: no effect on the game Native Windows execution of the Longshot fixture

Measurements

Branch state: on main f41db065cf6667ec638a10aa6990099392d10dca; head 7f840c0ae592364fa8110a2d73ded06118519e0d; whole game-free suite on this head: 510 passed, 0 failed, 19 skipped (main f41db065cf6667ec638a10aa6990099392d10dca: 509 passed, 0 failed, 19 skipped); the commits are unchanged by rebases apart from the results table.

Known local failure: tests/test_updater_asset_digest.py fails with NU1100: Unable to resolve 'Microsoft.AspNetCore.App.Ref (= 10.0.13)' for 'net10.0'. The same test fails with the same diagnostic on pinned main d3bd2805. No test was weakened or package installed; this is not an all-green suite. The 20 skips are declared platform/game prerequisites. That test left main together with the in-game updater, so the suites in the branch-state block no longer contain it.

main: d3bd280503 (2026-11-12, UTC commit date)
this PR: move/fix-web-floor-step-carry-r2 @ 27375dbe99ef96dfb55b0be585a5852cba05b4bf
Hardware: RTX 4090, NVIDIA 615.78.08; Core i9-13900K, 94 GiB usable RAM; Arch Linux 7.2.15-1-omarchy; 2026-11-12, windowless
Scene: Deku Tree floor web, same save and camera; interior, time of day not varied; 1280×720, game's own 50% render scale (640×360), frame generation off, real-time game speed, caps 60/240, no mods
Method: three scripted jumps per run after at least 10 s in the scene; about 11 s of observations each. At cap 240, two interleaved pairs (main, fixed, main, fixed) in one 150.6 s exclusive GPU session, with no other GPU test work. The other runs used shared load. Read-only snapshots of the web's step count, changing ring indices and four central heights, plus HOS_PRESENT_TRACE CPU intervals. No added entry tracer or memory writes.
How to reproduce: use a disposable save at the centre of the Deku Tree floor web in your own test install; use the scene settings above, wait at least 10 s after arrival, stand for 2 s, then jump three times, 3 s apart. Use the menu cap 240 (or HOS_FPS_MAX=240) and verify actual game presents exceed 60; repeat main, this PR, main, this PR. Repeat the control with cap 60 and the override unset. Run python -I -B tests/test_web_floor_steps.py for the authored fixture and python -I -B tests/run_all.py --jobs 6 --strict for the full game-free suite; the low-level observer was read-only and no save or game data is published.

The main suite was run once for all moved pull requests; this branch's suite was run once. Commands: main python -I -B tests/run_all.py --jobs 6 --strict; this PR python -I -B tests/run_all.py --jobs 6 --strict. The inherited local failure is named above, not counted as an all-green result.

Retained Longshot game measurements

Baseline: main @ d3bd2805 (Longshot measured build)

These are the measured builds, not new runs on the current heads: main d3bd280503 and this PR's measured source 27375dbe99ef96dfb55b0be585a5852cba05b4bf. The later original commit only added results rows. Both full builds used the verified Hookshot v2.1.0 release play profile.

Table cells are achieved game presents/s; intervals below 16.7 ms; observed updates / steps delivered / distinct four-height vectors. The median row is steps/s. These rates establish the above-60 test condition; this is a correctness result, not a speed comparison or display/GPU-completion measurement.

main @ d3bd2805 (Longshot measured build) this PR @ 27375dbe (Longshot measured build)
Longshot, cap 240, pair 1 89.840; 100.00%; 989 / 0 / 1 88.244; 99.90%; 972 / 661 / 487
Longshot, cap 240, pair 2 88.579; 99.38%; 975 / 0 / 1 88.652; 99.80%; 976 / 660 / 488
Longshot cap-240 median delivered steps/s 0.000 59.979
Longshot, shared-load cap 240 84.775; 97.86%; 933 / 9 / 8 41.852; rejected, counters unread
Longshot, shared-load cap 60 Not rerun 34.864; 0.52%; 384 / 426 / 193

Earlier Hookshot measurements, before the rename

Baseline: Hookshot main + local entry tracing @ e2057b2b

This historical comparison is retained from the original pull request, not a current-main rerun: the baseline is the old pinned Hookshot source plus local entry tracing, and the fixed build is the original floor-web change. It is not a speed comparison with current Longshot.

Hookshot main + local entry tracing @ e2057b2b Hookshot floor-web fix @ 25333d94
Earlier Hookshot, cap 60 59.996; 52.04%; 661 / 661 / 274 59.937; 50.38%; 660 / 660 / 270
Earlier Hookshot, cap 240 87.981; 99.59%; 969 / 0 / 1 89.290; 99.90%; 983 / 660 / 492

Both held main runs delivered zero steps and kept one height vector; both fixed runs delivered about 60 steps/s and hundreds of changing vectors. The ordinary main run's nine one-step observations are expected when some updates last a whole frame: its other 924 updates yielded zero. The ordinary fixed high-cap attempt stayed below 60 and was rejected before its counters were read. The cap-60 control reacted, but under load it reached only 34.864 presents/s; it is not a sustained-60-Hz proof.

The earlier Hookshot rows are carried from the original pull request, not reruns. Their baseline used local entry tracing and a different base, so they are not a matched speed comparison with Longshot. New counts mean observed ring-index changes, not an added entry counter; held sampling covered at least 99.79% of present numbers. The heights are read from the web itself, so camera movement cannot be mistaken for web movement.

Observation output and build identities:

[hos host] longshot v2.2.0-rc.1-15-gd3bd28050 (source 2bce0d57)
[hos host] longshot v2.2.0-rc.1-17-g27375dbe9 (source fc14c184)
Longshot base cap240 ordinary: presents/s=84.775; updates=933; steps=9; height_vectors=8; steps/s=0.818
Longshot fixed cap60 ordinary: presents/s=34.864; updates=384; steps=426; height_vectors=193; steps/s=38.677
Longshot base cap240 held run 1: presents/s=89.840; updates=989; steps=0; height_vectors=1; steps/s=0.000
Longshot fixed cap240 held run 1: presents/s=88.244; updates=972; steps=661; height_vectors=487; steps/s=60.009
Longshot base cap240 held run 2: presents/s=88.579; updates=975; steps=0; height_vectors=1; steps/s=0.000
Longshot fixed cap240 held run 2: presents/s=88.652; updates=976; steps=660; height_vectors=488; steps/s=59.949
Longshot base cap240 held median: steps/s=0.000; steps=0.0; height_vectors=1.0
Longshot fixed cap240 held median: steps/s=59.979; steps=660.5; height_vectors=487.5

Earlier, on the measured source 27375dbe, I ran the whole game-free suite locally, with the repository's default compiler selection and the exact command python -I -B tests/run_all.py --jobs 6 --strict. These checks have not yet been run on a forge runner.

508 passed, 1 failed, 20 skipped in 206 s (linux, 6 at once)

The new floor fixture passes here; against main it fails, including:

FAIL: 240-Hz first floor must run 60 steps, not zero or 240
FAIL: 240-Hz second floor must keep its own fraction
FAIL: 120-Hz floor must run 60 steps

Windows-target syntax on the measured Longshot code passed one captured C unit (the unchanged fixture is carried across the rebases, not rerun here); Windows execution was not run. Every Longshot game run exited 0, with no fatal, crash, device-loss or kernel-driver fault and complete journal coverage.

The comparison was built and run on main d3bd2805. Afterwards the branch was rebased onto main d4a69456 without any change (range-diff equal for all three commits); the commits in between do not touch nx2/oot_patches.py or the host frame-step mechanism, and the floor test passes on the rebased branch. It was not rebuilt or rerun in the game after that rebase.

The measured builds remain on d3bd2805; the newer main d725b3631 adds preparation/bug-report changes, save tools and forge scripts/docs/tests but does not touch the patched file or frame-step mechanism, confirmed by an empty git diff d3bd2805..d725b3631 -- nx2/oot_patches.py host, including host/frame_whole.h, host/nn_vi.c and host/oot_high_fps.c/.h.

All three range-diff entries remain equal. No new build or game run was made.

Testing

Tested: on this PC (Arch Linux, RTX 4090 with NVIDIA 615.78.08, i9-13900K), the whole game-free suite and the floor-step fixture, including its expected failures against main; Windows-target syntax checked one C unit, not Windows execution. In the game, the Deku Tree floor web at 1280×720 and 50% render scale, frame generation off: after at least 10 s in the scene, three jumps per run, main/fixed/main/fixed at cap 240 with actual presents above 60, plus the shared-load controls described above. The step counts and web heights, normal exits and driver logs were checked. Tested but not measured: the rejected shared-load cap-240 candidate completed the three jumps, but its deformation counters were deliberately not examined because the above-60 prerequisite failed; no other gameplay is claimed.

Not tested: Intel and AMD gameplay; other interactive floors such as the flying carpet; long play, web-breaking progression, swapchain/display timing, or sustained 60-Hz Longshot play. The runs were bounded to the stated web scene on this PC, and the cap-60 control was below 60 under load. The updater is shared by interactive floors, so those remain a risk. No cross-hardware test request has been opened. Above-60 play remains experimental.

Needs other testers:

  • Windows x64: run the floor-step fixture, then stand and jump three times on the Deku Tree floor web at a 240 fps cap with actual game presents above 60, expecting the fixture passes and the web bends and rises instead of freezing (test request T-YKGE)

Screenshots

main @ d3bd2805: panels 1 and 2, cap 240, standing and jumping with the web frozen. this PR @ 27375dbe: panels 3 and 4, cap 240, the web bends and rises; panels 5 and 6, cap-60 control under shared load. These captions name the actual measured builds, not the rebased heads.

1 and 2: main at a 240 cap, standing and jumping, the web stays still. 3 and 4: with the fix at a 240 cap, the web bends and rises. 5 and 6: with the fix at a 60 cap, under shared load.

Risk and rollback

The updater is shared by interactive floors, including the flying carpet: retaining fractional steps could change an untested floor's animation or interaction. The existing 0..3 clamp and cap-60 path remain unchanged. Revert this PR to remove the table entry and its regression test if it regresses another floor; there is no runtime switch for this fix.

Reviewer notes

Start with the f_80652cb0 entry in nx2/oot_patches.py's WHOLE_SITES, then patch_whole_frames and tests/test_web_floor_steps.py. The key keeps each object's fraction separate; no shared mechanism was refactored. The docs rows and uploaded picture are retained across the rebases. The limited hardware/area coverage is explicit above; this update changes the branch base and description, not the fix or measured evidence.

Issues

Fixes #86

Original bug report: https://github.com/NotRexed/Hookshot/issues/2667.

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.
  • 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

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • Screenshots for a change that shows on screen.
  • A row in docs/tested-configurations.md for each measured run.
  • A game-free test added for the fix, failing on main and passing here.
  • Docs updated.

Moved from NotRexed/Hookshot#2929.

Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra [email protected]

## Why The Deku Tree floor web stops reacting when Link jumps on it above 60 fps. This restores its movement in the Linux/RTX 4090 test, not every above-60 gameplay issue. ## What changed - runtime: `f_80652cb0` truncates elapsed time divided by 1/60 to whole simulation steps, so a sub-one update becomes zero. - lift: one `WHOLE_SITES` entry in `nx2/oot_patches.py` uses the existing fractional carry to retain that remainder per web object before the unchanged 0..3 clamp; no new runtime helper, switch or logging. - tests: `tests/test_web_floor_steps.py` is an authored game-free test of the selected site, independent objects, the clamp and long pauses. - docs: `docs/tested-configurations.md` records each measured run and the rejected attempt; the earlier Hookshot row is unchanged. ## Flags and settings No game flags or settings are added or changed. The new authored test exposes only this compiler selector, documented in its own usage text; the existing gameplay/testing switches below are not changed. | Flag | What it does | Default now | Recommendation | Helps on | Doesn't help on | Untested on | |---|---|---|---|---|---|---| | `tests/test_web_floor_steps.py --cc` | New test-only CLI option: Chooses the C compiler for the authored fixture | `gcc` | Not applicable: a test compiler choice, not a game default | Running the fixture with GCC or Clang | Gameplay: no effect on the game | Native Windows execution of the Longshot fixture | ## Measurements <!-- branch-state --> Branch state: on main `f41db065cf6667ec638a10aa6990099392d10dca`; head `7f840c0ae592364fa8110a2d73ded06118519e0d`; whole game-free suite on this head: `510 passed, 0 failed, 19 skipped` (main `f41db065cf6667ec638a10aa6990099392d10dca`: `509 passed, 0 failed, 19 skipped`); the commits are unchanged by rebases apart from the results table. <!-- /branch-state --> **Known local failure:** `tests/test_updater_asset_digest.py` fails with `NU1100: Unable to resolve 'Microsoft.AspNetCore.App.Ref (= 10.0.13)' for 'net10.0'`. The same test fails with the same diagnostic on pinned main d3bd2805. No test was weakened or package installed; this is not an all-green suite. The 20 skips are declared platform/game prerequisites. That test left main together with the in-game updater, so the suites in the branch-state block no longer contain it. main: d3bd280503b8d5ea10111883edacf68b7f223d25 (2026-11-12, UTC commit date) this PR: move/fix-web-floor-step-carry-r2 @ 27375dbe99ef96dfb55b0be585a5852cba05b4bf Hardware: RTX 4090, NVIDIA 615.78.08; Core i9-13900K, 94 GiB usable RAM; Arch Linux 7.2.15-1-omarchy; 2026-11-12, windowless Scene: Deku Tree floor web, same save and camera; interior, time of day not varied; 1280×720, game's own 50% render scale (640×360), frame generation off, real-time game speed, caps 60/240, no mods Method: three scripted jumps per run after at least 10 s in the scene; about 11 s of observations each. At cap 240, two interleaved pairs (main, fixed, main, fixed) in one 150.6 s exclusive GPU session, with no other GPU test work. The other runs used shared load. Read-only snapshots of the web's step count, changing ring indices and four central heights, plus `HOS_PRESENT_TRACE` CPU intervals. No added entry tracer or memory writes. How to reproduce: use a disposable save at the centre of the Deku Tree floor web in your own test install; use the scene settings above, wait at least 10 s after arrival, stand for 2 s, then jump three times, 3 s apart. Use the menu cap 240 (or `HOS_FPS_MAX=240`) and verify actual game presents exceed 60; repeat main, this PR, main, this PR. Repeat the control with cap 60 and the override unset. Run `python -I -B tests/test_web_floor_steps.py` for the authored fixture and `python -I -B tests/run_all.py --jobs 6 --strict` for the full game-free suite; the low-level observer was read-only and no save or game data is published. The main suite was run once for all moved pull requests; this branch's suite was run once. Commands: main `python -I -B tests/run_all.py --jobs 6 --strict`; this PR `python -I -B tests/run_all.py --jobs 6 --strict`. The inherited local failure is named above, not counted as an all-green result. ### Retained Longshot game measurements Baseline: main @ d3bd2805 (Longshot measured build) These are the measured builds, not new runs on the current heads: main d3bd280503b8d5ea10111883edacf68b7f223d25 and this PR's measured source 27375dbe99ef96dfb55b0be585a5852cba05b4bf. The later original commit only added results rows. Both full builds used the verified **Hookshot v2.1.0 release play profile**. Table cells are **achieved game presents/s; intervals below 16.7 ms; observed updates / steps delivered / distinct four-height vectors**. The median row is steps/s. These rates establish the above-60 test condition; **this is a correctness result, not a speed comparison or display/GPU-completion measurement**. | | main @ d3bd2805 (Longshot measured build) | this PR @ 27375dbe (Longshot measured build) | |---|---|---| | Longshot, cap 240, pair 1 | 89.840; 100.00%; 989 / 0 / 1 | 88.244; 99.90%; 972 / 661 / 487 | | Longshot, cap 240, pair 2 | 88.579; 99.38%; 975 / 0 / 1 | 88.652; 99.80%; 976 / 660 / 488 | | Longshot cap-240 median delivered steps/s | 0.000 | 59.979 | | Longshot, shared-load cap 240 | 84.775; 97.86%; 933 / 9 / 8 | 41.852; rejected, counters unread | | Longshot, shared-load cap 60 | Not rerun | 34.864; 0.52%; 384 / 426 / 193 | ### Earlier Hookshot measurements, before the rename Baseline: Hookshot main + local entry tracing @ e2057b2b This historical comparison is retained from the original pull request, not a current-main rerun: the baseline is the old pinned Hookshot source plus local entry tracing, and the fixed build is the original floor-web change. It is not a speed comparison with current Longshot. | | Hookshot main + local entry tracing @ e2057b2b | Hookshot floor-web fix @ 25333d94 | |---|---|---| | Earlier Hookshot, cap 60 | 59.996; 52.04%; 661 / 661 / 274 | 59.937; 50.38%; 660 / 660 / 270 | | Earlier Hookshot, cap 240 | 87.981; 99.59%; 969 / 0 / 1 | 89.290; 99.90%; 983 / 660 / 492 | Both held main runs delivered zero steps and kept one height vector; both fixed runs delivered about 60 steps/s and hundreds of changing vectors. The ordinary main run's nine one-step observations are expected when some updates last a whole frame: its other 924 updates yielded zero. The ordinary fixed high-cap attempt stayed below 60 and was rejected before its counters were read. The cap-60 control reacted, but under load it reached only 34.864 presents/s; it is not a sustained-60-Hz proof. The earlier Hookshot rows are carried from the original pull request, not reruns. Their baseline used local entry tracing and a different base, so they are not a matched speed comparison with Longshot. New counts mean observed ring-index changes, not an added entry counter; held sampling covered at least 99.79% of present numbers. The heights are read from the web itself, so camera movement cannot be mistaken for web movement. Observation output and build identities: ```text [hos host] longshot v2.2.0-rc.1-15-gd3bd28050 (source 2bce0d57) [hos host] longshot v2.2.0-rc.1-17-g27375dbe9 (source fc14c184) Longshot base cap240 ordinary: presents/s=84.775; updates=933; steps=9; height_vectors=8; steps/s=0.818 Longshot fixed cap60 ordinary: presents/s=34.864; updates=384; steps=426; height_vectors=193; steps/s=38.677 Longshot base cap240 held run 1: presents/s=89.840; updates=989; steps=0; height_vectors=1; steps/s=0.000 Longshot fixed cap240 held run 1: presents/s=88.244; updates=972; steps=661; height_vectors=487; steps/s=60.009 Longshot base cap240 held run 2: presents/s=88.579; updates=975; steps=0; height_vectors=1; steps/s=0.000 Longshot fixed cap240 held run 2: presents/s=88.652; updates=976; steps=660; height_vectors=488; steps/s=59.949 Longshot base cap240 held median: steps/s=0.000; steps=0.0; height_vectors=1.0 Longshot fixed cap240 held median: steps/s=59.979; steps=660.5; height_vectors=487.5 ``` Earlier, on the measured source 27375dbe, I ran the whole game-free suite locally, with the repository's default compiler selection and the exact command `python -I -B tests/run_all.py --jobs 6 --strict`. These checks have not yet been run on a forge runner. ```text 508 passed, 1 failed, 20 skipped in 206 s (linux, 6 at once) ``` The new floor fixture passes here; against main it fails, including: ```text FAIL: 240-Hz first floor must run 60 steps, not zero or 240 FAIL: 240-Hz second floor must keep its own fraction FAIL: 120-Hz floor must run 60 steps ``` Windows-target syntax on the measured Longshot code passed one captured C unit (the unchanged fixture is carried across the rebases, not rerun here); Windows execution was not run. Every Longshot game run exited 0, with no fatal, crash, device-loss or kernel-driver fault and complete journal coverage. The comparison was built and run on main d3bd2805. Afterwards the branch was rebased onto main d4a69456 without any change (range-diff equal for all three commits); the commits in between do not touch `nx2/oot_patches.py` or the host frame-step mechanism, and the floor test passes on the rebased branch. It was not rebuilt or rerun in the game after that rebase. The measured builds remain on d3bd2805; the newer main d725b3631 adds preparation/bug-report changes, save tools and forge scripts/docs/tests but does not touch the patched file or frame-step mechanism, confirmed by an empty `git diff d3bd2805..d725b3631 -- nx2/oot_patches.py host`, including `host/frame_whole.h`, `host/nn_vi.c` and `host/oot_high_fps.c`/`.h`. All three range-diff entries remain equal. No new build or game run was made. ## Testing **Tested:** on this PC (Arch Linux, RTX 4090 with NVIDIA 615.78.08, i9-13900K), the whole game-free suite and the floor-step fixture, including its expected failures against main; Windows-target syntax checked one C unit, not Windows execution. In the game, the Deku Tree floor web at 1280×720 and 50% render scale, frame generation off: after at least 10 s in the scene, three jumps per run, main/fixed/main/fixed at cap 240 with actual presents above 60, plus the shared-load controls described above. The step counts and web heights, normal exits and driver logs were checked. Tested but not measured: the rejected shared-load cap-240 candidate completed the three jumps, but its deformation counters were deliberately not examined because the above-60 prerequisite failed; no other gameplay is claimed. **Not tested:** Intel and AMD gameplay; other interactive floors such as the flying carpet; long play, web-breaking progression, swapchain/display timing, or sustained 60-Hz Longshot play. The runs were bounded to the stated web scene on this PC, and the cap-60 control was below 60 under load. The updater is shared by interactive floors, so those remain a risk. No cross-hardware test request has been opened. Above-60 play remains experimental. **Needs other testers:** - Windows x64: run the floor-step fixture, then stand and jump three times on the Deku Tree floor web at a 240 fps cap with actual game presents above 60, expecting the fixture passes and the web bends and rises instead of freezing (test request T-YKGE) ## Screenshots main @ d3bd2805: panels 1 and 2, cap 240, standing and jumping with the web frozen. this PR @ 27375dbe: panels 3 and 4, cap 240, the web bends and rises; panels 5 and 6, cap-60 control under shared load. These captions name the actual measured builds, not the rebased heads. ![1 and 2: main at a 240 cap, standing and jumping, the web stays still. 3 and 4: with the fix at a 240 cap, the web bends and rises. 5 and 6: with the fix at a 60 cap, under shared load.](https://git.magicbean.dev/attachments/cfbc2ea9-4c11-4a5c-ac48-7af95dbda9d5) ## Risk and rollback The updater is shared by interactive floors, including the flying carpet: retaining fractional steps could change an untested floor's animation or interaction. The existing 0..3 clamp and cap-60 path remain unchanged. Revert this PR to remove the table entry and its regression test if it regresses another floor; there is no runtime switch for this fix. ## Reviewer notes Start with the `f_80652cb0` entry in `nx2/oot_patches.py`'s `WHOLE_SITES`, then `patch_whole_frames` and `tests/test_web_floor_steps.py`. The key keeps each object's fraction separate; no shared mechanism was refactored. The docs rows and uploaded picture are retained across the rebases. The limited hardware/area coverage is explicit above; this update changes the branch base and description, not the fix or measured evidence. ## Issues Fixes #86 Original bug report: https://github.com/NotRexed/Hookshot/issues/2667. ## 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. - [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] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] Screenshots for a change that shows on screen. - [x] A row in `docs/tested-configurations.md` for each measured run. - [x] A game-free test added for the fix, failing on `main` and passing here. - [x] Docs updated. --- Moved from NotRexed/Hookshot#2929. Assisted-by: GPT-6 Astra Co-Authored-By: GPT-6 Astra <[email protected]>
Carry each interactive floor object’s fractional simulation steps through the existing WHOLE_SITES mechanism. Leave its 0..3 clamp and the cap-60 path unchanged.

Cover 60/120/240-Hz updates, independent object remainders, clamp bounds and long pauses with an authored game-free fixture.

Assisted-by: GPT-6 Astra

Co-Authored-By: GPT-6 Astra <[email protected]>
Record the matched 60/240-cap jump proof on the fixed binary, with the rejected shared-load attempt and untested hardware kept explicit.

Assisted-by: GPT-6 Astra

Co-Authored-By: GPT-6 Astra <[email protected]>
Record the pinned main/fix A/B/A/B proof at cap 240, the shared-load cap-60 control and the rejected high-cap attempt. Keep the earlier Hookshot evidence unchanged.

Assisted-by: GPT-6 Astra

Co-Authored-By: GPT-6 Astra <[email protected]>
mooki changed title from fix(runtime): let the floor web react above 60 fps to WIP: fix(runtime): let the floor web react above 60 fps 2026-11-13 00:58:44 +00:00
Author
First-time contributor

Back to work in progress, for its description only. This was opened shortly before #48 merged and follows the earlier template, so it does not pass the new description check (no Flags and settings and no Risk and rollback section, table columns named Before and After). The code and the measurements are unchanged: the whole suite passes on this exact commit apart from one local .NET failure that also fails on main. The description is being moved to the new template and the branch rebased onto d725b363; it comes back through pr ready once the check passes.

Back to work in progress, for its description only. This was opened shortly before #48 merged and follows the earlier template, so it does not pass the new description check (no Flags and settings and no Risk and rollback section, table columns named Before and After). The code and the measurements are unchanged: the whole suite passes on this exact commit apart from one local .NET failure that also fails on main. The description is being moved to the new template and the branch rebased onto d725b363; it comes back through `pr ready` once the check passes.
Author
First-time contributor

Rebased onto d725b3631 as 440fef872 with all three carried commits unchanged. The description now follows the new template, names each measured build and baseline, and keeps the uploaded picture and every earlier result; the description checker passes without WIP. The whole suite on this exact head reports 511 passed, 1 failed and 20 skipped, with only the same missing .NET reference-pack failure as main (510 passed, 1 failed, 20 skipped). The game evidence remains on d3bd2805 because nx2/oot_patches.py and the host frame-step mechanism are unchanged; the game was not rebuilt or rerun.

Rebased onto d725b3631 as 440fef872 with all three carried commits unchanged. The description now follows the new template, names each measured build and baseline, and keeps the uploaded picture and every earlier result; the description checker passes without WIP. The whole suite on this exact head reports 511 passed, 1 failed and 20 skipped, with only the same missing .NET reference-pack failure as main (510 passed, 1 failed, 20 skipped). The game evidence remains on d3bd2805 because `nx2/oot_patches.py` and the host frame-step mechanism are unchanged; the game was not rebuilt or rerun.
mooki changed title from WIP: fix(runtime): let the floor web react above 60 fps to fix(runtime): let the floor web react above 60 fps 2026-11-13 01:19:18 +00:00
mooki force-pushed fix/web-floor-step-carry from 9926c1cba3 to 440fef872d 2026-11-13 01:19:19 +00:00 Compare
mooki changed title from fix(runtime): let the floor web react above 60 fps to WIP: fix(runtime): let the floor web react above 60 fps 2026-11-13 01:48:31 +00:00
Author
First-time contributor

Back to work in progress for two reasons, neither a change to the code or the measurements. The template gained a Testing section with #72 (what was tested, what was not, and which testers are needed, with test requests), which this description does not have yet. And #39's merge added a row to the results table at the same place as this pull request's rows, so the branch conflicts in that one file until it is rebased. Both are being done; it returns through pr ready.

Back to work in progress for two reasons, neither a change to the code or the measurements. The template gained a Testing section with #72 (what was tested, what was not, and which testers are needed, with test requests), which this description does not have yet. And #39's merge added a row to the results table at the same place as this pull request's rows, so the branch conflicts in that one file until it is rebased. Both are being done; it returns through `pr ready`.
Author
First-time contributor

The description now has the current template's Testing section: what was tested, what was not, and which testers are needed; the test request is open (T-YKGE). Rebased onto main f41db065c keeping both sides' rows of the results table; whole suite on the new head 7f840c0ae: 510 passed, 0 failed, 19 skipped. Ready for review.

The description now has the current template's Testing section: what was tested, what was not, and which testers are needed; the test request is open (T-YKGE). Rebased onto main f41db065c keeping both sides' rows of the results table; whole suite on the new head 7f840c0ae: 510 passed, 0 failed, 19 skipped. Ready for review.
mooki force-pushed fix/web-floor-step-carry from 440fef872d to 7f840c0ae5
Some checks are pending
Linux AppImage / appimage (pull_request) Blocked by required conditions
Windows builder / Longshot Builder zip (pull_request) Blocked by required conditions
Windows builder / Windows Vulkan back end (llvm-mingw) (pull_request) Blocked by required conditions
Windows builder / dav1d for Windows (llvm-mingw) (pull_request) Blocked by required conditions
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / Python source checks (windows-2022, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (windows-2022, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
Vulkan back end with NVIDIA DLSS / Windows Vulkan back end with NVIDIA DLSS and AMD FSR 4 (llvm-mingw, link check) (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 2s
2026-11-13 02:39:11 +00:00
Compare
mooki changed title from WIP: fix(runtime): let the floor web react above 60 fps to fix(runtime): let the floor web react above 60 fps 2026-11-13 02:39:12 +00:00
Some checks are pending
Linux AppImage / appimage (pull_request) Blocked by required conditions
Windows builder / Longshot Builder zip (pull_request) Blocked by required conditions
Windows builder / Windows Vulkan back end (llvm-mingw) (pull_request) Blocked by required conditions
Windows builder / dav1d for Windows (llvm-mingw) (pull_request) Blocked by required conditions
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / Python source checks (windows-2022, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (windows-2022, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
Vulkan back end with NVIDIA DLSS / Windows Vulkan back end with NVIDIA DLSS and AMD FSR 4 (llvm-mingw, link check) (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 2s
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
Some workflows are waiting to be reviewed.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'fix/web-floor-step-carry:mooki-fix/web-floor-step-carry'
git switch 'mooki-fix/web-floor-step-carry'
Sign in to join this conversation.
No description provided.