BetterController is a client-side Fabric mod for premium controller support in Minecraft.
- Minecraft:
1.21.11 - Java:
21 - Fabric Loader:
0.18.4 - Fabric API:
0.141.3+1.21.11
- Automatic controller connect/disconnect detection.
- Controller type detection (
xbox,playstation,switch,generic) with auto-layout switching. - Low-latency input pipeline:
ControllerPoller -> ControllerSnapshot -> InputTranslator -> GameplayInputFrame -> MinecraftInputApplier
- Full JSON action rebinding for gameplay + hotbar + menu navigation.
- Configurable deadzones, trigger threshold, look sensitivity, response curve, and camera smoothing.
- GUI controller navigation modules:
GuiNavigationControllerGuiFocusElementGuiInputRouter
- Radial quick menu modules:
RadialMenuRadialMenuSlotRadialMenuControllerRadialMenuRenderer
- Bedrock-inspired compact HUD hints near the hotbar (less intrusive).
- In-game settings shortcut (
Controller Settings) in:Options -> Controls- pause menu
- options menu
- Settings screen includes:
- HUD on/off toggle
- deadzone/sensitivity/trigger sliders
- look curve + smoothing controls
- one-click ultra-fluid tuning preset
- Controller inventory/handled-screen navigation:
- directional slot navigation
- confirm to pick/place stack
- Debug overlay (toggle with
F8). - Haptics architecture (
ControllerHaptics,HapticEvent,HapticProfile) with graceful no-op fallback on unsupported backends. - Chat binding support with optional Windows OSK launch.
Implemented and usable now:
- Controller gameplay input (movement, look, actions, hotbar, remapping).
- Controller GUI navigation for common screens and handled inventories (inventory/chests-style screens).
- JSON config + auto-reload + per-layout overrides.
- In-game controller settings screen.
- Optional HUD hints + debug overlay + radial menu.
Current limitations:
- Haptics/vibration is currently a graceful no-op in the GLFW backend (architecture is ready, runtime rumble is not active yet).
- Virtual keyboard launcher currently targets Windows
oskonly and can fail on systems requiring elevation. - GUI navigation works, but edge-case polish across every modded/custom screen is still ongoing.
- Runtime config path:
config/bettercontroller.json(auto-created on first launch) - Bundled template:
src/main/resources/bettercontroller.default.json - Example config:
examples/bettercontroller.example.json - Config reload is automatic when the file is saved.
activeLayoutcontrollerTypeLayoutsmovementDeadzonelookDeadzonelookSensitivityXlookSensitivityYlookSpeedMultiplierlookResponseCurve(linear,exponential_light,exponential_strong)cameraSmoothingcameraSmoothingStrengthtriggerThresholdmenuAxisThresholdmenuInitialRepeatDelayMsmenuRepeatIntervalMshudHintsEnableddebugOverlayEnabledradialMenuEnabledradialMenuSlotsvibrationEnabledvibrationIntensity(off,low,medium,strong)virtualKeyboardEnabled
- Global bindings:
bindings.<action>supports one or many inputs (["A"],["RT", "RB"], etc.)
- Per-layout override:
layouts.<layout>.bindings.<action>
- Axes:
- Global:
axes.move_x,axes.move_y,axes.look_x,axes.look_y - Per-layout:
layouts.<layout>.axes.<axis>
- Global:
- Axis inversion:
- prefix token with
-(example:"-RIGHT_Y").
- prefix token with
movementDeadzone: start around0.12to0.16lookDeadzone: start around0.04to0.08lookSensitivityX/lookSensitivityY: increase together for faster cameralookSpeedMultiplier: increase for faster turning with sticklookResponseCurve:linearfor direct aim,exponential_lightfor softer center controltriggerThreshold: lower to0.35to0.45if triggers feel slow to reactmenuInitialRepeatDelayMs/menuRepeatIntervalMs: lower values for faster menu navigation- Or use the in-game
Apply Ultra Fluid Presetbutton from BetterController settings.
Requires JDK 21 (java -version).
Windows:
- if needed, set Java 21 for the current terminal:
$env:JAVA_HOME="C:\Path\To\jdk-21"$env:PATH="$env:JAVA_HOME\bin;$env:PATH"
.\gradlew.bat build.\gradlew.bat runClient
Linux/macOS:
./gradlew build./gradlew runClient
Build output:
build/libs/
If you are a creator/testing release builds, check these values first:
gradle.properties -> mod_version: release/version tag shown in the mod metadatagradle.properties -> archives_base_name: output jar namegradle.properties -> org.gradle.jvmargs: increase memory for heavier local builds (example:-Xmx2G)
Recommended in-game config profile for recording/review sessions (run/config/bettercontroller.json):
hudHintsEnabled: false(clean HUD footage)debugOverlayEnabled: falselookSpeedMultiplier: 2.4to3.0(faster camera feel)menuInitialRepeatDelayMs: 90to120menuRepeatIntervalMs: 30to45
Quick release check:
- Update
mod_versioningradle.properties. - Run
.\gradlew.bat build. - Verify jar under
build/libs/.