Add keybind registration API
Pathoschild opened this issue ยท 4 comments
Extend the helper.Input
API to let mods register key bindings, optionally with an in-game UI which lets the user change bindings.
See #744 for a proposed API with a smaller scope.
Some preliminary requirements per discussion in #modding:
- Allow multi-key bindings.
- Allow optional secondary combo for each binding to support keyboard + controller.
- Allow saving/reading key bindings to JSON:
{ "LookupKey": "CTRL + ALT + S, LeftTrigger + ControllerA" }
- Allow resetting or clearing a key binding.
- Require translatable name (and possibly description) for a future key binding UI.
Possible API designs:
- Design A (not persisted automatically). This is simple and flexible; mods can create a binding on the fly, read/write it to
config.json
, have per-save bindings if they want, change key bindings to avoid conflicts automatically, etc. Modders must persist the key binding themselves.IKeyBinding binding = helper.Input.RegisterBinding("name-translation-key", new[] { SButton.LeftControl, SButton.LeftAlt, SButton.S }); binding.OnPressed += this.OnBindingPressed;
- Design B (read/write to
config.json
for user convenience). Less flexible than design A, but persistence is automatic. Players can edit key bindings inconfig.json
just like before, but this depends on modders adding the property to their config model.IKeyBinding binding = helper.Input.RegisterBinding("name-translation-key", "config_property_name"); binding.OnPressed += this.OnBindingPressed;
- Design C (read/write to global data API). Less flexible than design A, but persistence is automatic. This doesn't depend on modders adding a property to their config model, but it's less intuitive for players since some mod options aren't editable via
config.json
.IKeyBinding binding = helper.Input.RegisterBinding("id-unique-within-mod", "name-translation-key"); binding.OnPressed += this.OnBindingPressed;
The ideal is to possibly support a key bind UI (not necessarily in the first release). This would be something similar to this Minecraft UI, where each mod is a section:
Unfortunately there's a few issues with that approach:
- Key bindings can be contextual. For example, one mod might only respond to a key on the title screen while another only handles it in-game; even though both use the same key, they don't conflict.
- Two mods might use the same key with different modifiers (e.g.
CTRL + S
vsALT + S
). The key would be listed in both manifests, but there's no actual conflict. - If the key binding is changed in
config.json
(which might be included in the download), the value inmanifest.json
would be misleading. - Mods often have multiple key bindings, so SMAPI would have no way to know which key is the default for each binding.
How about let, or prompt moder to declare default key usage info in "manifest.json"?, so that player can recognize potential key conflict at least, and change key setting accordingly. There may be such key assignment info in "config.json", but at mod install time, it is not created yet, so not available to player to check. If default keys are listed in "manifest.json", it would be much easier for player to use the the mod in game and to check potential key conflict of all mods.
Example entry in "manifest.json",
"UsedButtons": "OemTilde, P, F8, ControllerA, RightShoulder,~LeftControl"
"UsedButtons": "None" (for mod that does not use keyboard key)
The "~" notation before LeftControl is to denote that it is used as modifier key or used only in some special case like in Menu or debugging, so that the key can be shared with other mod without conflict so no need to worry or change.
For the time being, SMAPI will not utilize such info, or just print warning log for potential key bind conflict with the SDV game key binding or other installed mods.
And it may be interim solution and preparing for future with key assignment API you suggested, before such API is widely adopted by future updated mod's. It does not require source code change, just editing and adding one entry to "manifest.json" will do and it can be done on mod without source code, or even by the player.
And it is good for suggested keybinding API, because the SMAPI can get key binding infos of those old mod that does not use new keybinding API, but with such Default key entry. If player changed the key binding of such old mod, simply change the "UsedButtons" in "manifest.json" so that the keybinding API will avoid assigning such keys.
This measure can be done now so that all moder can follow the measure from now on , without new SMAPI 3.0 or keybind API will be available in future.
#744 adds a multi-keybind API in SMAPI 3.9. We could still add a keybind registry eventually, but I have no plans to work on one in the foreseeable future, so I'll close this ticket.