Skip to content

Players own every key; servers declare actions, not keys ​

Status: Accepted (2026-10-26)

Context ​

A multiplayer client needs keys of its own (chat, player list, screenshot), the platform offers vehicle shortcuts (engine, lights, entering as a passenger), and game modes need actions of their own (open a shop, use an item). If each of these hard-codes a key, they collide with each other and with the game's controls, and the player cannot fix the collision. If a script may listen to any key, the server can see every key the player presses, which turns it into a keylogger. Game modes still need a way to move or disable platform shortcuts that do not fit them.

Decision ​

Keys are split into four layers. In every layer the player has the final say over which physical key does what.

LayerWho sets the default keyWhat the server can doWhat the player can doMembers
Corethe clientnothing: it cannot move, disable or listen to these keysrebindopen chat (T), player list (Tab), help (F1, reserved), diagnostics (F5), hide the interface (F7), screenshot (F8), disconnect (no default key), server menu (Up, Down, Enter, Backspace), answer an offer (Y, N); the pause menu stays on Esc
Platformthe clientmove the default key or turn the action off, server-widerebindengine (K), lights (L), enter as a passenger (G)
Scriptthe resource that declares the actiondeclare and withdraw actions, each with an optional default keyrebind; the choice is stored per serverthe game mode's own actions
Gamethe game's own controlsonly read them in player sync (the keys bitmask)rebind in the game's own settings screenwalking, firing, aiming, entering a vehicle (F) and the rest of the controls
  • The server hears actions, never keys. A resource declares a named action (dlmp.register_action, ActionDeclare); the client binds it to a key and reports only presses and releases of declared actions (ActionInput, Lua event player_action). The server never learns which key the player chose. Actions do not fire while the chat or dialog input or a menu is open, or while the window is not focused; an action held at that moment is released.
  • Defaults must not collide. The server refuses a script default key that is a core key, a default key of the game's controls, a platform action's stock or current key, or another declared action's default. A modifier chord (Ctrl+, Shift+, Alt+) is not a stock key of anyone and is allowed. If the player has already rebound something to a declared default, the client leaves the action without a key until the player picks one; remaining conflicts are resolved by the player rebinding.
  • Platform keys stay reserved. K, L and G belong to their platform actions even while a server moves an action elsewhere or turns it off (dlmp.set_platform_action_key, PlatformKeys). An action can therefore always return to its stock key, including when the resource that moved it stops, and two defaults never end up on the same key. A turned-off action does not fire even for a player who bound it themselves.
  • Core keys belong to the player. They give the player control over their own client, so no server may occupy them. The server also never hands out F11 (switches the game window) or F12 (the Steam overlay's screenshot).
  • Server menu and offer keys do not capture input. They work only while a server menu or an offer card is open, and the game keeps them too, so a menu never takes control away from the player. The menu uses the arrows and Enter rather than spare keys such as PageUp and Home, which not every keyboard has. The cost: in some vehicles the game uses the arrows for steering, so the player scrolls and steers at once or rebinds. Y and N read as "yes" and "no" on any layout.
  • Tab is the player list. The game's weapon wheel, which uses Tab by default, gets another default key for the session without that choice being saved, unless the player has rebound the wheel themselves.
  • Game settings are kept apart. The client keeps the game's settings, including its controls, in a profile of its own: on first launch it copies the player's single-player settings once, and from then on multiplayer changes never touch the single-player profile.
  • Rebinding happens in the client's pause menu (the Key bindings tab), reached with Esc.

Consequences ​

  • Resources get a stable, conflict-free way to offer actions, and players can always remap them.
  • A resource cannot implement "press any key" logic or read raw key state; it designs around named actions instead.
  • A server that wants engine or lights on a command instead of a key turns the platform action off; the stock key stays reserved and cannot be reused for a script action.
  • Cursor and keyboard input for resource-owned pages are covered by ADR 0049. Gamepads are out of scope.

Alternatives considered ​

  • Scripts bind any key directly. The script picks the key, the player cannot resolve conflicts, and the server can listen to arbitrary keys. Rejected.
  • Only the game's own controls are visible to scripts. Game modes lack actions of their own. Rejected.
  • A fixed core layer the player cannot rebind. Inconvenient for players with other layouts or habits. Rejected.
  • Engine and lights in the core layer. A game mode could not move them to a command or another key. Rejected.

Documentation licensed under CC BY 4.0. DarqlineMP is not affiliated with Rockstar Games or Take-Two Interactive. Grand Theft Auto is a trademark of Take-Two Interactive Software, Inc.