Mod Compatibility
Control Flex is built for mid-to-large modpacks: zero configuration by default, escalating only when a mod's input refuses to behave. This page maps out what each of the five tools can do, when to climb to the next one, and where the result ends up.
1. The escalation ladder
From zero cost to writing code — a ladder you only climb when the rung below does not work. Each step down is more precise, and more expensive to maintain.
| Tool | What you need | What it covers | Where the result lives | Cost |
|---|---|---|---|---|
| Auto-discovery | Nothing | Mods that register their keys through KeyMapping | None (registered at runtime) | Zero |
| In-game mod adaptation | A controller and a few minutes | Key layering, plus stick and cursor behavior for screens and overlays | compat/user/<mod_id>.json |
Low |
| Compat configs | A network connection, or a ready-made file | The shareable form of the two rungs above, plus dispatch channels, key suppression and tips | compat/{default,mods,user}/ |
Low |
| Hand-written compat JSON | A text editor and the field reference | Fine-grained rules: per-key channels, item suppression, phase persistence, per-screen stick parameters | compat/user/<mod_id>.json |
Medium |
| Bridge mod | Java + Gradle | Input systems that bypass KeyMapping, runtime state, custom-drawn UIs | Separate JAR + compat/mods/*.json |
High |
Most modpacks stop at rungs 1–3. Only a handful of mods genuinely need a bridge — usually the ones that ship their own input system: EMI, Create's train console, Immersive Vehicles, Epic Fight.
2. When to climb a rung
- First check Key Mapping for it — if the key is there, it is a standard KeyMapping mod and rungs 2 / 3 will do.
- The key exists but nothing happens in a screen — usually the wrong phase or the wrong dispatch path: add a screen / overlay rule on rung 2, then change the channel on rung 3.
- Nothing on press, or the action fires twice — the dispatch channel is wrong (eventBus and keyMapping both firing). Pin it down on rung 4.
- The key never shows up at all — the mod keeps bindings in its own config, polls raw key state, or reads the gamepad directly. Only rung 5 can reach it.
- The mod has runtime state such as a battle mode — the bridge pushes the state (
IPlayerStateRegistry) and JSON consumes it throughitemSuppressKeys'playerStatecondition.
3. One data model underneath all five
Whichever rung you use, what lands on disk is the same compat JSON. The core is three key sections plus one dispatch concept:
| Section | Active when | Typical use |
|---|---|---|
inGameKeys |
No screen, no overlay | Combat keys, skill keys, transformation keys |
screenKeys |
A screen (GUI) is open | Inventory, crafting, recipe lookup |
overlayKeys |
An overlay is open (wheels or circles drawn over the HUD) | Spell wheels, radial menus, photo HUDs |
How a press reaches the mod is decided by the dispatch channel: keyMapping, eventBus, glfwPoll, screenInput, virtualKbm. Different keys in the same file can use different channels — which is also the fix for double-firing keys.
4. Where the result lives: three layers
Compat configs load from three layers, priority user > mods > default; the same mod_id is replaced wholesale, never merged field by field. Which layer to edit — and what can overwrite it — is covered in Editing configs by hand.
5. Where to go next
Compat JSON
Where files go, every field explained, how to contribute a config, how to run your own source.
Read the field reference →
Bridge mods
How to adapt in Java when JSON is not enough — and where the official implementations live.
See the bridge approach →
Editing configs by hand
Editing files directly, copy-on-write, common traps, and how to roll back.
Start editing →
In-game adaptation
The adaptation center itself: layering keys, screen / overlay rules, applying community configs.
See the UI walkthrough →
Still misbehaving? Check in this order
- Look at Key Mapping — is the action on the right layer (Main / Screen / Overlay)?
- Open Mod Adaptation for that mod — add a screen / overlay rule, or apply a community config.
- If the mod only listens for physical keys, bind it through Virtual KBM.
- Search the log for
[ModCompat]to see whether the config loaded at all, and which gate stopped it.