Skip to content

docs(conventions): gate command words with uxmLib's Gate - #39

Merged
siracozmen01 merged 1 commit into
mainfrom
docs/command-gates
Nov 4, 2026
Merged

siracozmen01 merged 1 commit into
mainfrom
docs/command-gates

Conversation

@siracozmen01

Copy link
Copy Markdown
Member

A customer read Incorrect argument for command kits editor<--[HERE] (2026-11-04): a native requires hides a word from the parser too, so a player without the node gets Brigadier's text instead of the catalog line the standard asks for. The rule: who may use a word is a uxmLib Gate; requires takes nothing else.

Goes with UXPLIMA/uxm-lib feat/command-gates (the Gate API) and UXPLIMA/uxm-essentials feat/command-gates (every essentials command moved onto it).

@siracozmen01 siracozmen01 changed the title docs: gate command words with uxmLib's Gate, never a native requires docs(conventions): gate command words with uxmLib's Gate Nov 4, 2026
@siracozmen01 siracozmen01 reopened this Nov 4, 2026
@siracozmen01
siracozmen01 merged commit e52a6b6 into main Nov 4, 2026
10 of 12 checks passed
@siracozmen01
siracozmen01 deleted the docs/command-gates branch November 4, 2026 15:43
siracozmen01 added a commit to UXPLIMA/uxm-lib that referenced this pull request Nov 4, 2026
A customer read `Incorrect argument for command kits editor<--[HERE]`
and nothing in the console (2026-11-04). Brigadier's `requires` hides a
word from the client's command list and from the parser at once, and the
parser tries only the literal a typed word matches, so a sender without
the node reads Brigadier's own text: not the plugin's line, not which
node. The same happens to every `@Permission` branch the annotation
layer renders, through `Cmd.visibility`.

This separates the two jobs.

- `Gate`: who sees a node (`shows`) and who may use it (`allows`). As a
requirement it always passes, so the parser accepts every word.
`Gate.permission`, `Gate.visibility` (keeps the `default: true`
meaning), `Gate.shownTo` (a word for some readers, usable by everyone),
`Gate.when` (a feature that is off), `Gate.open`, joined with
`and`/`or`; a plain predicate cannot be joined in, since it would always
pass.
- `CommandGates.seal`: rebuilds a tree so every executor and every
suggestion below a gate asks the gates on its path first and answers a
refusal with the plugin's `Refusal`. The gates are read at seal time, so
a Paper alias that redirects to the root still passes the root's gate. A
tree with a gate may not redirect anywhere.
- `GateVisibility`: one listener per plugin; trims each player's command
list and the completions the server sends of what a gate hides from
them. Geyser translates the same list.
- `CommandRegistrar` seals and listens; a new overload takes a
`Refusal`, the old one answers with the server's permission message.
`AnnotatedCommands` refuses with `CommandMessages.noPermission`. The
executor of an annotated branch now checks the class node as well as its
own.
- `Cmd.permission` and `Cmd.visibility` keep their native meaning and
are deprecated.

17 tests run the trees in a real `CommandDispatcher`: refusals,
suggestions (custom and the argument type's own), pruning, words for
some readers, redirects, joined gates, the class node. Checked on a
Folia server through uxmEssentials built on this snapshot: a player
typing `/kits editor`, `/worlds create`, `/guard define` or `/npc
create` reads the catalog's no-permission line; the tree each player was
sent, captured after the listener, lacked every staff word for the
player and held all of them for an operator.

Goes with UXPLIMA/uxm-essentials feat/command-gates and
UXPLIMA/.github#39.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant