Skip to content

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

Open
guilhermebueno6 wants to merge 1 commit into
NotRexed:mainfrom
guilhermebueno6:feat/sprint
Open

guilhermebueno6 wants to merge 1 commit into
NotRexed:mainfrom
guilhermebueno6:feat/sprint

Conversation

@guilhermebueno6

@guilhermebueno6 guilhermebueno6 commented Nov 12, 2026 •

Copy link
Copy Markdown

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

The game runs while A is held, and A pressed while Link moves is a roll.
Sprint is a new control, with keys and a gamepad input, that holds A
only while Link is steered, started with the stick let go for 120 ms
(HOS_SPRINT_STILL_MS) so the run comes without the roll. Tested in game.

- Defaults: Shift (held) and the left stick's press (a toggle: pressed
  once while moving, Link runs until the stick comes back to the
  middle). B moves from Shift to V; the stick's press is no longer the
  Switch's LS.
- An options file from before Sprint (options_version < 7) that still
  has Shift on B and the press on LS gets the new defaults; bindings the
  player changed are kept, and Sprint takes none of its defaults that
  another control has.
- The Controls page has a Sprint row; pad_sprint and key_sprint lines.
  The Controls tab's Sprint row (HOS_OPT_SPRINT, 52; on by default) turns it
  off.
- HOS_KEY_SPRINT (after the ocarina notes) in vk_api.h: MKWVK_API_VERSION 20.
  Sprint has two gamepad slots and trades them by the Switch buttons' slot
  rules; options_version 7.
- tests/test_sprint.py: defaults, migration cases, binding swaps, and
  sprint_step compiled alone (the still start, the hold, the toggle).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@Joey-Magnus Joey-Magnus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants