Skip to content

These docs describe Bloom 0.1.0, a pre-release. APIs may change before 1.0, and Bloom is not on Maven Central yet (see Installation).

Messaging

Chat, action bars, titles and boss bars with placeholders, MiniMessage and legacy colour codes on every version.

bloom.messages() returns a Messenger. Messengers are immutable: withPrefix, withFormat and withUnsupportedPolicy return new ones, so keep the variants you use as fields.

Sending messages

JavaView source
Messenger messages = bloom.messages().withPrefix("&d&lShop &8ยป &7");
messages.send(
        player,
        "You bought &f{amount}x {item}&7.",
        Placeholder.of("amount", 3),
        Placeholder.of("item", "Golden Apple"));
messages.broadcast("&f{player} &7joined the arena!", Placeholder.of("player", player.getName()));

send adds the messenger's prefix; action bars, titles and boss bars never get the prefix. broadcast sends to every online player and the console.

Placeholders

Write {name} in a template and pass Placeholder.of("name", value). Substitution happens in one pass, so a value that itself contains {other} is not expanded again. Unknown placeholders are left as they are.

Placeholder values are plain text by default: colour codes or MiniMessage tags inside them are neutralised. That makes it safe to insert player names and chat. Use Placeholder.formatted only for text you trust.

JavaView source
// Placeholder.of: plain text. "&c" or "<red>" inside chatMessage is shown literally.
bloom.messages().send(player, "&7[Chat] &f{message}", Placeholder.of("message", chatMessage));
// Placeholder.formatted: trusted text that should keep its formatting.
bloom.messages().send(player, "Rank: {rank}", Placeholder.formatted("rank", "&6&lVIP"));

Formats

Bloom supports two markup formats on every server. The default is TextFormat.LEGACY; change it for the whole plugin with BloomOptions.textFormat(...) or per messenger with withFormat.

LEGACYMINIMESSAGE
Example&dHello &lworld<light_purple>Hello <bold>world
Paper 1.21+ / 26.xConverted with Adventure, &#RRGGBB hex supportedReal MiniMessage
1.7 / 1.8NativeConverted by Bloom (see below)
JavaView source
Messenger mini = bloom.messages().withFormat(TextFormat.MINIMESSAGE);
mini.send(
        player,
        "<gradient:#F2A7CC:#B9A0DD>Welcome</gradient> <gray>to the server, <white>{player}</white>!",
        Placeholder.of("player", player.getName()));
// On 1.7/1.8 the gradient uses its first colour; colours, bold, italic and so on convert exactly.

Action bars and titles

JavaView source
Messenger messages = bloom.messages();
messages.actionBar(player, "&a+5 coins");
messages.title(
        player,
        Title.of("&dRound 2", "&7Fight!")
                .times(Duration.ofMillis(250), Duration.ofSeconds(2), Duration.ofMillis(500)));
// Returns false when skipped (e.g. action bars on 1.7.10 with the default SKIP policy).
boolean shown = messages.actionBar(player, "&eCapturing...");

Title timings need the TITLE_TIMINGS capability; on 1.8 the client's default timings are used.

Boss bars

Boss bars exist only on modern Paper (BOSS_BAR). They must be created and changed on the main thread, and Bloom hides them from all viewers on shutdown.

JavaView source
BloomBossBar bar = bloom.messages()
        .bossBar(
                "&dEvent ends in {time}",
                1.0f,
                BossBarColor.PINK,
                BossBarStyle.SEGMENTED_10,
                Placeholder.of("time", "5:00"));
bar.show(player);
bar.progress(0.5f).title("&dEvent ends in 2:30");
bar.close(); // also closed automatically on shutdown
// isFunctional() is false on servers without boss bars (unless the policy is THROW, which throws instead)

Unsupported features

When a server lacks a feature, the messenger's UnsupportedFeaturePolicy decides what happens:

PolicyEffect
SKIP (default)Nothing is sent; the method returns false; one warning per feature is logged
FALLBACK_TO_CHATAction bars and titles are sent as chat messages; boss bars are skipped
THROWUnsupportedCapabilityException naming the capability and the platform
JavaView source
Messenger strict = bloom.messages().withUnsupportedPolicy(UnsupportedFeaturePolicy.THROW);
Messenger lenient = bloom.messages().withUnsupportedPolicy(UnsupportedFeaturePolicy.FALLBACK_TO_CHAT);
lenient.title(player, Title.of("&6Victory")); // a chat line on servers without titles

Threads

Chat, action bars and titles can be sent from any thread. Boss bars are main-thread only. For strings that must be plain legacy text (scoreboards, signs), use messenger.legacy(template, placeholders...).