PrismaticAPI is a Bukkit/Paper text-formatting library for RGB colors, gradients, rainbows, MiniMessage-aware parsing and legacy-safe fallback.
Version 1.4.0 reorganizes the public API around two facades backed by the same formatting engine:
PrismaticAPI.legacy()returnsFormatter<String>PrismaticAPI.adventure()returnsFormatter<Component>
The old top-level methods such as PrismaticAPI.colorize(...) and PrismaticAPI.applyGradient(...) still exist and now delegate to legacy() for compatibility.
- Added
PrismaticAPI.legacy()as the always-safe string formatter facade. - Added
PrismaticAPI.adventure()as the optional Adventure formatter facade. - Added
PrismaticAPI.isAdventureAvailable()to guard Adventure-only code paths. - Removed
RichText. - Removed
colorizeText(...),applyColorText(...),applyGradientText(...)andapplyRainbowText(...). - Kept the existing legacy top-level helpers as compatibility delegates to
legacy().
- One formatting engine for legacy strings and Adventure components.
- Multiple single-color RGB syntaxes.
- Gradient and rainbow tags.
- Optional MiniMessage support at runtime.
- Player-aware legacy fallback through VNC/ViaVersion support.
- Safe startup on runtimes where Adventure is not present.
groupId: me.croabeast
artifactId: PrismaticAPI
version: 1.4.0
Add the repository that hosts your published artifact, then depend on me.croabeast:PrismaticAPI:1.4.0.
If your plugin calls PrismaticAPI.adventure(), keep the Adventure API on your compile classpath and ensure the required Adventure runtime classes are present when the plugin starts.
{#ff8800}%#ff8800%[#ff8800]<#ff8800>&xff8800#ff8800&#ff8800
<g:ff0000>Hello</g:0000ff><gradient:ff0000>Hello</gradient:0000ff><#ff0000>Hello</#0000ff><#ff0000:#00ff00:#0000ff>Hello</gradient>
<rainbow:1>Hello</rainbow><r:1>Hello</r>
&a&l&n&r
When Adventure MiniMessage is present at runtime, standard MiniMessage tags can be mixed with Prismatic syntax in the same string.
PrismaticAPI processes text in this order:
- MiniMessage, when the Adventure runtime is available.
- Prismatic multi-color blocks such as gradients and rainbows.
- Single RGB syntaxes.
- Legacy Bukkit formatting such as
&a,&land&r.
This lets MiniMessage and Prismatic tags coexist without forcing Adventure to be present on every runtime.
legacy() returns Formatter<String>, which is always safe to use. It emits Bukkit/Bungee-compatible color-code strings.
String raw = "<g:ff0000>Hello</g:0000ff> &lworld";
String formatted = PrismaticAPI.legacy().colorize(player, raw);
player.sendMessage(formatted);adventure() returns Formatter<Component> and uses the same Prismatic parser to build Adventure components.
Always guard this call when Adventure is optional:
if (PrismaticAPI.isAdventureAvailable()) {
Component component = PrismaticAPI.adventure().colorize(player, "<#ff8800>PrismaticAPI");
}If Adventure is not available and you call PrismaticAPI.adventure() anyway, the method throws IllegalStateException with a controlled error message instead of crashing with NoClassDefFoundError.
The classic entry points still work:
String formatted = PrismaticAPI.colorize(player, "<rainbow:1>Chromatic</rainbow>");
String gradient = PrismaticAPI.applyGradient("Hello", Color.RED, Color.BLUE, false);These methods delegate to the legacy() facade.
PrismaticAPI.colorize(String) and PrismaticAPI.legacy().colorize(String) call the formatter without a Player context.
That means PrismaticAPI cannot know whether the receiver supports hex colors, so it falls back to legacy-safe output.
If you want player-aware RGB preservation, call:
String formatted = PrismaticAPI.legacy().colorize(player, raw);If you want exact RGB output without a player capability check, use the explicit color methods with legacy = false:
String solid = PrismaticAPI.legacy().applyColor(new Color(255, 136, 0), "Hello", false);
String gradient = PrismaticAPI.legacy().applyGradient("Hello", Color.RED, Color.BLUE, false);
String rainbow = PrismaticAPI.legacy().applyRainbow("Hello", 1.0f, false);PrismaticAPI can run perfectly fine without Adventure on the classpath as long as you stay on legacy() or the compatibility methods.
PrismaticAPI.adventure() requires these classes at runtime:
net.kyori.adventure.text.Componentnet.kyori.adventure.text.minimessage.MiniMessagenet.kyori.adventure.text.minimessage.tag.resolver.TagResolvernet.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
Both facades use the same parsing pipeline. If MiniMessage is available:
- standard MiniMessage tags are deserialized first
- Prismatic gradients and rainbows are preserved safely during MiniMessage parsing
- output is downsampled when the target must remain legacy-safe
If MiniMessage is not available, Prismatic-specific formatting and legacy color codes still work normally.
String legacy = PrismaticAPI.colorize(player, raw);
RichText text = PrismaticAPI.colorizeText(player, raw);
Component component = text.component();String legacy = PrismaticAPI.colorize(player, raw);
if (PrismaticAPI.isAdventureAvailable()) {
Component component = PrismaticAPI.adventure().colorize(player, raw);
}Migration summary:
- Replace
RichTextusage withPrismaticAPI.adventure(). - Replace
colorizeText(...)withPrismaticAPI.adventure().colorize(...). - Replace
applyColorText(...),applyGradientText(...)andapplyRainbowText(...)with the correspondingadventure()methods. - Keep existing legacy string code unchanged if you only need Bukkit-style strings.
Both facades expose the same helper methods:
fromString(...)stripBukkit(...)stripSpecial(...)stripRGB(...)stripAll(...)startsWithColor(...)getStartColor(...)getEndColor(...)
These methods are useful for inspecting or cleaning already-formatted strings without duplicating parsing logic in downstream plugins.
This project expects the VNC project to exist either:
- next to this repository as
../VNC - or inside this repository as
VNC
The build compiles the sibling VNC jar before compiling PrismaticAPI.
./gradlew jar