Message Formatting
Command Framework now sends string messages through a component formatter. The default formatter is MiniMessage, so framework messages and CommandArguments#sendMessage(String) can use tags such as <red>, <bold>, gradients, hover text, and other Adventure components.
Default MiniMessage Formatting
Section titled “Default MiniMessage Formatting”You can write MiniMessage directly in framework messages and command responses.
@Command(name = "hello")public void helloCommand(CommandArguments arguments) { arguments.sendMessage("<green>Hello, <yellow>" + arguments.getSender().getName() + "</yellow>!");}The framework converts the string into a Component and sends it to the command sender.
arguments.sendMessage("<gradient:#00ff88:#00aaff><bold>Command executed!</bold></gradient>");arguments.sendMessage("<red>You do not have permission for this action.");Formatting Parameterized Messages
Section titled “Formatting Parameterized Messages”The sendMessage(String, Object...) overload still formats parameters first, then passes the final string through the active component formatter.
@Command(name = "coins")public void coinsCommand(CommandArguments arguments) { int coins = 250;
arguments.sendMessage( "<gray>You currently have <gold>{0}</gold> coins.", coins );}Built-in Framework Error Messages
Section titled “Built-in Framework Error Messages”Default error messages also use MiniMessage tags.
| Error Message | Default Output |
|---|---|
CommandErrorMessage.SHORT_ARG_SIZE | <red>Required argument length is less than needed! |
CommandErrorMessage.LONG_ARG_SIZE | <red>Required argument length greater than needed! |
CommandErrorMessage.NO_PERMISSION | <red>You don't have enough permission to execute this command! |
CommandErrorMessage.UNKNOWN_SUBCOMMAND | <red>This command cannot be used directly. |
CommandErrorMessage.WAIT_BEFORE_USING_AGAIN | <red>You have to wait before using this command again! |
You can replace an individual framework message with your own logic.
@Overridepublic void onEnable() { CommandErrorMessage.NO_PERMISSION.setHandler((command, arguments) -> { arguments.sendMessage("<red>You need <yellow>{0}</yellow> to use this command.", command.permission()); return true; });}Using Legacy Color Codes
Section titled “Using Legacy Color Codes”If your plugin still stores messages with & color codes, provide a custom component formatter. The formatter receives the raw message string and must return an Adventure Component.
@Overridepublic void onEnable() { LegacyComponentSerializer legacy = LegacyComponentSerializer.legacyAmpersand();
CommandErrorMessage.setMessageFormatter(text -> legacy.deserialize(text) );}@Command(name = "legacy")public void legacyCommand(CommandArguments arguments) { arguments.sendMessage("&aThis message uses legacy color codes.");}Custom Component Formatter
Section titled “Custom Component Formatter”For full control, provide a function that converts every raw message string into a Component.
@Overridepublic void onEnable() { MiniMessage miniMessage = MiniMessage.miniMessage();
CommandErrorMessage.setMessageFormatter(text -> miniMessage.deserialize( "<gray>[MyPlugin]</gray> " + text ));}This formatter is used by:
CommandArguments#sendMessage(String)CommandArguments#sendMessage(String, Object...)- the default
CommandErrorMessagehandlers - custom
CommandErrorMessage#setHandler(...)implementations that callarguments.sendMessage(...)
MiniMessage vs Legacy Formatter
Section titled “MiniMessage vs Legacy Formatter”arguments.sendMessage("<green><bold>Success!</bold> <gray>Your settings were saved.");LegacyComponentSerializer legacy = LegacyComponentSerializer.legacyAmpersand();
CommandErrorMessage.setMessageFormatter(legacy::deserialize);
arguments.sendMessage("&a&lSuccess! &7Your settings were saved.");Choose one formatting style for your plugin messages when possible. Mixing legacy and MiniMessage in the same project can make translations and config files harder to maintain.