Adventure
Keystone bundles Adventure so it works on Spigot. Whether you take that copy is your choice, and the two options are mutually exclusive.
Cross-platform, the default
Adventure is shaded and relocated with Keystone. Your components are a different type from the server's, so all text goes through MessageService and LegacyRenderer, never player.sendMessage(Component).
Take this one if you target Spigot and your plugin's text never leaves your own code.
Paper-only
Exclude net.kyori from keystone-core and override the parent's relocations to drop the Adventure entry:
<dependency>
<groupId>dev.bwmp</groupId>
<artifactId>keystone-core</artifactId>
<exclusions>
<exclusion><groupId>net.kyori</groupId><artifactId>*</artifactId></exclusion>
</exclusions>
</dependency>
<relocations combine.self="override">
<relocation>
<pattern>dev.bwmp.keystone.</pattern>
<shadedPattern>${keystone.libs.package}.keystone.</shadedPattern>
</relocation>
<!-- Keep this relocation when using keystone-metrics. -->
<relocation>
<pattern>org.bstats.</pattern>
<shadedPattern>${keystone.libs.package}.bstats.</shadedPattern>
</relocation>
</relocations>
Keystone detects which situation it is in at runtime and sends natively rather than through BukkitAudiences.
Which one
Take the Paper-only build if either is true:
- You hand components straight to Paper APIs.
- You publish an API that exposes
Componenton its own surface.
HoloPanels is the worked example. Its renderer hands components straight to Paper's display APIs and holopanels-api exposes Component, so it is the Paper-only build, and CI asserts the jar contains no kyori classes for exactly that reason.
Sigil is the other case: it targets Spigot as well, and its API deliberately crosses the boundary as MiniMessage strings rather than components, so it takes the shaded copy.
Verify the choice against the final shaded jar. A Paper-only artifact should contain no relocated
kyori classes; a cross-platform artifact must not expose its relocated Adventure types through a
public addon API. Compile and run a small external consumer whenever that boundary changes.