Wizards of Lua — Dynamic Commands¶
With dynamic commands you can register custom commands at runtime and bind them to Lua code. You can add, remove, and inspect commands via the WizardsOfLua module API.
1. Registering a Dynamic Command¶
A command definition is a Lua table with these attributes:
id(string): unique identifier and permission node (e.g.coins.add).level(number): minimum operator level (0 - 4) required for invoking this command.pattern(string): Brigadier-style syntax with literals and%-placeholders.code(string): Lua code; receives anargstable mapping placeholders to parsed values.
Example: define a new command¶
-- Register a command that adds coins to a player
WizardsOfLua.setCommand( {
id = "coins.add",
level = 2,
pattern = "coins add amount:%i to p:%player",
code = [[
local player = args.p
local c = player.extra.coins or 0
c = c + args.amount
player:putExtra({ coins = c })
print(player.name .. " now has " .. c .. " coins.")
]]
})
In‐game, invoke it like this:
Note: Calling
WizardsOfLua.setCommand(…)queues the new command for registration at the end of the current game tick. The command becomes usable on the next tick. So if your script wants to invoke it immediately, you need to yield for one tick (e.g. viasleep(1)) before calling it. Wizards of Lua will not replace other mods’ or vanilla commands. If the requested top-level literal is already taken by another provider, setCommand(...) throws an error.
2. Command ID syntax¶
- Use a dot-separated sequence of lowercase words (e.g.
my.command.action). - If you integrate with a permissions plugin (LuckPerms, etc.), this ID becomes the permission node.
3. Pattern Syntax¶
A pattern is one or more tokens separated by spaces. Each token can be:
- Literal word (e.g.
home,spawn,coins) - Unnamed placeholder (e.g.
%s,%i,%d, …) - Named placeholder (e.g.
name:%s,amount:%i, …)
Naming rule: All placeholders in a single pattern must be either all unnamed or all named.
Greedy%s: If%sappears as the last token, it captures the rest of the input, including spaces.
3.1 Enum-String Placeholders¶
If you need a string argument that’s restricted to a fixed set of values (and you want built-in tab-completion), use:
- Unnamed enum-string:
- Named enum-string:
At runtime the system will:
- Suggest only
easy,normal,hardwhen you press Tab. - Reject any other value with a “Unknown value” error.
4. Accessing Placeholder Values¶
When your command runs, the parsed values are provided in the args table:
- Unnamed placeholders → passed by index
- Named placeholders → passed by key
-- Pattern: "coins add amount:%i to p:%player"
-- Invocation: /coins add amount:50 to Alice
args = { amount = 50, p = <Player Alice> }
5. Placeholder Reference¶
| Placeholder | Description | Returns | Lua Type |
|---|---|---|---|
%s |
String (single word or greedy if last) | raw text | string |
%s[o1…oN] |
Enum-string (only accepts the listed options) | one of o1…oN |
string |
%d |
Floating-point number | e.g. 3.14, -0.5 |
number |
%i |
Integer | e.g. 42, -7 |
number |
%b |
Boolean | true or false |
boolean |
%v |
3D vector (x, y, z) | a Vec3d |
Vec3 |
%entity |
Single entity (selector or name) | one Entity |
Entity |
%entities |
Multiple entities (selector or names) | list of Entity |
{ Entity, … } |
%player |
Single online player (selector or name) | one Player |
Player |
%players |
Multiple online players (selector/list) | list of Player |
{ Player, … } |
%item |
Item-stack argument | an ItemStack |
Item |
Options: Options are separated by
|characters, e.g.red|green|blue.
Selectors: Most selectors (@e,@a, etc.) require operator level ≥ 2 to use.
6. Defining the Lua Callback¶
The code field is a string containing your Lua logic. It is compiled and run at invocation time.
- Syntax errors only surface when the command is executed.
- Inside your code,
argsis a predefined variable that contains the placeholder values.
7. Managing Dynamic Commands¶
7.1 Listing Commands¶
local all = WizardsOfLua.listCommands()
for i, cmd in ipairs(all) do
print(i, cmd.id, "→", cmd.pattern, "(level " .. cmd.level .. ")", cmd.code)
end
7.2 Removing a Command¶
8. Best Practices¶
- Unique IDs: Avoid collisions by choosing clear, namespaced IDs.
- Permission Levels: Assign higher levels (2–4) to potentially destructive commands.
- Code Size: Aim for inline Lua snippets under ~20 lines. For complex logic, factor code into separate
.luafiles underconfig/wizards-of-lua/andrequirethem from your code block.
What’s next?¶
- Browse the Frequently Asked Questions.