Skip to content

Player commands are a packet of their own, handled by resources and answered with server messages ​

Status: Accepted (2026-06-25)

Context ​

Players type commands (/where, /kick 3) in the same input box as chat, and game modes act on them. The server needs a path from "a player typed a command" to "a resource reacted", and a way to answer one player with a line of text that is not player chat. This builds on the reliable event lane and the server facade of ADR 0009.

Decision ​

  • A command travels as ClientCommand, not as chat. When the input starts with /, the client sends the line without the slash as ClientCommand instead of ClientChat. Detecting the slash is only framing: the client does not parse or execute commands itself. The server checks the token and the reliable order as for chat, sanitizes the line, drops an empty one and rate-limits commands per connection. It never relays a command to other players.
  • Resources register command handlers. dlmp.add_command_handler(name, fn, opts) binds a command name to a callback that receives the player and the whitespace-split arguments as strings. Names match case-insensitively unless the handler asks otherwise; handlers run in priority order (high, normal, low, then registration order), across resources. The first handler that returns true consumes the command and stops the dispatch. A handler that fails or times out neither consumes the command nor blocks the handlers after it. A handler is removed with dlmp.remove_command_handler or goes away with its resource.
  • An unconsumed command gets an answer from the core. When no handler consumes it, the player receives Unknown command: /<name>. A bare / is ignored silently.
  • Answers are ServerMessage, not chat. Player:send_message sends one line of text to one player, with up to 16 colored runs. The client shows it in the chat log without a player attribution. Commands that only the server operator may run are console commands (dlmp.add_console_command), not player commands; see ADR 0026.

The player only triggers a command. The server owns its reception and dispatch; the resource that consumes it owns the reaction, expressed through the server facade.

Consequences ​

  • A typo in a command can never leak into public chat, and a chat line can never be mistaken for a command: the two are different packets.
  • Permissions are the handler's business: the core has no notion of an admin or a command ACL.
  • Client-side autocomplete and history are not part of this decision.

Alternatives considered ​

  • Detect the leading / in ClientChat on the server. One packet with two meanings: a branching mistake broadcasts a command as chat.
  • Answer through ChatMessage with a system sender. Mixes server notices with player chat and leaves an overloaded packet that a real server-message primitive would have to split later.

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.