Skip to content
InputBooster
Developer DocumentationInternals

Engine modes

Automatic, event-driven and polled modes, how the mode is resolved, and how the compatibility fallback works.

2 min readInputBooster 4.1.2-alphaMinecraft 26.2 / 26.3

The engine has two input sources and three modes. The mode decides which source is allowed to dispatch an action; the other source still updates state.

The three modes

java
public enum Mode {
    AUTO("auto"),
    EVENT("event"),
    POLL("poll");
}
ModeBehaviour
AUTOEvent hooks when they applied and no known input mod is present, otherwise polling
EVENTEvent hooks only. Falls back to polling when they are unavailable
POLLHigh-rate sampling only. The hooks still update state but never dispatch

The configured value maps to the mode like this:

engine_modeMode
0AUTO
1EVENT
2POLL

Resolving the mode

CompatibilityManager.resolveMode() decides:

java
public InputEngine.Mode resolveMode() {
    InputEngine.Mode configured = InputEngine.Mode.fromConfig(InputBoosterConfig.getEngineMode());
    if (configured == InputEngine.Mode.EVENT && !eventSourceActive) {
        fallbackReason = "event hooks unavailable";
        return InputEngine.Mode.POLL;
    }
    if (configured == InputEngine.Mode.AUTO) {
        if (!detected.isEmpty() && InputBoosterConfig.isCompatFallback()) {
            fallbackReason = "compatibility fallback: " + String.join(", ", detected);
            return InputEngine.Mode.POLL;
        }
        return eventSourceActive ? InputEngine.Mode.EVENT : InputEngine.Mode.POLL;
    }
    return configured;
}

The mode can change at runtime

The mode is re-resolved in two situations:

TriggerWhere
The first event arrivesInputEngine.onKeyState calls resolveMode() again
engine_mode changed in the configThe client tick compares the configured value with the last one
java
public void onKeyState(int code, boolean down) {
    CompatibilityManager compat = InputBoosterMod.compatibilityManager;
    if (compat != null) {
        boolean firstEvent = !compat.eventSourceActive();
        compat.markEventSourceActive();
        if (firstEvent) {
            eventDriven = true;
            setMode(compat.resolveMode());
        }
    }
    state.setRaw(code, down);
    if (mode == Mode.POLL) return;
    ...
}

The compatibility fallback

Some mods own input routing. When one of them is present and compat_fallback is on, the engine keeps polling and leaves event handling alone instead of competing for it.

Detection is a class-path lookup, not a mod-list dependency, so it works the same on Fabric and NeoForge without touching loader APIs:

java
private static final String[][] KNOWN_INPUT_MODS = {
    {"controlify", "dev.isxander.controlify.Controlify"},
    {"midnightcontrols", "dev.lambdaurora.midnightcontrols.MidnightControls"},
    {"controllable", "com.mrcrayfish.controllable.Controllable"},
    {"sodium", "net.caffeinemc.mods.sodium.client.SodiumClientMod"},
    {"iris", "net.irisshaders.iris.Iris"},
    {"zoomify", "com.jab125.zoomify.Zoomify"},
};

The scan runs once during initialisation. A class that cannot be loaded simply means the mod is not installed.

Reading the resolved mode

The Compatibility tab of the settings screen shows the mode and the reason. The overlay shows the mode in its engine line, and the status line is:

java
public String statusLine() {
    return "Input: " + mode.label + (eventDriven ? " (event)" : " (poll)");
}

CompatibilityManager.statusLine() adds the detection result:

text
Engine: poll | sodium

Turning the fallback off

With compat_fallback=false, AUTO no longer downgrades to polling when an input mod is detected. It picks EVENT when the hooks are live.

Forcing a mode

SituationSetting
The hooks are not applying and you want the pollerengine_mode=2
You want to prove the hooks workengine_mode=1 after the first event has fired
You are not sureLeave it on 0

The mode is not part of a profile, so switching profiles does not change it.