Actions & Requirements
Everything a menu does is an action; everything it checks is a requirement
(also called a condition). Both are written the same way โ a bare id:value reference โ
and both are shared by the built-in menus and your own.
Bare references, never brackets
A reference is id:value: message:hi, command:spawn, has-money:500, perm:vip,
open:shop. There is no bracketed [message] form. An action or condition that takes
no value is just its id: close, back, has-next. A leading ! on a condition
inverts it: !perm:uxmessentials.vip.
Actions¶
Actions run in order. Any action reference can also carry per-action modifiers โ a
delay in ticks, a chance percent, and a fallback to run if the chance roll fails โ
when written as a block instead of a bare string.
The table below is the common set; the engine ships around sixty action ids in total
(plus aliases), and modules and the Menu API can register
more. Use /menu dump <menu> to see exactly what a menu resolves.
| Action | Does |
|---|---|
close |
Close the menu. |
back |
Return to the previous menu. |
open:<menu> |
Open another menu by name. |
refresh |
Re-render the whole menu. |
refresh-slot:<slot> |
Re-render one slot. |
reset-pagination |
Jump back to page one. |
message:<text> |
Send the clicker a chat message (MiniMessage). |
broadcast:<text> |
Announce to everyone. |
action-bar:<text> |
Show an action-bar line. |
title:<text> |
Show a title. |
toast:<text> |
Pop an advancement-style toast. |
sound:<key> |
Play a sound to the clicker. |
broadcast-sound:<key> |
Play a sound to everyone. |
command:<cmd> |
Run a command as the player. |
console:<cmd> |
Run a command as the console. |
command-as-op:<cmd> |
Run a command with a temporary op. |
command-random:<a;b;โฆ> |
Run one of several commands at random. |
give-money:<amt> ยท take-money:<amt> ยท set-money:<amt> |
Adjust the player's balance. |
give-points:<amt> ยท take-points:<amt> |
Adjust PlayerPoints. |
give-exp:<amt> ยท take-exp:<amt> ยท give-levels:<n> |
Adjust experience / levels. |
give-permission:<node> |
Grant a permission (via Vault). |
give-item:<item> ยท take-item:<item> ยท set-item:<item> |
Give / take / set an item (accepts a b64: item string). |
data-set: ยท data-add: ยท data-sub: ยท data-remove: |
Read/write a per-player data value. |
meta-set: ยท meta-add: ยท meta-remove: |
Read/write a per-player metadata value. |
set-cooldown:<key> |
Stamp a cooldown the cooldown: condition can read. |
teleport:<x,y,z[,world]> |
Teleport the player. |
connect:<server> |
Send the player to another server (proxy). |
Requirements¶
A requirement decides whether a click's actions run, or whether a tile is even visible.
Every requirement is a condition reference; a leading ! inverts it.
| Requirement | Passes when |
|---|---|
perm:<node> |
The player has the permission. |
has-money:<amt> |
Balance is at least the amount. |
has-points:<amt> |
PlayerPoints balance is at least the amount. |
has-exp:<amt> ยท has-level:<n> |
Enough experience / a high enough level. |
has-item:<item> |
The player is holding / carrying the item. |
has-empty-slots:<n> |
At least N free inventory slots. |
has-meta:<key> |
A metadata value is present / matches. |
has-prev ยท has-next ยท on-page:<n> |
Pagination state (used on page-control tiles). |
cooldown:<key> |
A named cooldown has elapsed. |
expr:<expression> |
A boolean expression (with placeholders) is true. |
compare: ยท papi-compare: |
A numeric / placeholder comparison holds. |
equals-ignorecase:<a;b> |
Two strings match, ignoring case. |
contains:<a;b> |
One string contains the other. |
regex: ยท length: ยท is-integer: |
String-shape checks. |
world:<name> |
The player is in the named world. |
is-near: ยท cuboid: |
The player is within a radius / region. |
has-group:<group> ยท job:<name> ยท worldguard-region:<id> ยท weather:<kind> |
Integration checks (LuckPerms / JobsReborn / WorldGuard / world weather). |
Integration conditions fail closed
A condition that needs a plugin you do not run (job:, worldguard-region:,
has-group: without LuckPerms) can't be evaluated, so it is treated as false โ
the tile hides or the click is denied rather than silently passing. Install the
plugin, or don't use the condition.
Per-gesture click blocks¶
A gesture can be a bare action list, or a block that gates its actions behind
requirements and runs a deny list (or an else fallback) when the gate fails.
click {
# Simple form: always runs on left-click.
left = ["command:kit starter", "close"]
# Gated form on right-click.
right {
requirements = ["perm:uxmessentials.vip", "has-money:100"]
minimum = 2 # both must pass (see below)
actions = ["take-money:100", "command:kit vip"]
deny = ["message:<red>VIPs only, and it costs 100."]
}
# 'any' fires alongside whichever gesture the player used.
any = ["sound:UI_BUTTON_CLICK"]
}
minimum โ how requirements combine¶
The minimum key turns a requirement list into AND / OR / N-of-M without a separate
flag:
minimum |
Meaning |
|---|---|
omitted or 0 |
All requirements must pass (AND). |
1 |
Any one may pass (OR). |
N (between) |
At least N of the M must pass. |
View requirements¶
The same block gates a tile's visibility. A flat list is an all-must-pass AND; the
block form lets you use minimum and inversion.
# Flat form โ hide unless BOTH hold.
view = ["perm:uxmessentials.vip", "!world:spawn"]
# Block form โ show if the player meets ANY one of the three.
view {
requirements = ["perm:uxmessentials.tier1", "perm:uxmessentials.tier2", "has-money:1000"]
minimum = 1
}
A tile whose view fails is not drawn at all โ it does not appear greyed-out, it simply
isn't there.
Next Steps¶
- Custom Menu Engine โ the full spec and a worked example.
- Menu API โ register your own actions, conditions and placeholders.
- Permission Reference โ nodes for
perm:conditions. - Bedrock Forms โ how these menus render for Floodgate players.