feat(input): sprint on Shift or the left stick's press, without the roll #2604

Open
guilhermebueno6 wants to merge 1 commit from guilhermebueno6/feat/sprint into main
guilhermebueno6 commented 2026-11-12 01:22:28 +00:00 (Migrated from github.com)

On keyboard and mouse there is no way to run without holding the game's A key, and pressing A while moving makes Link roll first. This adds a Sprint control: hold Shift, or press the left stick once on a controller, and Link runs without the roll.

What changed

  • Sprint control (HOS_KEY_SPRINT, after the ocarina note controls): keys and two gamepad slots, which trade inputs with the Switch buttons by the same slot rules (the ocarina notes keep sharing theirs). It holds A, the game's own run, only while the left stick or the movement keys are pushed, so standing still it does not talk, open or pick up.
  • No roll: A pressed while Link moves is a roll, so Sprint starts with A pressed and the stick let go for 120 ms, then gives the stick back with A still held. HOS_SPRINT_STILL_MS=<ms> in hookshot_env.txt tunes it (0 = the old behaviour, with the roll).
  • Shift runs while held. The left stick's press is a toggle: press once while moving, and Link runs until the stick returns to center, then it needs a new press.
  • Defaults: Shift and the left stick's press are Sprint's. The keyboard's B moves from Shift to V, and the stick's press is no longer the Switch's LS (rebindable on the Controls page).
  • Existing options files: a file from before this (options_version < 7) that still has the old defaults (Shift on B, the press on LS) gets the new ones; anything the player bound differently is kept, and Sprint takes none of its defaults another control already has. The menu now writes options_version=7.
  • Menu: a Sprint row on the Controls page (gamepad and keyboard columns, pad_sprint / key_sprint lines) and an on/off Sprint row on the Controls tab (HOS_OPT_SPRINT, 52; on by default).
  • MKWVK_API_VERSION 20: binding/bind take gamepad inputs for HOS_KEY_SPRINT.

Testing

  • python -I -B tests/run_all.py on Windows 11 (llvm-mingw): 402 passed, 15 failed; an unmodified main on the same PC fails the same 15 (401 passed), so nothing new fails and test_sprint is the extra pass. (test_input_background is among them on this compiler: clang's -Wunused-but-set-global on main's oc_consumed_pads. With that warning off it passes with Sprint.)
  • New tests/test_sprint.py: the binding table compiled alone against six options files (new install, old defaults migrated from version 4 and from version 6, rebound kept, V taken, version 7 kept) and binding swaps; sprint_step compiled alone (the still start, Shift held, the toggle and its end, nothing with the menu open); source checks for the menu rows, the option and the A-hold gate. test_input_background, test_bound_keys and test_menu_env_overrides updated for the new control.
  • In game (Windows 11, DualSense and keyboard): Shift and the left stick's press run without rolling; the toggle ends when Link stops; the old options file was migrated (hid: Shift is Sprint now, B is V in the log).

Screenshots

To be added: the Controls tab's Sprint row and the Controls page's Sprint row.

🤖 Generated with Claude Code

On keyboard and mouse there is no way to run without holding the game's A key, and pressing A while moving makes Link roll first. This adds a Sprint control: hold Shift, or press the left stick once on a controller, and Link runs without the roll. ## What changed - **Sprint control** (`HOS_KEY_SPRINT`, after the ocarina note controls): keys and two gamepad slots, which trade inputs with the Switch buttons by the same slot rules (the ocarina notes keep sharing theirs). It holds A, the game's own run, only while the left stick or the movement keys are pushed, so standing still it does not talk, open or pick up. - **No roll:** A pressed while Link moves is a roll, so Sprint starts with A pressed and the stick let go for 120 ms, then gives the stick back with A still held. `HOS_SPRINT_STILL_MS=<ms>` in `hookshot_env.txt` tunes it (0 = the old behaviour, with the roll). - **Shift** runs while held. **The left stick's press** is a toggle: press once while moving, and Link runs until the stick returns to center, then it needs a new press. - **Defaults:** Shift and the left stick's press are Sprint's. The keyboard's B moves from Shift to V, and the stick's press is no longer the Switch's LS (rebindable on the Controls page). - **Existing options files:** a file from before this (`options_version` < 7) that still has the old defaults (Shift on B, the press on LS) gets the new ones; anything the player bound differently is kept, and Sprint takes none of its defaults another control already has. The menu now writes `options_version=7`. - **Menu:** a Sprint row on the Controls page (gamepad and keyboard columns, `pad_sprint` / `key_sprint` lines) and an on/off **Sprint** row on the Controls tab (`HOS_OPT_SPRINT`, 52; on by default). - `MKWVK_API_VERSION` 20: `binding`/`bind` take gamepad inputs for `HOS_KEY_SPRINT`. ## Testing - `python -I -B tests/run_all.py` on Windows 11 (llvm-mingw): 402 passed, 15 failed; an unmodified `main` on the same PC fails the same 15 (401 passed), so nothing new fails and `test_sprint` is the extra pass. (`test_input_background` is among them on this compiler: clang's `-Wunused-but-set-global` on main's `oc_consumed_pads`. With that warning off it passes with Sprint.) - New `tests/test_sprint.py`: the binding table compiled alone against six options files (new install, old defaults migrated from version 4 and from version 6, rebound kept, V taken, version 7 kept) and binding swaps; `sprint_step` compiled alone (the still start, Shift held, the toggle and its end, nothing with the menu open); source checks for the menu rows, the option and the A-hold gate. `test_input_background`, `test_bound_keys` and `test_menu_env_overrides` updated for the new control. - In game (Windows 11, DualSense and keyboard): Shift and the left stick's press run without rolling; the toggle ends when Link stops; the old options file was migrated (`hid: Shift is Sprint now, B is V` in the log). ## Screenshots To be added: the Controls tab's Sprint row and the Controls page's Sprint row. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Owner

@Joey-Magnus reviewed on GitHub · 2026-11-12 14:33 UTC · original

I merged this into current main (it merges cleanly) and ran tests/run_all.py on Linux. 458 checks pass. The only failures are test_lift_cache, which fails on main on this machine too, and a test_recorder_sync timeout that passes when run alone. test_sprint, test_bound_keys, test_input_background and the menu tests all pass. Points for you and the maintainers:

  • This changes defaults for every player. The keyboard's B moves from Shift to V, and the left stick's press stops being the Switch's LS. binds_sprint_migrate (host/nn_hid.c:569) also rewrites existing options files that still have the old defaults. A maintainer should agree to that first.
  • Each time a sprint starts, sprint_step zeroes the stick for 120 ms (HOS_SPRINT_STILL_MS) with A held down. If Link is facing an NPC, a sign, a chest or a pot, that's an A press while standing. Pressing Shift right next to one could then talk, open or pick up, which is the very thing the steered gate is meant to prevent. Please check it in the game.
  • MKWVK_API_VERSION 20 is also claimed by #2600, #2317, #2261 and #2566. options_version=7 is free today.
    The screenshots of the two new rows are still "to be added". CONTRIBUTING asks for them on changes that show on screen.
> [@Joey-Magnus](https://github.com/Joey-Magnus) reviewed on GitHub · 2026-11-12 14:33 UTC · [original](https://github.com/NotRexed/Hookshot/pull/2604#pullrequestreview-5876220824) I merged this into current main (it merges cleanly) and ran tests/run_all.py on Linux. 458 checks pass. The only failures are test_lift_cache, which fails on main on this machine too, and a test_recorder_sync timeout that passes when run alone. test_sprint, test_bound_keys, test_input_background and the menu tests all pass. Points for you and the maintainers: - This changes defaults for every player. The keyboard's B moves from Shift to V, and the left stick's press stops being the Switch's LS. binds_sprint_migrate (host/nn_hid.c:569) also rewrites existing options files that still have the old defaults. A maintainer should agree to that first. - Each time a sprint starts, sprint_step zeroes the stick for 120 ms (HOS_SPRINT_STILL_MS) with A held down. If Link is facing an NPC, a sign, a chest or a pot, that's an A press while standing. Pressing Shift right next to one could then talk, open or pick up, which is the very thing the steered gate is meant to prevent. Please check it in the game. - MKWVK_API_VERSION 20 is also claimed by #2600, #2317, #2261 and #2566. options_version=7 is free today. The screenshots of the two new rows are still "to be added". CONTRIBUTING asks for them on changes that show on screen. <!-- github-sync:r:5876220824 -->
Commenting is not possible because the repository is archived.
No description provided.