Key bindings
Let players pick a key with the Keybind widget, store it as text with Key.name, and compare it with the game's input on old and new versions.
Steps
The Keybind widget lets the player pick a key. The key is a Key, which is the same object on every Minecraft version, so your config and menu stay version-independent.
Edit a key in the menu#
Keybind.builder("zoomKey")
.label(Text.translatable("mymod.zoomKey", "Zoom"))
.value(() -> config.zoomKey) // null or Key.UNBOUND show as unbound
.onChange(key -> config.zoomKey = key)
.build();
The player clicks the button, then presses a key or mouse button. Escape unbinds (your onChange receives
Key.UNBOUND). Call .allowMouse(false) to accept keyboard keys only.
Make keys#
| Call | Gives |
|---|---|
Key.keyboard(glfwCode) |
a keyboard key by its GLFW key code, e.g. Key.keyboard(82) for R, Key.keyboard(340) for Left Shift |
Key.mouse(button) |
a mouse button: 0 left, 1 right, 2 middle, 3 and up the side buttons |
Key.UNBOUND |
no key |
Key.ESCAPE |
the Escape key |
Key is immutable; compare keys with equals. isUnbound(), type() (KEYBOARD or MOUSE) and code()
describe a key, and englishName() gives "R", "Left Shift" or "Not Bound" for logs and tests (the widget itself
shows vanilla's translated name).
Store a key#
name() is the text 1.13+ writes to options.txt, and Key.fromName reads it back:
String stored = config.zoomKey.name(); // "key.keyboard.z"
Key loaded = Key.fromName(stored); // null if the text is no key name
config.zoomKey = loaded != null ? loaded : Key.keyboard(90); // default: Z
The same text works on every version, including 1.7.10 – 1.12.2, so one config file format fits all.
Reset to a default#
Keep the built Keybind and call set, which passes the key to your onChange:
Keybind zoom = Keybind.builder("zoomKey")
.label(Text.translatable("mymod.zoomKey", "Zoom"))
.value(() -> config.zoomKey)
.onChange(key -> config.zoomKey = key)
.build();
Button reset = Button.builder("zoomKey.reset")
.label(Text.translatable("mymod.zoomKey.reset", "Reset"))
.onPress(() -> zoom.set(Key.keyboard(90)))
.build();
Check the key in game#
Listening for input is version-specific, so it belongs in your game layer (Build one mod for every loader). Compare the key there with what that version's input gives you:
| Minecraft | Input codes | Compare with |
|---|---|---|
| 1.13 – 26.3 | GLFW key codes; mouse buttons by number | key.code() and key.type() |
| 1.7.10 – 1.12.2 | LWJGL 2 key codes; mouse button b as -100 + b |
key.toLwjgl2() |
Key.fromLwjgl2(code) converts the other way. A few keys exist on only one side: F20 – F25 and the World 1/2
keys can't be bound on 1.7.10 – 1.12.2, and LWJGL 2 keys with no GLFW equivalent become Key.UNBOUND.
Test it#
FakeHost.pressKey(id, key) clicks the button and presses the key:
host.pressKey("zoomKey", Key.keyboard(82));
assertTrue(host.render().contains("[keybind zoomKey] Zoom: R"));
host.pressKey("zoomKey", Key.ESCAPE);
assertEquals(Key.UNBOUND, config.zoomKey);
Next steps#
- Keybind: every builder option.
- Open your menu: open the menu from your own key.