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!");