First Command
First Command
Section titled “First Command”This page shows the normal DaisyCore command workflow:
- define a command group
- annotate it with
@DaisyCommandSet - let
DaisyPlatformdiscover it at startup - use direct MiniMessage strings by default
The important default
Section titled “The important default”reply("...") is already MiniMessage-first.
That means this is normal DaisyCore code:
reply("<gradient:#7dd3fc:#c4b5fd>Opening your profile.</gradient>")You do not need:
- a key
- a
DaisyTextSource - a config file
just to send a normal formatted message.
Step 1: create a command group
Section titled “Step 1: create a command group”package cat.daisy.example.command
import cat.daisy.command.DaisyCommandGroupimport cat.daisy.command.DaisyCommandSet
@DaisyCommandSetobject ProfileCommands : DaisyCommandGroup({ command("profile") { description("Open your profile tools")
player { reply("<gradient:#7dd3fc:#c4b5fd>Opening your profile.</gradient>") } }})Step 2: add a subcommand
Section titled “Step 2: add a subcommand”command("profile") { description("Open your profile tools")
subcommand("open") { player { reply("<green>Profile opened.</green>") } }}Step 3: keep async replies clean
Section titled “Step 3: keep async replies clean”subcommand("sync") { player { loading()
profileService.sync(player.uniqueId).replyResult( context = this, success = { reply("<green>Profile synced for <white>${player.name}</white>.</green>") }, failure = { error -> fail("<red>Profile sync failed:</red> <gray>${error.message.orEmpty()}</gray>") }, ) }}Step 4: use shared config-backed text only when it helps
Section titled “Step 4: use shared config-backed text only when it helps”If your plugin already stores text in lang.yml, admin-editable config, or translation bundles, then replyLang(...) becomes the clean scaling path.
command("profile") { description("Open your profile tools")
player { replyLang("profile.opening", "player" to player.name) }}That key is just your plugin’s own path.
It is useful when you want:
- reloadable text
- shared wording across systems
- localization
- large config-driven message sets
It is not required for a basic command.
Components still work
Section titled “Components still work”If your plugin is already component-first, you can still send components directly:
reply( Component.text("Profile opened.") .color(NamedTextColor.AQUA))The recommended order is:
- direct MiniMessage strings
- components when you want explicit control
- config-backed keys when you want shared or reloadable text
How discovery works
Section titled “How discovery works”When commands() is enabled in your DaisyPlatform builder, DaisyCore scans your plugin jar for types annotated with @DaisyCommandSet.
That means normal usage does not require manual command provider registration.
Next steps
Section titled “Next steps”- Open a UI from a command: First Menu
- Learn the shared config-backed text path: Config and Lang Text
- Jump to API details: Command DSL