Keybinding Manager
Raccourcis clavier avances pour tes mods — touches simples, combos, double-tap, callbacks, et contextes.
Introduction
Le Keybinding Manager d'EriAPI te permet de definir des raccourcis clavier avec une fluent API claire et expressive. Plus besoin de gerer manuellement les evenements clavier ou les conflits — le framework s'en occupe pour toi.
Ce que tu peux faire
- Touche simple — appuie sur G pour ouvrir un menu
- Combinaisons (combos) — Ctrl+Shift+G pour activer un mode debug
- Double-tap — appuie deux fois rapidement sur W pour dasher
- Hold (maintien) — maintiens R enfonce pour sprinter
- Contextes — actif seulement en jeu, seulement dans un GUI, ou toujours
- Detection de conflits — avertissement automatique si deux touches se chevauchent
Toutes les classes du Keybinding Manager se trouvent dans le package fr.eri.eriapi.keys.
EriKeys — L'API statique
EriKeys est le point d'entree principal. Toutes les methodes sont statiques :
tu appelles EriKeys.create(...) pour demarrer la creation d'un raccourci,
tu enchaines les options avec la fluent API, et tu termines avec .register().
Touche simple
La forme la plus simple : une touche, une action. Ici, appuyer sur G appelle
la methode openMenu().
EriKeys.create("open_menu")
.key(Keyboard.KEY_G)
.category("Mon Mod")
.onPress(() -> openMenu())
.register();
Combo — Ctrl+Shift+G
Pour une combinaison de touches, utilise .combo(KeyCombo) a la place de
.key(int). Tu construis le combo avec KeyCombo.of(...)
puis tu chaines les modificateurs.
EriKeys.create("debug_mode")
.combo(KeyCombo.of(Keyboard.KEY_G).ctrl().shift())
.category("Mon Mod")
.context(KeyContext.IN_GAME)
.onPress(() -> toggleDebug())
.register();
Double-tap
Le parametre de .doubleTap(maxTicks) est la fenetre de temps maximale
(en ticks, 20 ticks = 1 seconde) entre les deux appuis pour que le double-tap
soit reconnu.
EriKeys.create("dash")
.key(Keyboard.KEY_W)
.doubleTap(10)
.category("Mon Mod")
.onPress(() -> dash())
.register();
Hold — maintien de touche
.onHold() est appele a chaque tick tant que la touche est enfoncee.
.onRelease() est appele une seule fois quand la touche est relachee.
Tu peux combiner les deux.
EriKeys.create("sprint")
.key(Keyboard.KEY_R)
.category("Mon Mod")
.onHold(() -> sprint())
.onRelease(() -> stopSprint())
.register();
Reference des methodes du builder
Chaque methode retourne this — tu peux les enchainer dans n'importe quel ordre,
tant que tu termines par .register().
EriKeys.create(String id) // Identifiant unique du raccourci (ex: "mymod.open_menu")
.key(int keyCode) // Touche simple (constantes Keyboard.KEY_*)
.combo(KeyCombo combo) // Combinaison de touches (remplace .key())
.category(String category) // Categorie affichee dans le menu Options > Touches
.context(KeyContext context) // Contexte d'activation (IN_GAME / IN_GUI / ALWAYS)
.doubleTap(int maxTicks) // Active la detection double-tap (fenetre en ticks)
.onPress(Runnable action) // Appele une fois a chaque appui (ou double-tap confirme)
.onRelease(Runnable action) // Appele une fois au relachement de la touche
.onHold(Runnable action) // Appele chaque tick pendant le maintien
.register(); // Enregistre le raccourci — OBLIGATOIRE a la fin
KeyCombo — Combinaisons de touches
KeyCombo permet de definir une combinaison de touches avec un ou plusieurs
modificateurs. Tu commences toujours par KeyCombo.of(int keyCode) en passant
la touche principale, puis tu chaines les modificateurs souhaites.
KeyCombo.of(Keyboard.KEY_G) // G seul (equivalent a .key(Keyboard.KEY_G))
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
KeyCombo.of(Keyboard.KEY_G).ctrl().alt() // Ctrl+Alt+G
Modificateurs disponibles
L'ordre dans lequel tu chaines .ctrl(), .shift() et .alt()
n'a pas d'importance. Ce qui compte, c'est qu'ils soient tous actifs au moment de l'appui
sur la touche principale.
KeyContext — Contextes d'activation
Le contexte determine quand ton raccourci est actif. Cela evite par exemple qu'un raccourci de jeu se declenche alors que le joueur est en train de taper dans un GUI.
EriKeys.create("my_action")
.key(Keyboard.KEY_F)
.context(KeyContext.IN_GAME) // Seulement en jeu, pas dans un menu
.onPress(() -> doSomething())
.register();
Valeurs de l'enum
Si tu n'appelles pas .context(), le contexte par defaut est
KeyContext.IN_GAME. C'est le comportement le plus courant et le plus sur.
KeyConflictDetector — Detection de conflits
Le KeyConflictDetector est integre automatiquement dans le processus d'enregistrement.
Tu n'as rien a configurer : chaque appel a .register() declenche une verification
automatique.
Comment ca marche
A chaque enregistrement, le systeme verifie si un raccourci deja enregistre partage la meme touche (ou combo) et le meme contexte. Si c'est le cas, un avertissement est emis dans la console de debug.
[EriAPI/WARN] KeyConflictDetector : conflit detecte !
Touche : KEY_G (context: IN_GAME)
Binding 1 : open_menu (Mon Mod)
Binding 2 : open_shop (Mon Mod)
Les deux bindings sont actifs dans le meme contexte avec la meme touche.
La detection de conflit n'empeche pas l'enregistrement du raccourci. Les deux bindings restent actifs — c'est au developpeur de resoudre le conflit en changeant la touche ou le contexte de l'un d'eux.
Bonnes pratiques pour eviter les conflits
- Prefixe tes identifiants avec le nom de ton mod :
"mymod.action" - Utilise des combos plutot que des touches seules pour les actions secondaires
- Specifie toujours un
KeyContextexplicite - Evite les touches que Minecraft utilise deja (W/A/S/D, E, Echap, Entree...)
Exemple complet
Voici un exemple realiste d'un mod RPG qui enregistre plusieurs raccourcis au demarrage, avec des contextes differents et un combo pour l'action secondaire.
package fr.tonnom.tonmod.proxy;
import fr.eri.eriapi.keys.EriKeys;
import fr.eri.eriapi.keys.KeyCombo;
import fr.eri.eriapi.keys.KeyContext;
import org.lwjgl.input.Keyboard;
public class ClientProxy extends CommonProxy {
@Override
public void init(FMLInitializationEvent event) {
super.init(event);
registerKeybindings();
}
private void registerKeybindings() {
// Capacite 1 — touche V en jeu
EriKeys.create("mymod.ability1")
.key(Keyboard.KEY_V)
.category("My RPG Mod")
.context(KeyContext.IN_GAME)
.onPress(() -> useAbility(1))
.register();
// Capacite 2 — Shift+V en jeu (combo, pas de conflit avec ability1)
EriKeys.create("mymod.ability2")
.combo(KeyCombo.of(Keyboard.KEY_V).shift())
.category("My RPG Mod")
.context(KeyContext.IN_GAME)
.onPress(() -> useAbility(2))
.register();
// Dash — double-tap W (fenetre de 10 ticks = 0.5 seconde)
EriKeys.create("mymod.dash")
.key(Keyboard.KEY_W)
.doubleTap(10)
.category("My RPG Mod")
.context(KeyContext.IN_GAME)
.onPress(() -> dash())
.register();
// Sprint — maintien de R
EriKeys.create("mymod.sprint")
.key(Keyboard.KEY_R)
.category("My RPG Mod")
.context(KeyContext.IN_GAME)
.onHold(() -> sprint())
.onRelease(() -> stopSprint())
.register();
// Ouvrir le panneau de statistiques — toujours actif (en jeu ou GUI)
EriKeys.create("mymod.stats_panel")
.combo(KeyCombo.of(Keyboard.KEY_P).ctrl())
.category("My RPG Mod")
.context(KeyContext.ALWAYS)
.onPress(() -> toggleStatsPanel())
.register();
}
private void useAbility(int slot) { /* ... */ }
private void dash() { /* ... */ }
private void sprint() { /* ... */ }
private void stopSprint() { /* ... */ }
private void toggleStatsPanel() { /* ... */ }
}
Resultat
Enregistre tous tes keybindings dans une methode dediee appelee depuis
ClientProxy.init(). Cela garde ton code organise et facilite
la maintenance quand ton mod grandit.