Keybinding Manager

Create keyboard shortcuts with a fluent API: simple keys, combos, double-tap, and context-aware callbacks.

Package: fr.eri.eriapi.keys Fluent API Minecraft 1.12.2

Introduction

The Keybinding Manager lets you create keyboard shortcuts for your mod without wrestling with Forge's raw keybinding infrastructure. Using a clean fluent API, you can declare simple keys, multi-key combos (e.g. Ctrl+Shift+X), double-tap shortcuts, and attach onPress, onRelease, or onHold callbacks to each binding.

Bindings are context-aware: you can restrict a shortcut to be active only in-game, only when a GUI is open, or always. Automatic conflict detection warns you at registration time if two bindings share the same key and context, making debugging painless.

Where to register keybindings

Call EriKeys.create(...).register() inside your ClientProxy.init() method, during the FMLInitializationEvent. Registering on the server side has no effect — keybindings are client-only.

EriKeys — Static API

EriKeys is the entry point for the entire Keybinding Manager. Every binding starts with a call to EriKeys.create(id), which returns a fluent builder. Chain the methods you need, then finish with .register().

Simple key

The most basic binding: one key, one action.

Java — Simple key binding
EriKeys.create("open_menu")
    .key(Keyboard.KEY_G)
    .category("My Mod")
    .onPress(() -> openMenu())
    .register();

Combo — Ctrl+Shift+G

Use .combo(KeyCombo) instead of .key(int) to require modifier keys. Combos are evaluated only when every specified modifier is held at the moment the main key is pressed.

Java — Combo binding
EriKeys.create("debug_mode")
    .combo(KeyCombo.of(Keyboard.KEY_G).ctrl().shift())
    .category("My Mod")
    .context(KeyContext.IN_GAME)
    .onPress(() -> toggleDebug())
    .register();

Double-tap

Pass a maximum tick window to .doubleTap(maxTicks). The callback fires only when the key is pressed twice within that window. A value of 10 equals half a second at 20 ticks/second.

Java — Double-tap binding
EriKeys.create("dash")
    .key(Keyboard.KEY_W)
    .doubleTap(10)
    .category("My Mod")
    .onPress(() -> dash())
    .register();

Hold — onHold / onRelease

Use .onHold(Runnable) to run code every tick the key is held, and .onRelease(Runnable) to react when the key is lifted.

Java — Hold binding
EriKeys.create("sprint")
    .key(Keyboard.KEY_R)
    .category("My Mod")
    .onHold(() -> sprint())
    .onRelease(() -> stopSprint())
    .register();

Builder method reference

Every method in the builder returns this, so they can be freely chained in any order.

API — EriKeys builder methods
EriKeys.create(String id)            // Start a new binding with the given unique ID
    .key(int keyCode)                // Bind to a single key (Keyboard.KEY_*)
    .combo(KeyCombo combo)           // Bind to a key combination
    .category(String category)       // Display category in the vanilla controls screen
    .context(KeyContext context)     // Restrict activation context (default: ALWAYS)
    .doubleTap(int maxTicks)         // Require two presses within maxTicks ticks
    .onPress(Runnable callback)      // Called on key press (or second tap if doubleTap)
    .onRelease(Runnable callback)    // Called when key is released
    .onHold(Runnable callback)       // Called every tick while key is held
    .register();                     // Finalise and register the binding
Unique IDs are required

The string passed to EriKeys.create() must be unique across your entire mod. A good convention is "modid.action_name" — for example "myrpgmod.ability1".

KeyCombo — Combinations

KeyCombo describes a key together with optional modifier requirements. Build one with the static factory KeyCombo.of(keyCode), then chain modifiers.

Java — KeyCombo examples
KeyCombo.of(Keyboard.KEY_G)                 // G only (no modifiers)
KeyCombo.of(Keyboard.KEY_G).ctrl()          // Ctrl + G
KeyCombo.of(Keyboard.KEY_G).ctrl().shift()  // Ctrl + Shift + G
KeyCombo.of(Keyboard.KEY_G).alt()           // Alt + G

Modifier methods available on KeyCombo:

  • .ctrl() — requires the Control key to be held
  • .shift() — requires the Shift key to be held
  • .alt() — requires the Alt key to be held
Modifiers are additive

You can chain as many modifiers as you like. KeyCombo.of(KEY_G).ctrl().shift().alt() will only fire when all three modifiers are held simultaneously.

KeyContext — Enum

KeyContext controls when a binding is active. Assign it with .context(KeyContext.XXX) on the builder. If you omit it, the default is ALWAYS.

Java — KeyContext values
KeyContext.IN_GAME   // Active only when no GUI is open (pure gameplay)
KeyContext.IN_GUI    // Active only when a GUI screen is open
KeyContext.ALWAYS    // Always active, regardless of GUI state (default)

Choosing the right context prevents accidental triggers. For example, a dash ability bound to W should use IN_GAME so it never fires while you are typing in a chat box.

IN_GUI and EriGuiScreen

KeyContext.IN_GUI is useful for shortcuts inside your own menus — for example pressing Escape or F to trigger a specific action while a custom EriAPI GUI is open.

KeyConflictDetector

KeyConflictDetector runs automatically every time a binding is registered via .register(). You do not need to call it manually.

At registration time it checks whether any already-registered binding shares the same effective key (main key + modifiers) and the same KeyContext. If a conflict is found, a warning is written to the game log:

Log output — conflict warning
[EriAPI/WARN] KeyConflictDetector: binding "mymod.ability2" conflicts with
"mymod.ability1" (same key G + context IN_GAME). Both are registered but
only the first one may fire reliably.
Conflicts do not prevent registration

Both conflicting bindings are still registered. The warning is informational — it is up to you to resolve the conflict by changing one of the keys or contexts.

Complete Example

The snippet below registers two ability shortcuts for a hypothetical RPG mod. Both are restricted to in-game context so they never interfere with chat or menus. The second uses a combo to avoid conflicting with the first.

Java — ClientProxy.java
// In ClientProxy.init()
EriKeys.create("mymod.ability1")
    .key(Keyboard.KEY_V)
    .category("My RPG Mod")
    .context(KeyContext.IN_GAME)
    .onPress(() -> useAbility(1))
    .register();

EriKeys.create("mymod.ability2")
    .combo(KeyCombo.of(Keyboard.KEY_V).shift())
    .category("My RPG Mod")
    .context(KeyContext.IN_GAME)
    .onPress(() -> useAbility(2))
    .register();

Because ability2 uses Shift+V while ability1 uses plain V, they do not conflict. KeyConflictDetector will log no warning.

Combine with NotificationManager for feedback

Show the player a visual confirmation when an ability is triggered: NotificationManager.getInstance().success("Ability 1 activated!");