Skip to content

Commit ab33658

Browse files
committed
1.4.0 - Adventure Support Rework
1 parent 46d37f9 commit ab33658

11 files changed

Lines changed: 843 additions & 345 deletions

File tree

README.md

Lines changed: 144 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,45 @@
11
# PrismaticAPI
22

3-
PrismaticAPI is a Bukkit/Paper text-formatting library focused on RGB colors, gradients, rainbow effects, MiniMessage compatibility, and legacy fallback.
3+
PrismaticAPI is a Bukkit/Paper text-formatting library for RGB colors, gradients, rainbows, MiniMessage-aware parsing and legacy-safe fallback.
44

5-
It is designed for plugin code that needs one formatting pipeline but multiple output forms:
5+
Version `1.4.0` reorganizes the public API around two facades backed by the same formatting engine:
66

7-
- Plain legacy strings for `Player#sendMessage(...)`
8-
- Adventure components when MiniMessage is available
9-
- Automatic downsampling for older client versions through VNC
7+
- `PrismaticAPI.legacy()` returns `Formatter<String>`
8+
- `PrismaticAPI.adventure()` returns `Formatter<Component>`
109

11-
## Highlights
10+
The old top-level methods such as `PrismaticAPI.colorize(...)` and `PrismaticAPI.applyGradient(...)` still exist and now delegate to `legacy()` for compatibility.
1211

13-
- Multiple RGB syntaxes in one parser
14-
- Gradient and rainbow tags
15-
- Optional MiniMessage integration
16-
- `RichText` results when you want both component and legacy output
17-
- Version-aware fallback using VNC and ViaVersion-aware player checks
12+
## What Changed In 1.4.0
1813

19-
## Formatting pipeline
14+
- Added `PrismaticAPI.legacy()` as the always-safe string formatter facade.
15+
- Added `PrismaticAPI.adventure()` as the optional Adventure formatter facade.
16+
- Added `PrismaticAPI.isAdventureAvailable()` to guard Adventure-only code paths.
17+
- Removed `RichText`.
18+
- Removed `colorizeText(...)`, `applyColorText(...)`, `applyGradientText(...)` and `applyRainbowText(...)`.
19+
- Kept the existing legacy top-level helpers as compatibility delegates to `legacy()`.
2020

21-
`PrismaticAPI` processes text in this order:
21+
## Features
2222

23-
1. MiniMessage, when Adventure MiniMessage is present at runtime
24-
2. Prismatic multi-color blocks such as gradients and rainbows
25-
3. Single RGB color syntaxes
26-
4. Legacy ampersand formatting such as `&a`, `&l`, and `&r`
23+
- One formatting engine for legacy strings and Adventure components.
24+
- Multiple single-color RGB syntaxes.
25+
- Gradient and rainbow tags.
26+
- Optional MiniMessage support at runtime.
27+
- Player-aware legacy fallback through VNC/ViaVersion support.
28+
- Safe startup on runtimes where Adventure is not present.
2729

28-
This keeps MiniMessage and Prismatic tags from stepping on each other while still producing a final legacy string for Bukkit APIs.
30+
## Coordinates
31+
32+
```text
33+
groupId: me.croabeast
34+
artifactId: PrismaticAPI
35+
version: 1.4.0
36+
```
2937

30-
## Supported formats
38+
Add the repository that hosts your published artifact, then depend on `me.croabeast:PrismaticAPI:1.4.0`.
39+
40+
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.
41+
42+
## Supported Syntax
3143

3244
### Single RGB colors
3345

@@ -51,86 +63,158 @@ This keeps MiniMessage and Prismatic tags from stepping on each other while stil
5163
- `<rainbow:1>Hello</rainbow>`
5264
- `<r:1>Hello</r>`
5365

54-
## Quick usage
66+
### Legacy formatting
67+
68+
- `&a`
69+
- `&l`
70+
- `&n`
71+
- `&r`
72+
73+
### MiniMessage
74+
75+
When Adventure MiniMessage is present at runtime, standard MiniMessage tags can be mixed with Prismatic syntax in the same string.
76+
77+
## Formatting Pipeline
5578

56-
### 1. Get a legacy string
79+
PrismaticAPI processes text in this order:
80+
81+
1. MiniMessage, when the Adventure runtime is available.
82+
2. Prismatic multi-color blocks such as gradients and rainbows.
83+
3. Single RGB syntaxes.
84+
4. Legacy Bukkit formatting such as `&a`, `&l` and `&r`.
85+
86+
This lets MiniMessage and Prismatic tags coexist without forcing Adventure to be present on every runtime.
87+
88+
## API Overview
89+
90+
### `PrismaticAPI.legacy()`
91+
92+
`legacy()` returns `Formatter<String>`, which is always safe to use. It emits Bukkit/Bungee-compatible color-code strings.
5793

5894
```java
5995
String raw = "<g:ff0000>Hello</g:0000ff> &lworld";
60-
String formatted = PrismaticAPI.colorize(raw);
96+
String formatted = PrismaticAPI.legacy().colorize(player, raw);
6197
player.sendMessage(formatted);
6298
```
6399

64-
### 2. Format for a specific player
100+
### `PrismaticAPI.adventure()`
101+
102+
`adventure()` returns `Formatter<Component>` and uses the same Prismatic parser to build Adventure components.
103+
104+
Always guard this call when Adventure is optional:
65105

66106
```java
67-
String raw = "<rainbow:1>Chromatic</rainbow>";
68-
String formatted = PrismaticAPI.colorize(player, raw);
107+
if (PrismaticAPI.isAdventureAvailable()) {
108+
Component component = PrismaticAPI.adventure().colorize(player, "<#ff8800>PrismaticAPI");
109+
}
69110
```
70111

71-
When ViaVersion is installed, PrismaticAPI uses the player's effective version to decide whether RGB can be preserved or should be downsampled.
112+
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`.
113+
114+
### Top-level compatibility methods
72115

73-
### 3. Keep both component and legacy output
116+
The classic entry points still work:
74117

75118
```java
76-
RichText text = PrismaticAPI.colorizeText(player, "<#ff8800>PrismaticAPI");
119+
String formatted = PrismaticAPI.colorize(player, "<rainbow:1>Chromatic</rainbow>");
120+
String gradient = PrismaticAPI.applyGradient("Hello", Color.RED, Color.BLUE, false);
121+
```
77122

78-
player.sendMessage(text.asLegacy());
79-
Component component = text.component();
123+
These methods delegate to the `legacy()` facade.
124+
125+
## Important Behavior Notes
126+
127+
### `colorize(String)` is conservative
128+
129+
`PrismaticAPI.colorize(String)` and `PrismaticAPI.legacy().colorize(String)` call the formatter without a `Player` context.
130+
131+
That means PrismaticAPI cannot know whether the receiver supports hex colors, so it falls back to legacy-safe output.
132+
133+
If you want player-aware RGB preservation, call:
134+
135+
```java
136+
String formatted = PrismaticAPI.legacy().colorize(player, raw);
80137
```
81138

82-
### 4. Build colors programmatically
139+
If you want exact RGB output without a player capability check, use the explicit color methods with `legacy = false`:
83140

84141
```java
85-
String solid = PrismaticAPI.applyColor(new Color(255, 136, 0), "Hello", false);
86-
String gradient = PrismaticAPI.applyGradient("Hello", Color.RED, Color.BLUE, false);
87-
String rainbow = PrismaticAPI.applyRainbow("Hello", 1.0f, false);
142+
String solid = PrismaticAPI.legacy().applyColor(new Color(255, 136, 0), "Hello", false);
143+
String gradient = PrismaticAPI.legacy().applyGradient("Hello", Color.RED, Color.BLUE, false);
144+
String rainbow = PrismaticAPI.legacy().applyRainbow("Hello", 1.0f, false);
88145
```
89146

90-
## Useful API entry points
147+
### Adventure is optional
91148

92-
- `colorize(String)` returns a formatted legacy string
93-
- `colorize(Player, String)` returns a formatted legacy string tailored to that player
94-
- `colorizeText(...)` returns `RichText`
95-
- `applyColorText(...)`, `applyGradientText(...)`, and `applyRainbowText(...)` return `RichText`
96-
- `stripBukkit(...)`, `stripSpecial(...)`, `stripRGB(...)`, and `stripAll(...)` remove formatting in different levels
97-
- `getStartColor(...)` and `getEndColor(...)` inspect the formatted output
149+
PrismaticAPI can run perfectly fine without Adventure on the classpath as long as you stay on `legacy()` or the compatibility methods.
98150

99-
## MiniMessage behavior
151+
`PrismaticAPI.adventure()` requires these classes at runtime:
100152

101-
MiniMessage support is optional at runtime. If Adventure MiniMessage is available, PrismaticAPI will:
153+
- `net.kyori.adventure.text.Component`
154+
- `net.kyori.adventure.text.minimessage.MiniMessage`
155+
- `net.kyori.adventure.text.minimessage.tag.resolver.TagResolver`
156+
- `net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer`
102157

103-
- deserialize standard MiniMessage tags
104-
- preserve Prismatic gradient/rainbow sections by masking and restoring them safely
105-
- downsample RGB output to named colors when a legacy target requires it
158+
### MiniMessage support is shared
106159

107-
If MiniMessage is not present, the library still processes Prismatic formats and legacy codes normally.
160+
Both facades use the same parsing pipeline. If MiniMessage is available:
108161

109-
## Requirements
162+
- standard MiniMessage tags are deserialized first
163+
- Prismatic gradients and rainbows are preserved safely during MiniMessage parsing
164+
- output is downsampled when the target must remain legacy-safe
110165

111-
- Java 8+
112-
- Bukkit / Spigot / Paper API on the classpath
113-
- Adventure MiniMessage is optional
114-
- ViaVersion is optional
166+
If MiniMessage is not available, Prismatic-specific formatting and legacy color codes still work normally.
115167

116-
## Coordinates
168+
## Migration From 1.3.x
117169

118-
If you publish the artifact to your own repository or consume it from a local build, the coordinates are:
170+
### Before
119171

120-
```text
121-
groupId: me.croabeast
122-
artifactId: PrismaticAPI
123-
version: 1.3.0
172+
```java
173+
String legacy = PrismaticAPI.colorize(player, raw);
174+
RichText text = PrismaticAPI.colorizeText(player, raw);
175+
Component component = text.component();
176+
```
177+
178+
### After
179+
180+
```java
181+
String legacy = PrismaticAPI.colorize(player, raw);
182+
183+
if (PrismaticAPI.isAdventureAvailable()) {
184+
Component component = PrismaticAPI.adventure().colorize(player, raw);
185+
}
124186
```
125187

126-
## Local development
188+
Migration summary:
189+
190+
- Replace `RichText` usage with `PrismaticAPI.adventure()`.
191+
- Replace `colorizeText(...)` with `PrismaticAPI.adventure().colorize(...)`.
192+
- Replace `applyColorText(...)`, `applyGradientText(...)` and `applyRainbowText(...)` with the corresponding `adventure()` methods.
193+
- Keep existing legacy string code unchanged if you only need Bukkit-style strings.
194+
195+
## Useful Utility Methods
196+
197+
Both facades expose the same helper methods:
198+
199+
- `fromString(...)`
200+
- `stripBukkit(...)`
201+
- `stripSpecial(...)`
202+
- `stripRGB(...)`
203+
- `stripAll(...)`
204+
- `startsWithColor(...)`
205+
- `getStartColor(...)`
206+
- `getEndColor(...)`
207+
208+
These methods are useful for inspecting or cleaning already-formatted strings without duplicating parsing logic in downstream plugins.
209+
210+
## Local Development
127211

128212
This project expects the `VNC` project to exist either:
129213

130214
- next to this repository as `../VNC`
131215
- or inside this repository as `VNC`
132216

133-
The build automatically compiles the sibling `VNC` jar before compiling PrismaticAPI.
217+
The build compiles the sibling `VNC` jar before compiling PrismaticAPI.
134218

135219
## Build
136220

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group = "me.croabeast"
9-
version = "1.3.0"
9+
version = "1.4.0"
1010

1111
val vncProjectDir = listOf("../VNC", "VNC")
1212
.map(::file)

0 commit comments

Comments
 (0)