Lua Chat Commands

Register custom chat commands in Lua, optionally restricted to operators or overriding built-in commands.

Mods can register custom chat commands (e.g. /ping, /heal) using Lua. Commands can be restricted to operators only, or open to all players. Mods can also override built-in commands by registering a command with the same name.

See lua-modding-overview.md for a general introduction to Lua modding.


Quick Example

commands-config.yaml (in your mod root):

commands:
  - name: "ping"
    permission: "everyone"
    scripts:
      server-on-command: /commands/ping.lua

commands/ping.lua:

return function(executor, args)
    executor:send_message("Pong!")
end

Register this file in your mod’s root YAML:

commands-config: commands-config.yaml

commands-config.yaml Field Reference

commands:
  - name: "my_command"       # Required. The command name (no leading slash, lowercase).
    permission: "everyone"   # Required. Exactly "everyone" or "operator", lowercase.
    scripts:
      server-on-command: /commands/my_command.lua  # Required. Path to a Lua file that returns its handler, relative to your mod root.

All three fields are required, and every entry is validated when your mod loads. A missing field, an unrecognised permission value, or a misspelled key causes that command to be rejected with an error in the server log naming the problem — it is never silently given a default. This is deliberate: a typo like permission: "opperator" must not quietly leave an operator command open to every player.

Multiple commands can be declared in the same file:

commands:
  - name: "ping"
    permission: "everyone"
    scripts:
      server-on-command: /commands/ping.lua

  - name: "heal"
    permission: "operator"
    scripts:
      server-on-command: /commands/heal.lua

Lua Function Signature

Every command function receives two arguments:

return function(executor, args)
    -- executor: the player who typed the command
    -- args: a Lua table of string arguments (1-indexed), excluding the command name itself
end

Example/greet Alice Hello there:

  • args[1] is "Alice"
  • args[2] is "Hello"
  • args[3] is "there"

Replying to the Executor

Use executor:send_message(text) to send a private reply visible only to the player who typed the command:

return function(executor, args)
    executor:send_message("Pong!")
end

To send a message visible to all players, use the global broadcast_server_message:

return function(executor, args)
    broadcast_server_message("Something happened!")
end

Executor Methods

The executor object is a full server entity object — see lua-server-entity.md for everything available on it. Frequently used in commands:

MethodDescription
executor:send_message(text)Private reply — only the executor sees it
executor:get_location()Location object with .x, .y, .world fields
executor:get_health()Current health
executor:get_max_health()Max health
executor:heal(amount)Restore health, capped at max
executor:set_display_name(name)Change the executor’s displayed name

Permission Levels

ValueWho can run the command
"everyone"Any connected player
"operator"Only players listed under operators: in server_config.yaml

These are the only two accepted values, and they must be written exactly as shown, in lowercase. Anything else is a load-time error rather than a fallback to "everyone". In singleplayer the local player is always treated as an operator.

To designate operators, edit server_config/server_config.yaml:

operators:
  - "Alice"
  - "Bob"

The value must match the player’s login ID (the name used to create their save file) exactly — not their display name.


Overriding Built-in Commands

Register a command with the same name as a built-in to replace it:

commands:
  - name: "list"             # Overrides the built-in /list
    permission: "everyone"
    scripts:
      server-on-command: /commands/list.lua

Built-in commands (always available unless overridden):

CommandPermissionWhat it does
/helpEveryoneLists all available commands (built-ins and mod-registered)
/listEveryoneShows who is currently online
/me <text>EveryoneBroadcasts * Name text to all players
/r <message>EveryoneReplies to the last player who whispered you
/whisper <player> <msg> (alias /w)EveryonePrivate message between two players
/mute <player>OperatorSilences a player’s chat messages for all players on the server. The muted player is notified privately. The mute lasts until the server restarts or the player is unmuted.
/unmute <player>OperatorRemoves a mute from a player. Accepts the player’s login ID, so it works even if the player is currently offline.
/noclip [player]OperatorToggles no-clip movement for yourself, or for the named player. The affected player sees the new state in chat.
/kick <player> [reason]OperatorDisconnects a player, showing them the reason if one is given. They may reconnect immediately.
/ban <player> [reason]OperatorAdds a player to the ban list, saves it to disk, and kicks them if they are online. Accepts a login ID, so offline players can be banned.
/unban <player>OperatorRemoves a player from the ban list. Accepts a login ID, so it works while the player is offline.
/pvp <on|off>OperatorEnables or disables player-vs-player damage for the whole server, and announces the change in chat.
/teleport (alias /tp)OperatorMoves players around. Takes <x> <y>, <player>, <player> here, <playerA> <playerB>, or <player> <x> <y>. The target’s world is never changed.

Full Example — /heal Operator Command

commands-config.yaml:

commands:
  - name: "heal"
    permission: "operator"
    scripts:
      server-on-command: /commands/heal.lua

commands/heal.lua:

return function(executor, args)
    local amount = tonumber(args[1]) or 20
    executor:heal(amount)
    executor:send_message("Healed for " .. amount .. " HP.")
end

Usage in game: /heal 50


Client-Only Commands

The following commands are processed entirely by the game client. They are not sent to the server and cannot be overridden or intercepted by mods.

CommandWhat it does
/ignore <player>Hides all future chat messages from that player in your own chat window. The player is not notified and can still see your messages. Your ignore list is saved and persists across sessions.
/unignore <player>Removes a player from your ignore list so their messages appear again.

The ignore list is stored locally on your machine. Each server you connect to maintains a separate ignore list.