Skip to content

Commands

Commands players type in the chat box, as /mute, or bind to keys themselves, and the actions on the keys. A module declares each command at its top with its arguments, typed, and its handler. The chat box completes the names and checks the arguments before a line is sent, and the server checks them again. run_by says who may run one, as a group.

Every server has the same actions, each on a key the player chooses once for all of them: moving, firing, the slots, crouching, and nine purpose actions that do nothing until a mod handles them, named by what they are for: tactical, lethal, utility, ultimate, buy, drop, quick_menu, ping and map. No mod binds a key. action handles a purpose action, with a label players see beside it, hearing its key go down and up; p.held says which actions a player holds. A client script reads the player’s keys for an action with keys_of, as a hint does, and whether one is held with is_held.

A player binds keys in Settings → Controls, which lists every action, the server’s label beside each purpose action its mod handles, or with /bind. On a server, Controls asks whether a change is for every server or this server alone, so a player may put tactical on F5 on your server and keep it on Q on the rest. The loading screen lists the actions your mod handles, with their labels and the player’s keys.

Crouch, prone, sprint, aim and the scoreboard a player holds or toggles, as they choose in Controls for every server: crouch and prone toggle by default, the rest are held. A toggled one is on from one press to the next, and your mod sees it held all that while, in p.held and is_held. The engine turns a toggled sprint off when the sprint ends, a toggled aim on a weapon whose aim_fov is a list, which steps a level a press, and toggled aim, sprint and scoreboard when the player dies; crouch and prone stay, and no life starts aiming or sprinting. A purpose action is never toggled: its handler hears each press and release, and a mod that wants a toggle writes it.

key action key action
W A S D forward, left, back, right Q tactical
Space jump G lethal
C crouch E utility
Ctrl prone X ultimate
Shift sprint 4 equipment
left, right mouse fire, aim B buy
R reload H drop
F use Z quick_menu
V melee middle mouse ping
1, 2, 3, 5 slot1, slot2, slot3, slot5 M map
wheel up, down slot_next, slot_prev T, ` chat
Tab scoreboard F12 screenshot

These are the keys a player who never changed them has. An argument can take a word of a list, such as a map to vote for: choices fills the list, for everyone or for one player. switch_off turns stock actions off, such as sprinting.

What a player, p, or an entity, e, reads beside the mod’s state. A field of the other side’s fails.

NameTypeSideWhat it is
p.held{[string]: boolean}?On the serverThe actions they held as of the last tick, as p.held.fire or p.held.tactical: the buttons, the movement keys and the purpose actions; a dead player's too. Crouch, prone, sprint and aim toggled by the player read held while on.
p.pressed{[string]: boolean}?On the serverThe actions they held at any point since the tick before, as held names them.
On a client is_held(action) → boolean

Gives whether the player holds an action, as Tab for scoreboard, Shift for sprint or Q for tactical, on whatever keys the player put it. Crouch, prone, sprint, aim and the scoreboard a player may toggle in place of holding: a press turns one on and the next off, and it reads held while on.

A render that reads it draws again as it changes. A name of no action fails.

NameTypeWhat it is
actionstringNeeded.
Returns
boolean
Fails
  • a value of the wrong type

To show the scoreboard while it is held, or toggled on

Section titled “To show the scoreboard while it is held, or toggled on”
mount(function()
if not is_held("scoreboard") then
return nil
end
return Box { "Scores", style = { position = "absolute", top = 100, left = 0, right = 0, textAlign = "center" } }
end)
On a client keys_of(action) → {string}

Gives the player's keys for an action, as "tactical", or a command line they bound, as "open shop": an array of the keys' names, in the order Controls shows them, a key bound for this server alone first, empty for none.

A render that reads it draws again as the player rebinds, so a hint names the key they press.

NameTypeWhat it is
actionstringNeeded.
Returns
{string}
Fails
  • a value of the wrong type

To tell the player which key plants the bomb

Section titled “To tell the player which key plants the bomb”
mount(function() return Box { `Hold {keys_of("use")[1] or "use"} to plant`, style = { position = "absolute", top =
700, left = 900 } } end)
On the server choices(name, words?, { player? }?)

Fills the list name, whose words a command's t.choices(name) argument takes, as maps to vote for; with nil words, empties it.

A list is everyone’s, or with player that player’s own, read over everyone’s for them. It has any number of words, each up to 32 bytes without spaces, as many as a player’s game can be sent; a mod has 8 names of lists in all, each 1 to 16 lowercase letters, digits and _. Each player’s game is told a list again as it changes, and completes its words as they are typed.

NameTypeWhat it is
namestringNeeded.
words{string}?May be left out.
optionstable?A table of the options below. It, and each option, may be left out.
player(Player | number)?The player whose own list it is, read over everyone's; everyone's without.
Fails
  • a value of the wrong type
  • an option it does not have
command("vote", { help = "Vote for the next map", args = { { "map", t.choices("maps") } } }, function(e)
say(`{e.player.name} votes for {e.map}`)
end)
on("start", function()
choices("maps", { "yard", "testbed" })
end)

To give one player a list of their own, and take it away

Section titled “To give one player a list of their own, and take it away”
choices("maps", { "yard" }, { player = p })
choices("maps", nil, { player = p })
On the server command(name, spec, run?)

Declares one of the mod's commands, which players type in the chat box after a / or run by a key they bind, and its handler, run.

A module declares its commands at its top as it loads. The box reaches one by its name, an alias, or either as module.name (/admins.mute, main. for main.server.luau’s). A name or an alias two modules declare fails at load, naming both; a module declaring one again replaces its own. Names, aliases and argument names are 1 to 16 lowercase letters, digits and _, an argument’s not a Luau keyword, as its handler reads e.<name>; none is named player. No name or alias is one of the client’s own (bind, binds, clear, connect, disconnect, forget, fov, help, maxfps, name, netgraph, quit, rate, request, screenshot, sensitivity, unbind, volume), nor the engine’s (set, reset, match, match_next, match_restart, match_rotation, kick, ban, unban), nor an action’s, as jump, slot1 or map. A mod has up to 256 commands.

Each argument of args is { name, type }, its type one of t’s: t.player, typed by any part of a name or as #id and given as the player; t.int, t.number, t.string (one word) or t.one_of, refused outside their limits (/mode: rounds: 1 to 9, got 10); t.duration, a whole number and its unit, 30s, 5m, 12h or 7d, up to 3650 days, given in seconds; t.text, the rest of the line, so last; or t.choices(name), a word of the list choices fills. Any of them t.optional(…) may be left out, after those needed, and reads nil.

Each player’s game is told the commands they may run and the lists those read, again as what a run_by reads changes, so a player’s box never lists one they may not run. The box completes them and checks a line before it is sent; the server checks it again, tells the player why one is dropped, and runs run with e.player, who ran it, and each argument by its name. The server prints each command run, and each one dropped. A command typed counts as a line said, one a second either kind; one run by a key, 10 a second after a burst of 5. No mod binds a key: a player binds a command themselves, and a key held down is an action’s (action).

What run returns before any wait, {to, label, color} as say takes them, shows the line typed as chat to the players to lists, written from what the server took, players by name, never back to the player; without to, or if run fails, no one sees it. A command declared without run is heard by on_event("command", player, name, args), args in order and players by id, whose answer routes it the same.

NameTypeWhat it is
namestringNeeded.
spectableA table of the options below. Each may be left out.
helpstring?What /help shows of it, up to 64 bytes.
aliases{string}?Other names the box runs it by, up to 4.
args({{string | Type}})?Its arguments in order, up to 8, each { name, type } of a type of t; none without.
run_by(Group | ((Player?, Player) -> boolean))?Who may run it: any group but those that pick by an owner (owner, team, spectators); everyone without.
run((e: {player: Player, [string]: any}) -> Routing?)?May be left out.
Fails
  • a value of the wrong type
  • an option it does not have
command("me", { help = "Say what you do", args = { { "action", t.text } } }, function(e)
say(`* {e.player.name} {e.action}`)
end)

To give admins a command, shown to the player it is run on

Section titled “To give admins a command, shown to the player it is run on”
command("slay", {
help = "Kill a player",
aliases = { "sl" },
args = { { "target", t.player }, { "reason", t.optional(t.text) } },
run_by = admins,
}, function(e)
e.target:hurt(e.target.health, e.player)
return { to = { e.target }, label = "Admin", color = "#ff4040" }
end)
On the server action(name, { label }, handler)

Handles a purpose action, hearing its key go down and up: tactical, lethal, utility, ultimate, buy, drop, quick_menu, ping or map, named by what it is for.

A player binds each action once, for every server, so a mod uses the keys they chose and binds none. Their Controls and loading screen show label beside it. A module declares it at its top as it loads; one two modules declare fails at load, naming both, and a module declaring it again replaces its own.

handler runs for every player as their key goes down and as it goes up, e.down saying which, on the player’s own time, as their requests do. When that time is spent, a press is dropped: a key still held is heard at the next mod tick, and a key let go is heard only if its press was. A tap between mod ticks is heard down and up a tick apart; one held as its player leaves is heard let go before leaving; p.held.<action> is true in between. A player typing /<action> taps it. A tap or a hold is the mod’s to tell apart: the engine never toggles one.

Until weapons go on these keys, lethal throws a frag grenade the player carries, and tactical a smoke grenade, whether a mod handles them or not.

NameTypeWhat it is
name"tactical" | "lethal" | "utility" | "ultimate" | "buy" | "drop" | "quick_menu" | "ping" | "map"Needed.
optionstableA table of the options below. Those marked needed may not be left out.
labelstringWhat a player's Controls and loading screen show beside the action, up to 64 bytes. Needed.
handler(e: {player: Player, down: boolean}) -> ()Needed.
Fails
  • a value of the wrong type
  • an option it does not have
  • a key it needs left out
action("ultimate", { label = "Call in the airstrike" }, function(e)
if e.down then
say(`{e.player.name} calls in an airstrike`)
end
end)
action("utility", { label = "Walk slowly" }, function(e)
e.player:tune({ speed = if e.down then 0.5 else 1 })
end)
On the server switch_off(...actions)

Switches stock actions off for the mod: their keys do nothing, and the server drops their buttons.

Any module may switch any off, at its top as it loads. slots is the keys taking the weapons in the slots, while the wheel stays; scoreboard is the key showing the scoreboard, which client scripts draw while it is held.

NameTypeWhat it is
...actions"use" | "slots" | "scoreboard" | "reload" | "crouch" | "prone" | "sprint" | "melee"Any number of them.
Fails
  • a value of the wrong type
switch_off("sprint", "prone")