Skip to content

hotkeys for adjusting step-by-step#2769

Open
aBlueShadow wants to merge 2 commits intodaid:masterfrom
aBlueShadow:weapon_aim_steps
Open

hotkeys for adjusting step-by-step#2769
aBlueShadow wants to merge 2 commits intodaid:masterfrom
aBlueShadow:weapon_aim_steps

Conversation

@aBlueShadow
Copy link
Contributor

This adds keybindings for 15 degree steps for the manual weapon aiming. When the binding is used, the aim will snap to the next multiple of 15 rather than just adding 15°.
That way you can use rotary encoders or knobs on macro keyboards for aiming. As they only send a short signal each step, they do not work reliably with the weapons_aim_left/weapons_aim_right bindings.
Each step is a 1/24th of a full circle, which means you will hit both 8 cardinal and 12 "clock" directions. It is also pretty close to the 20 steps per rotation that many rotary encoders have, and you won't get a perfect positional match anyway.

@aBlueShadow aBlueShadow changed the title hotkeys for aiming step-by-step hotkeys for adjusting step-by-step Mar 8, 2026
@aBlueShadow
Copy link
Contributor Author

Also added keybinding for adjusting scanning parameters stepwise.
I wasn't sure about the step size, but 0.2 seems to be a reasonable compromise between accuracy and speed. I was able to reliably deep-scan multiple objects with a 2-knob keyboard. Of course a 3 or even 4 param that might look different, but those are pretty rare anyways in scenarios, and can be avoided for normal ship scans.

@oznogon
Copy link
Contributor

oznogon commented Mar 9, 2026

That way you can use rotary encoders or knobs on macro keyboards for aiming. As they only send a short signal each step, they do not work reliably with the weapons_aim_left/weapons_aim_right bindings

I haven't seen an issue filed on this. What is the issue?

Is the use case that you want to adjust the sensitivity for keypress binds that adjust a slider or dial or similar control? Or does the encoder simply not register?

If the unreliable behavior with knobs/encoders is fixed, would these keybinds become redundant?

@oznogon
Copy link
Contributor

oznogon commented Mar 9, 2026

I ask because if we can make it so that any applicable keybind's rate and behavior are tuneable, we wouldn't have to implement stepwise logic ad hoc for each input. Could do it once instead of dozens of times and again for any new binds.

@aBlueShadow
Copy link
Contributor Author

I haven't filed an issue because I just got one of those macro keyboards the other day, And as my implementation is basically the same as your patches for impulse and jump controls (which was ironically introduced because the other bindings where too sensitive for key presses), which also work fine for that hardware.

Or does the encoder simply not register?

Almost never. Maybe once or twice per 20-step revolution. My assumption is that the pulses are too short.

I ask because if we can make it so that any applicable keybind's rate and behavior are tuneable, we wouldn't have to implement stepwise logic ad hoc for each input. Could do it once instead of dozens of times and again for any new binds.

Of course it would be nice if we have less keybinds, but on the other hand we already started it with the helms and jump controls and I don't think there is much left. I think only 4 for the engineering slider, and theoretically 2 for ship rotation, but I think holding down a key feels much better than rotating a knob.
There would still be others, but it doesn't really make sense to do, say, combat maneuvers with a dial anyway. So if I haven't missed anything, it is just this PR, engineering and maybe helms rotation that realistically make sense with a dial.

@daid
Copy link
Owner

daid commented Mar 9, 2026

For custom controls, doesn't it makes a lot more sense to use an "analogue" joystick axis?

@aBlueShadow
Copy link
Contributor Author

Well, the big advantage is that you can buy those keyboards off the shelf. For off-the-shelf analog controls you might be able to use throttles to move sliders, but those are usually much more expensive. Regular gaming joysticks have the obvious disadvantage of self-centering and feel also a bit awkward to use outside of helms and weapons.
And for the weapon aiming specifically, IMO the jog dial works very well. Of course a custom made controller with a potentiometer could work perfectly smooth, but for that to work, you'd either need connect to the http server or add yet another binding that sets the aim directly.

@oznogon
Copy link
Contributor

oznogon commented Mar 9, 2026

my implementation is basically the same as your patches for impulse and jump controls (which was ironically introduced because the other bindings where too sensitive for key presses)

The impulse controls change was a hack introduced to workaround a regression introduced by SDL2. I'm not sure they're role models. An actual fix would replace those stepwise binds with sensitivity and rate-of-change settings for binds that involve sliders and dials, which would also fix them on keyboards (AimLock also moves way too fast for me on keypress) and tunable for different types of inputs (A2D pots, hats, gamepads, joysticks, etc.).

Or does the encoder simply not register?

Almost never. Maybe once or twice per 20-step revolution. My assumption is that the pulses are too short.

This is a bug that should be addressed by making sensitivity and rates of change configurable. Logging would confirm assumptions about whether the steps are registering. This would also fix the bug I'd expect to ensue from this implementation when someone uses a different encoder than yours or a potentiometer.

I ask because if we can make it so that any applicable keybind's rate and behavior are tuneable, we wouldn't have to implement stepwise logic ad hoc for each input. Could do it once instead of dozens of times and again for any new binds.

Of course it would be nice if we have less keybinds

The point isn't fewer keybinds. It's:

  • to make press-and-hold events on keyboards configurable such that they work the way the user wants them to work
  • to make existing slider and dial controls function with any arbitrary encoder knob, poteniometer, analog or digital gamepad, HOTAS hat, etc.
  • to make any future slider and dial controls work without copying and pasting more redundant stepwise logic code
  • most importantly, to handle keyboard, joystick, gamepad, mouse, and arbitrary digital encoder/A2D pot knobs and sliders appropriately, even when we have no way of detecting which of those is in use

we already started it with the helms and jump controls and I don't think there is much left

If y'all want to do this for every control, that's fine. In the end it's just more code to remove, and more user-facing configurations that break, when the input system is improved.

maybe helms rotation that realistically make sense with a dial.

There are already at least two PRs to fix helms rotation, and I wager both are mostly incompatible with encoders because they undo a stepwise implementation. Which goes back to needing to handle different types of inputs differently, even when we can't detect when a keyboard event is one rotary step, four rotary steps, an A2D pot value turned into a keypress event by a microcontroller, a joystick axis fed through Joy2Key, etc.

@oznogon
Copy link
Contributor

oznogon commented Mar 9, 2026

Filed #2770 to get at the core issue that this is a symptom of.

@aBlueShadow
Copy link
Contributor Author

AimLock also moves way too fast for me on keypress

Jep, I mentioned just impulse control in #1739 because it was the first instance where I noticed the issue. It is basically present everywhere where getValue() is used instead of getDown(), i.e. bindings designed with joystick axes in mind.

Fun fact: the impulse workaround actually works better for dial knobs then it works for keys, because you have to press the key for every single step.

The point isn't fewer keybinds. It's:
to make press-and-hold events on keyboards configurable such that they work the way the user wants them to work
to make existing slider and dial controls function with any arbitrary encoder knob, poteniometer, analog or digital gamepad, HOTAS hat, etc.
to make any future slider and dial controls work without copying and pasting more redundant stepwise logic code
most importantly, to handle keyboard, joystick, gamepad, mouse, and arbitrary digital encoder/A2D pot knobs and sliders appropriately, even when we have no way of detecting which of those is in use

Which is basically what I meant. However I am not entirely sure if that last part is feasible?

If y'all want to do this for every control, that's fine.

It currently looks very much like those PR won't be merged, so I don't think it will happen, and I stopped my work on the engineering part. But in my defense, I was not talking about every control, just a handful.

And I am not at all imposed to an elegant solution that handles all kind of input properly. It just seemed that workarounds were the way to go on that matter, and more importantly, within my capabilities.

@oznogon
Copy link
Contributor

oznogon commented Mar 9, 2026

I am not entirely sure if that last part is feasible?

It's feasible if sensitivity is user-configurable. If we can't rely on detection (if we can't rely on keypresses always coming from a keyboard, in this case) then we should offer the option for the user to define at least some aspects of how the event is handled. Especially those that are hardcoded, like the 5.0f factor on the existing AimLock keybinds, which should be higher for a stepped input (say, 15 degrees per input) and lower for a sustained input (say, 0.25 degrees per held update).

Likewise, sliders should have a similar behavior for stepped vs. sustained inputs, and that should be centralized in at least the GuiSlider implementation, if not higher. Then we get that benefit across every engineering, science, and helms slider, without having to tweak each one separately.

in my defense

I'm not attacking you, and insofar as I'm attacking anything, it's the underlying problem with the input system. Similar to the cursor issue, the prior implementation has been good enough until it started to be used and extended past the limited scope it was originally designed to accomplish.

What I'm anxious about is adding more workarounds that add user-facing config options and binds, which then get immediately removed or broken but linger in config files. That's an avoidable bad practice. Since this is happening between releases, things like this PR or the jump controls having a workaround aren't that big of a deal (everything on this branch is unstable), but IMO a broader input fix should be decided and acted on before there's an ECS release. A bigger cost of effort to fix it at the input and GuiElement levels, to also eliminate the need to piecemeal it inconsistently at the crew screen level.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants