Engineering
Commands and rebindable keys in FiveM
Create chat commands with RegisterCommand, restrict them with ACE permissions, add chat suggestions, and bind them to keys players can change in the settings with RegisterKeyMapping — plus +/- commands for hold-to-use keys.
Overview
Commands are the simplest way to trigger code in FiveM, and key mapping turns any command into a key the player can rebind in their own settings. Together they replace the old pattern of checking hard-coded keys every frame — which costs performance and annoys every player who uses a different keyboard layout.
RegisterCommand
RegisterCommand('me', function(source, args, raw)
local text = table.concat(args, ' ')
if text == '' then return end
TriggerServerEvent('rp:me', text)
end, false)| Handler argument | Contains |
|---|---|
source | On the server, the player’s ID (0 for the server console). On the client, always 0. |
args | The words after the command, as a table of strings. |
raw | The full command line exactly as typed. |
Client commands run in the typing player’s game; server commands run on the server and can be typed by players in chat or by you in the server console.
Restricting server commands with ACE
RegisterCommand('announce', function(source, args)
local msg = table.concat(args, ' ')
TriggerClientEvent('chat:addMessage', -1, { args = { 'ANNOUNCEMENT', msg } })
end, true) -- restrictedadd_ace group.admin command.announce allow
add_principal identifier.fivem:1234567 group.adminWith restricted = true, only players with the ACE command.announce can run it. You can also check permissions yourself with IsPlayerAceAllowed(source, 'command.announce'), which is how you restrict actions that are not commands.
Chat suggestions
The default chat shows suggestions while typing when you register them:
TriggerEvent('chat:addSuggestion', '/me', 'Describe an action', {
{ name = 'action', help = 'What your character does' },
})RegisterKeyMapping: keys players can change
RegisterCommand('inventory', function()
-- open your inventory UI
end, false)
RegisterKeyMapping('inventory', 'Open inventory', 'keyboard', 'TAB')- The mapping appears in Settings → Key Bindings → FiveM, with your description.
- The fourth argument is the default key. Once a player has seen the mapping, their saved binding wins — changing the default later does not move existing players.
- Input sources include
keyboard,mouse_buttonandpad_digitalbutton. - No per-frame key checking is needed; the game calls your command when the key is pressed.
Hold-to-use keys with + and − commands
A mapped command whose name starts with + runs on key press, and the matching - command runs on release. This is how push-to-talk style actions work.
local pointing = false
RegisterCommand('+point', function()
pointing = true
-- start the animation
end, false)
RegisterCommand('-point', function()
pointing = false
-- stop the animation
end, false)
RegisterKeyMapping('+point', 'Point with finger', 'keyboard', 'B')Frequently asked questions
How do I make a command in FiveM?
Call RegisterCommand('name', function(source, args, raw) ... end, false) in a client or server script.
How do I make an admin-only command?
Register it on the server with restricted = true and grant the ACE in server.cfg: add_ace group.admin command.name allow.
How do I let players rebind a key?
Use RegisterKeyMapping('command', 'Description', 'keyboard', 'DEFAULTKEY'). It appears under Settings → Key Bindings → FiveM.
I changed the default key but players still have the old one. Why?
The default only applies the first time a player sees the mapping. After that their saved binding is kept.
How do I detect a key being held?
Map a +command for press and a -command for release.
Need this built, not just explained?
Ten years of FiveM work, from Lua to NUI
Custom resources, React NUI, ESX / QBCore / Qbox integration, OneSync performance audits and security reviews — plus the websites and SEO around your server brand.
Related guides
- EngineeringEvents in FiveM: how resources and players talkHandle events with AddEventHandler(name, fn); add RegisterNetEvent(name) (or use RegisterNetEvent(name, fn)) to allow the event to arrive over the network. TriggerEvent fires locally on the same side, TriggerServerEvent sends from a client to the server, and TriggerClientEvent(name, target, ...) sends from the server to one player (target = player ID) or everyone (-1). On the server, source is the sending player.
- Getting startedClient-side vs server-side in FiveMClient scripts run on each player’s PC and handle what that player sees and does: drawing, input, markers, animations and local effects. Server scripts run once, on your server, and own everything that has value or must be trusted: money, items, jobs, the database and permissions. The client asks; the server decides. Never trust data sent by a client without checking it.
- EngineeringWriting server events that cannot be abusedAny client can call any event you registered with RegisterNetEvent, with any arguments. In each handler: copy source into a local, check argument types and ranges, re-derive everything from server state (prices, amounts, rewards), verify the player can do this now (distance, job, item, cooldown), and log refusals. Events only other server scripts should use are registered with AddEventHandler alone, so clients cannot trigger them.
- Getting startedWrite your first FiveM script, step by stepCreate a folder resources/my_first, add an fxmanifest.lua with fx_version 'cerulean', game 'gta5', a client_script and a server_script, then write a client command that loads a model with RequestModel, waits for HasModelLoaded, spawns it with CreateVehicle and seats the player with SetPedIntoVehicle. Add ensure my_first to server.cfg, restart, and type /car adder in game.