Keybind Library
This page describes functions for registering and managing custom keybinds in the Lilia framework.
Overview
The keybind library runs client-side and stores user-defined key bindings in lia.keybind.stored
. Bindings are saved to data/lilia/keybinds/<gamemode>/<server-ip>.json
(using the server IP with dots replaced by underscores) and loaded automatically on start.
Keybinds are triggered through PlayerButtonDown
and PlayerButtonUp
hooks, and a "Keybinds" page is added to the configuration menu via PopulateConfigurationButtons
. Editing in this menu can be disabled with the AllowKeybindEditing
configuration option.
Each entry in lia.keybind.stored
contains:
default
(number) – key code assigned on registrationvalue
(number) – current key code (initially the default)callback
(function | nil) – invoked when the key is pressedrelease
(function | nil) – invoked when the key is releasedshouldRun
(function | nil) – optional validation function that must return true for the keybind to executeserverOnly
(boolean | nil) – if true, the callback runs server-side via networking
The library also maintains reverse mappings from key codes to action identifiers for efficient lookup.
Functions
lia.keybind.add
Purpose
Register a keybind action with callbacks and optional validation. The default key is stored and a reverse mapping from key code to action is created.
Parameters
k
(string | number): Key identifier. A string is matched case-insensitively against the internal key map. Invalid keys abort registration.d
(string): Action identifier (will be localized usingL()
function).cb
(table): Callback table containing:onPress
(function): Called when the key is pressed. Receives the player as its only argument.onRelease
(function | nil): Called when the key is released. Receives the player as its only argument. Optional.shouldRun
(function | nil): Validation function that must return true for the keybind to execute. Optional.serverOnly
(boolean | nil): If true, the callback runs server-side via networking. Optional.
Realm
Client
Returns
- nil: This function does not return a value.
Example Usage
-- Bind F1 to open the inventory while held
local inv
lia.keybind.add(KEY_F1, "Open Inventory", {
shouldRun = function(client)
-- Check if player can perform this action
return client:IsValid() and not client:IsDead()
end,
onPress = function(client)
inv = vgui.Create("liaMenu")
inv:setActiveTab("inv")
end,
onRelease = function(client)
if IsValid(inv) then
inv:Close()
end
end
})
-- Simple keybind with only onPress
lia.keybind.add(KEY_F2, "Simple Action", {
onPress = function(client)
client:ChatPrint("F2 pressed!")
end
})
-- Server-side keybind
lia.keybind.add(KEY_F3, "Server Action", {
shouldRun = function(client)
return client:IsValid() and client:hasPermission("admin")
end,
onPress = function(client)
client:addMoney(100)
end,
serverOnly = true
})
lia.keybind.get
Purpose
Fetch the key code for a keybind action. It checks the current value, then the registered default, and finally the caller-supplied fallback.
Parameters
a
(string): Action identifier.df
(number | nil): Fallback key code if the action is unknown. Optional.
Realm
Client
Returns
- number | nil: Key code associated with the action or the fallback.
Example Usage
local invKey = lia.keybind.get("openInventory", KEY_I)
print("Inventory key:", input.GetKeyName(invKey or KEY_NONE))
lia.keybind.save
Purpose
Persist all current keybinds to data/lilia/keybinds/<gamemode>/<server-ip>.json
. Only entries with a value
field are written.
Parameters
- None
Realm
Client
Returns
- nil: This function does not return a value.
Example Usage
lia.keybind.load
Purpose
Load keybinds from disk. If no keybind file exists, defaults registered via lia.keybind.add
are applied and saved. After loading, numeric indexes are cleared, reverse lookup mappings are rebuilt, and the InitializedKeybinds
hook fires.
Parameters
- None
Realm
Client
Returns
- nil: This function does not return a value.
Example Usage
hook.Add("InitializedKeybinds", "NotifyKeybinds", function()
chat.AddText("Keybinds loaded")
end)
-- Reload keybinds
lia.keybind.load()
Key Mapping
The library provides a comprehensive mapping of key names to key codes, including:
- Alphanumeric keys:
a
,b
,c
, etc. - Function keys:
f1
,f2
,f3
, etc. - Special keys:
space
,enter
,tab
,escape
, etc. - Arrow keys:
up
,down
,left
,right
- Modifier keys:
lshift
,rshift
,lctrl
,rctrl
,lalt
,ralt
- Numpad keys:
kp_0
,kp_1
,kp_plus
,kp_minus
, etc.
Keys can be specified either as strings (e.g., "f1"
) or as constants (e.g., KEY_F1
).
Server-Side Execution
When serverOnly
is set to true in a keybind callback, the action is executed server-side via networking:
- The client sends a
liaKeybindServer
net message with the action name and player entity - The server receives the message and executes the callback function
- The same process occurs for release actions with
_release
suffix
The server-side execution includes improved error handling with pcall
to prevent crashes from invalid callbacks.
This allows server-side validation and execution while maintaining the responsive feel of client-side keybinds.
Configuration Menu
The keybind system automatically adds a "Keybinds" page to the configuration menu (PopulateConfigurationButtons
hook). This page provides:
- A searchable list of all registered keybinds
- Dropdown menus to change key assignments
- Unbind buttons to remove key assignments
- A reset button to restore all default keybinds
- Automatic conflict detection (prevents multiple actions on the same key)
The editing functionality can be disabled by setting lia.config.get("AllowKeybindEditing", false)
.
Default Keybinds
The library registers several default keybinds:
openInventory
- Opens the F1 menu with inventory tab active (initially unbound)adminMode
- Switches to/from staff character mode (server-side only, initially unbound)quickTakeItem
- Quickly takes items from the ground (server-side only, initially unbound)interactionMenu
- Opens the player interaction menu (bound to TAB by default)personalActions
- Opens the personal actions menu (bound to G by default)
These default keybinds are initially unbound (KEY_NONE
) and must be assigned by the user, except for the interaction menu keybinds which have default assignments.
Hooks
InitializedKeybinds
- Fired after keybinds are loaded and initialized
File Storage
Keybinds are stored in JSON format at:
Where <server-ip>
has dots replaced with underscores (e.g., 192_168_1_1.json
).
Implementation Details
Data Structure
The library uses a dual-indexing system: - Action names as keys pointing to data tables - Key codes as keys pointing to action names for reverse lookup
Validation
The shouldRun
function is called before executing any keybind callback, allowing for conditional execution based on player state, permissions, or other game logic.
Error Handling
Server-side keybinds use pcall
to prevent crashes from invalid callbacks, with error messages printed to the console.
Performance
The library rebuilds reverse lookup mappings after loading to ensure efficient key-to-action resolution during gameplay.