-
Notifications
You must be signed in to change notification settings - Fork 1
PLUGINS COMMANDS
Pixels uses Brigodier, a Go implementation of Brigadier's command tree model. Plugins register command roots during startup. Room chat beginning with PIXELS_COMMAND_PREFIX is parsed by that shared tree before it can become visible speech.
A command is a graph of literal and typed argument nodes. Brigodier chooses a valid path, enforces node requirements, converts values, and runs the executor attached to the terminal node. This keeps parsing rules beside the command structure and avoids a different manual parser in every plugin.
hello
executes hello for the sender
name as StringPhrase
executes hello for name
The equivalent builder is:
root := brigodier.Literal("hello").
Executes(brigodier.CommandFunc(func(call *brigodier.CommandContext) error {
return replyToSender(call, senderName(call))
})).
Then(brigodier.Argument("name", brigodier.StringPhrase).
Executes(brigodier.CommandFunc(func(call *brigodier.CommandContext) error {
return replyToSender(call, call.String("name"))
})))StringPhrase consumes the remaining text as one value. Brigodier also provides typed arguments such as Int. A malformed or incomplete path is consumed as a command and produces localized feedback rather than appearing in room chat.
Pixels places an sdk/command.Sender in the command context. It represents the origin without forcing command code to depend on a live player type.
func replyToSender(call *brigodier.CommandContext, name string) error {
sender, found := sdkcommand.SenderFrom(call.Context)
if !found {
return nil
}
return sender.Reply(call.Context, "Hello, "+name)
}
func senderName(call *brigodier.CommandContext) string {
sender, found := sdkcommand.SenderFrom(call.Context)
if !found {
return "world"
}
return sender.Name()
}Name returns a display identity. Kind distinguishes player and future trusted console callers. Reply sends feedback through the originating channel. HasPermission resolves the real Pixels permission system.
A plugin registers only its local suffix:
err := host.Permissions().Register(
"hello.use",
"Use the hello command",
)Pixels expands that suffix using the manifest name:
plugin.hello-plugin.hello.use
The expanded node joins the normal permission catalog. Operators grant or deny it to permission groups or directly to a player through the same administration API used for native capabilities. There is no plugin rank table and no independent permission resolver.
Local names must be concrete dotted nodes. They cannot begin with plugin., contain a wildcard, or use another plugin's namespace. The description is required because it is displayed with the runtime node catalog.
Requirements belong on the earliest node that should be hidden from a sender. Placing the requirement on the root protects every descendant.
const helloPermission = "plugin.hello-plugin.hello.use"
root := brigodier.Literal("hello").
Requires(sdkcommand.RequiresPermission(helloPermission)).
Executes(brigodier.CommandFunc(runHello))
err := host.Commands().Register(root)RequiresPermission reads the sender from context and calls its HasPermission. A player without the node receives the localized denied response. The executor is never called.
Only one plugin may own a root literal. Registering another hello root fails startup registration for the second plugin. Child literals and arguments belong to the root owner.
| Input | Result |
|---|---|
| Does not begin with the configured prefix | Continues as normal room chat |
| Prefix with no command | Consumed with incomplete command feedback |
| Unknown root | Consumed with unknown command feedback |
| Known root without permission | Consumed with denied feedback |
| Malformed argument | Consumed with invalid command feedback |
| Valid command | Executor runs within the plugin callback deadline |
| Panic | Plugin is disabled and the sender receives failure feedback |
| Timeout | Sender receives timeout feedback |
Commands never echo the raw prefixed text to the room. This is important for administrative arguments that may contain player identifiers or operational data.
Listen to event.CommandAttemptName to observe every player input that begins
with PIXELS_COMMAND_PREFIX. Detection happens before Brigadier parsing and
therefore includes valid, denied, malformed, incomplete, and unknown commands.
CommandAttempt.Input excludes the prefix and Root contains the first token
when present.
The detector is a notification, not a command interceptor. It cannot cancel or claim execution; register a Brigadier root when the plugin owns behavior.
The command helper does not decide authorization itself. It delegates to the hotel wide algorithm documented in USERS-PERMISSIONS. Direct player overrides, group weights, inheritance, wildcard specificity, and deny precedence all apply to plugin nodes exactly as they apply to native nodes.
Pixels
Getting Started
Architecture
Architecture Internals
Authentication
Users
Navigator
Inventory
Furniture
Rooms
Decoration
Games
Plugins
- PLUGINS-OVERVIEW
- PLUGINS-CREATING
- PLUGINS-LISTENERS
- PLUGINS-EVENTS-REALMS
- PLUGINS-EVENTS-ECONOMY-ROOMS
- PLUGINS-EVENTS-MODERATION-TRADES
- PLUGINS-EVENTS-COMMERCE-WORLD
- PLUGINS-EVENT-FURNITURE-MOVE
- PLUGINS-EVENT-FURNITURE-PICKUP
- PLUGINS-EVENT-ROOM-CREATE
- PLUGINS-EVENT-MARKETPLACE-LIST
- PLUGINS-EVENT-MARKETPLACE-BUY
- PLUGINS-EVENT-PLAYER-PROFILE-UPDATE
- PLUGINS-EVENT-BOT-SPEECH
- PLUGINS-EVENT-GROUP-MEMBERSHIP-CHANGE
- PLUGINS-EVENT-MESSENGER-FRIEND-REQUEST
- PLUGINS-EVENT-MESSENGER-FRIEND-ACCEPT
- PLUGINS-EVENT-CRAFTING-CRAFT
- PLUGINS-WIRED
- WIRED
- PLUGINS-COMMANDS
- PLUGINS-SDK
- PLUGINS-DEPLOYMENT