EZ Bind — Customizable Keybind Manager

Need a flexible and persistent keybind system for your Roblox game? EZ Bind makes handling custom keybinds effortless with a clean API and built-in support for multiple devices.


EZ Bind – Drop-in Keybinding System for Luau

TL;DR: Plug in the module, register actions, call Load() once, and you’ve got fully-customizable, cross-device keybinds that persist between sessions.


Features

  • Fully customizable keybinds at runtime
  • Overwrite protection (auto-unbinds old key if reused)
  • Key combinations (bind multiple keys to one action)
  • Device-aware (Keyboard/Mouse and Gamepad supported)
  • Persistent save system with throttled DataStore + cache

File Structure


Getting Started


1. Server Setup

require(game.ReplicatedStorage.Modules.Keybinds.Data).Init()

2. Client Setup

require(game.ReplicatedStorage.Modules.Keybinds.ActionRegistry)
require(ReplicatedStorage.Modules.Keybinds.Client).Init()

3. Action Setup

local Keybinds = require(ReplicatedStorage.Modules.Keybinds)
local Sprint = require(script.Actions.Sprint)

Sprint.Init()

Keybinds.Register(
    "Sprint", -- Name
    Sprint.DefaultKey, -- Keyboard
    Sprint.DefaultGamepad, -- Gamepad
    Sprint.Action, -- Callback
    { doubleTap = true,
      tapWindow = 1 }  -- Optional
)

API

Method Description
Register(name, kb, gp?, callback, opts?) Registers a new action with optional gamepad input and settings.
SetInput(name, inputList?) Assigns one or more inputs to the action. Pass nil to unbind.
SetKey(name, Enum.KeyCode?) Shortcut for SetInput with a single KeyCode.
GetInput(name): {Input}? Returns the current inputs for the given action (based on active input scheme).
GetKey(name): Enum.KeyCode? Returns the first key assigned to the action in the active scheme, or nil if unbound.
Load(dataTable) Loads keybinds from a saved data table (typically from the server).

Events

  • Keybinds.Overwritten:Connect(function(old, new) end)
  • Keybinds.SchemeChanged:Connect(function(scheme) end)

Example Action Module

type Input = Enum.KeyCode | Enum.UserInputType

local PrintAction = {} :: {
    DefaultKey: Input,
    DefaultGamepad: Input,
    Action: (string, Enum.UserInputState, InputObject) -> (),
}

PrintAction.DefaultKey = Enum.KeyCode.P
PrintAction.DefaultGamepad = Enum.KeyCode.ButtonY
PrintAction.DefaultKeyCombo = {Enum.KeyCode.Q, Enum.KeyCode.E}
PrintAction.DefaultGamepadCombo = {Enum.KeyCode.ButtonX, Enum.KeyCode.ButtonY}

local function onPress()
    print("Key was pressed!")
end

function PrintAction.Action(_name, state, _io)
    if state == Enum.UserInputState.Begin then
        onPress()
    end
end

return PrintAction

Save System Notes

  • Uses DataStoreService + server cache
  • Save is debounced (0.4s) and throttled (6s)
  • On shutdown, remaining cache is flushed
  • Empty or bad data is ignored gracefully

License

MIT – use it in any personal or commercial project.


Feedback

Found a bug or want to suggest something? Reply below.


Download

Links

EZ Bind [Creator Store]

8 Likes

What I want to add next:

  • Images for the keybinds (also an option to keep the textlabel if thats what you fancy)

If anyone has ideas of what I can add next/fix leave comments please.

Any feedback is appreciated, if you could leave videos or comments what your using this for that would be dope to see.