Open the controls screen in a big Fabric pack and count the red conflict markers. Those are not cosmetic: Minecraft keeps exactly one keybind per physical key internally, so whichever binding registered or was rebound last silently wins the key, and every other binding sharing it goes dead.
Polybind removes that limit. Every action on a shared key works again, and you decide, key by key, how the key behaves when it's pressed.
/polybind, Mod Menu,
and an optional unbound keybind.The wheel is a radial chooser: one segment per action on the key, up to eight per page, drawn over a backdrop that dims the world rather than hiding it.
wheel.holdThresholdMs, 180 ms)
opens the wheel again, with your last pick already highlighted, so re-choosing is one click away.Esc or right click cancels; scroll to page through more than eight actions; number keys 1-8
pick directly.This tap/hold rhythm is the headline interaction: once you've set up your picks, a wheel key behaves almost like a single dedicated keybind for the action you use most, while still being one hold away from switching to something else on the same key.
| Mode | What happens on a press | Good for |
|---|---|---|
| Wheel | First press (or a hold past ~0.2s) opens a radial chooser; a quick tap repeats your last pick. Only the chosen action fires. | The shipped default for shared keys — lets you pick per key without losing anything. |
| All fire | Every action on the key fires, once each. | Hold-type actions (movement, sneak, sprint, attack/use, zoom, push-to-talk) — the shipped default for those, automatically. |
| Vanilla | Polybind stays out of it entirely; the game picks its usual single winner. | Keys you'd rather manage yourself, or debugging. |
A key with no explicit mode of its own simply follows the global default, whatever you later change that to.
Open it from the "Polybind…" button in the game's own Key Binds (or Controls) screen —
top right corner, carrying the number of keys that currently carry more than one action — or from
/polybind, the optional "Open Polybind" keybind, or Mod Menu's config button.
Every change applies immediately and is written to disk as it's made — there's no "apply" button to forget, and nothing needs a restart.
Ship the settings your pack should start with. Players get them on a fresh install, keep every change they make afterward, and still receive your later changes to anything they never touched.
Quick start:
/polybind, go to the Pack defaults tab, press Save everything (or run
/polybind defaults save all).config/polybind/defaults/defaults.json and, if you want them, set defaultDifficulty for
new worlds and list any further config files under extraFiles (a path or a glob, relative to
the game folder — e.g. "config/sodium-options.json" or "config/mymod/**").config/polybind/ with your pack. Do not ship polybind/journal.json — it lives
outside config/ for exactly that reason, so a normal export of config/ won't pick it up.The update rule:
| Situation | What happens |
|---|---|
| Fresh install | The player gets everything the pack ships. |
| Existing install, Polybind has never run here before | Nothing changes on the first run, whatever the pack says. |
| Pack update, to a setting the player never touched | The player gets the new value. |
| Pack update, to a setting the player changed themselves | The player keeps their own value, for good. |
Deleted servers never come back on an update, and shipped keybinds become the controls screen's Reset default.
File layout, shipped by the pack:
config/polybind/defaults/
options.txt vanilla option lines, no key_ lines
keybinds.txt key_<binding>:<key> lines, exactly as vanilla writes them
servers.dat optional, vanilla format
defaults.json the author's settings (defaultDifficulty, extraFiles, ignoredOptions, ...)
extra/ a mirror of the game folder, e.g. extra/config/sodium-options.json
Owned by the player and never shipped: <game folder>/polybind/journal.json,
<game folder>/polybind/wheel.json, and config/polybind.json itself.
What not to ship: anything machine- or person-specific. By default that's fullscreen
resolution, sound device, last server joined, language, window size overrides, the "joined a server
before" flag, the telemetry opt-in, dismissed warning dialogs, tutorial progress and GL debug
verbosity — the full, editable list is ignoredOptions in defaults.json.
Commands:
| Command | What it does |
|---|---|
/polybind, /polybind open |
Opens the screen on the Shared keys tab. |
/polybind reload |
Re-reads config/polybind.json. |
/polybind conflicts |
Lists every shared key in chat, ending with a clickable "[Open Polybind]". |
/polybind defaults |
Opens the screen on the Pack defaults tab. |
/polybind defaults save <all\|options\|keybinds\|servers\|extra> |
The same as the tab's four save buttons. |
/polybind defaults status |
What's shipped, where, and whether this install has a journal. |
/polybind defaults apply |
Applies extra files now and reports what options would change on the next start. |
All commands are client-only — none of them reach a server.
config/polybind.json is written with sensible defaults the first time you run the game, and an
older file is upgraded in place without losing anything you set:
{
"enabled": true,
"excludedBindings": [],
"logConflictsOnStartup": true,
"debug": false,
"defaultMode": "WHEEL",
"keyModes": {},
"holdBindings": [
"justzoom.keybinds.keybind.zoom",
"key.accessorify.open_widget",
"key.accessorify.use_spyglass",
"key.attack",
"key.back",
"key.deeperdarker.boost",
"key.deeperdarker.transmit",
"key.forward",
"key.jump",
"key.left",
"key.push_to_talk",
"key.right",
"key.sneak",
"key.sprint",
"key.use",
"key.whisper"
],
"wheel": {
"activation": "HOLD_RELEASE",
"holdThresholdMs": 180,
"showCategory": true,
"rememberLastChoice": true,
"tapRepeatsLast": true,
"scale": 1.0
},
"packDefaults": {
"enabled": true,
"applyUpdates": true
}
}
enabled — master switch; false leaves vanilla behaviour completely untouched.excludedBindings — keybind translation keys (e.g. "key.ponder.ponder") Polybind never
touches at all.logConflictsOnStartup — logs every shared key once at startup; the quickest way to find a
translation key for the lists above.debug — logs every binding Polybind feeds. Noisy; for diagnosing one specific keybind.defaultMode — WHEEL out of the box. The mode every key follows unless it has its own entry
in keyModes, or carries a binding named in holdBindings (see below).keyModes — per-key overrides, keyed on the name InputConstants.Key#getName() uses, e.g.
{"key.keyboard.v": "WHEEL"}. Always wins, hold safeguard included. A key set to the mode it
would have followed anyway is left out automatically.holdBindings — translation keys of actions whose whole meaning is "while I am holding this"
(walking, jumping, sneaking, sprinting, attack/use, and a handful of hold-type actions from other
mods, shipped so the setting works out of the box rather than only after you discover it). A key
carrying one of these does not follow a WHEEL default; it falls back to All fire unless you
set that key's mode yourself. An excluded binding does not count, since Polybind never fires it.
[] switches the safeguard off entirely; leave the field out of a hand-written file to get the
shipped list above.wheel.activation — HOLD_RELEASE (default) or CLICK.wheel.holdThresholdMs — the line between a tap (repeats your last pick) and a hold (opens
the wheel), in milliseconds. Default 180, clamped 0-2000.wheel.showCategory — show each action's category under its name in the wheel.wheel.rememberLastChoice — remember the action picked last time on each key, across
restarts, and pre-highlight it.wheel.tapRepeatsLast — a tap on a key with a remembered pick repeats it instead of opening
the wheel. Needs rememberLastChoice.wheel.scale — ring size multiplier, 1.0 default, clamped 0.5-2.0 (shrinks further to fit a
small window).packDefaults.enabled — master switch for the pack defaults feature.packDefaults.applyUpdates — false keeps the first run's values and stops every later push;
a value is only ever written when the player's file has no entry for it yet.Bad values fall back to their default with one warning in the log, numbers out of range are clamped, and a file that isn't valid JSON is left on disk untouched while defaults are used for the session.
Polybind was written and checked against a large 1.21.1 modpack, and every mod in it that hooks Minecraft's keybind handling was reviewed before a line of the mixin was written.
config/defaultoptions folder is imported automatically on first run if present, with
nothing changed on the player's own settings.Does the server need this mod? No. Polybind is entirely client-side. Installing it on a server does nothing, and a client running it joins a vanilla or modded server exactly as it would without it.
Will a pack update overwrite my settings? No. Polybind remembers the value it last applied for every setting. A value you changed stays yours for good; a value you never touched follows the pack's later updates. See the update-rule table above.
Why does pressing W not open a wheel?
WHEEL is the shipped default, but a key you haven't set yourself that carries a hold action —
walking, jumping, sneaking, sprinting, attack/use, and a few others listed in holdBindings — stays
on All fire instead, because a wheel can't keep a key held down for you. On the Shared keys tab
that key's Mode button shows the tooltip "Kept on All fire because [action] is a hold action. Click
to override." — one click sets that key's mode yourself and it stops following the safeguard.
I put push-to-talk or a zoom keybind on a shared key — what happens?
Leave that key on All fire (or add its translation key to holdBindings, or move it to a key of
its own). The wheel gives the action it fires one press and one release; anything that needs the key
held — zoom, push-to-talk, a charge-up — won't work correctly through it.
How do I turn Polybind off for just one key? Open the Shared keys tab and set that key's Mode to Vanilla. To leave just one specific action alone while still managing the rest of the key, clear its Included tick instead.
Does it work with mouse buttons? Yes. Keyboard and mouse buttons go through the same handling and get the same modes, wheel included.
Can I use just the keybind fix, without the wheel or the pack defaults?
Yes. Set defaultMode to ALL (or set individual keys to All fire from the screen) to keep every
shared binding firing without ever seeing a wheel. The pack defaults feature is independent and can
be turned off entirely with packDefaults.enabled: false.
Can I use just the pack defaults, without the shared-key handling?
Yes. Set defaultMode to VANILLA (and clear keyModes) to hand every key back to vanilla's
single-winner behaviour while keeping packDefaults.enabled: true.
How do I reset things back to defaults?
For the shared-key settings, keep clicking a key's Mode button — once it lands back on whatever the
global default is, Polybind stops storing an override for that key automatically. To reset
everything at once, close the game and delete config/polybind.json; it's regenerated with the
defaults on the next launch. For keybinds themselves, vanilla's own Reset button on the Key
Binds screen applies — it resets to the pack's shipped keys if pack defaults set them, or to each
mod's own default otherwise.
Esc instead of closing on
its own. Nothing is stuck — letting go of the key (once focus returns) closes it normally.