### Getting Started with MiniMessage
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/api.rst
A basic example demonstrating how to deserialize a MiniMessage string into a Component and send it to an Audience.
```APIDOC
## Getting Started with MiniMessage
### Description
MiniMessage exposes a simple API via the ``MiniMessage`` class. A standard instance of the serializer is available through the :java:`miniMessage()` method. This uses the default set of tags and is not in strict mode.
### Usage
```java
Audience player = ...;
var mm = MiniMessage.miniMessage();
Component parsed = mm.deserialize("Hello world, isn't MiniMessage fun?");
player.sendMessage(parsed);
```
```
--------------------------------
### BungeeCord ComponentBuilder Example
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/migration/bungeecord-chat-api.rst
Illustrates building a BungeeCord component with color and appended text.
```java
new ComponentBuilder("hello")
.color(ChatColor.GOLD)
.append(" world", FormatRetention.NONE)
.build()
```
--------------------------------
### Run Development Server
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/readme.md
Start the local development server to view the documentation and see changes in real-time. This command builds the HTML documentation and serves it locally.
```bash
pipenv run make livehtml
```
--------------------------------
### BungeeCord ComponentBuilder with Bold Example
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/migration/bungeecord-chat-api.rst
Shows how to build a BungeeCord component with color, bold styling, and appended text.
```java
new ComponentBuilder("hello")
.color(ChatColor.GOLD)
.bold(true)
.append(" world")
.build()
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/readme.md
Install all required Python libraries for the project using pipenv. This ensures the development environment is correctly set up.
```bash
pipenv install
```
--------------------------------
### Build Documentation on Windows
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/contributing.rst
Steps to build the documentation locally on Windows using poetry and make. Ensure Git and Python 3.12+ are installed. Pages will auto-refresh on change.
```powershell
poetry run ./make livehtml
```
--------------------------------
### Build Documentation on Linux/macOS
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/contributing.rst
Steps to build the documentation locally on Linux or macOS using poetry and make. Ensure Git and Python 3.12+ are installed. Pages will auto-refresh on change.
```bash
poetry run make livehtml
```
--------------------------------
### Create MiniMessage tag for PlaceholderAPI
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/faq.md
This example demonstrates how to create a custom MiniMessage tag resolver that allows the use of PlaceholderAPI placeholders within MiniMessage strings. The tag format is ``. Ensure PlaceholderAPI is installed and the player is valid.
```java
/**
* Creates a tag resolver capable of resolving PlaceholderAPI tags for a given player.
*
* @param player the player
* @return the tag resolver
*/
public @NotNull TagResolver papiTag(final @NotNull Player player) {
return TagResolver.resolver("papi", (argumentQueue, context) -> {
// Get the string placeholder that they want to use.
final String papiPlaceholder = argumentQueue.popOr("papi tag requires an argument").value();
// Then get PAPI to parse the placeholder for the given player.
final String parsedPlaceholder = PlaceholderAPI.setPlaceholders(player, '%' + papiPlaceholder + '%');
// We need to turn this ugly legacy string into a nice component.
final Component componentPlaceholder = LegacyComponentSerializer.legacySection().deserialize(parsedPlaceholder);
// Finally, return the tag instance to insert the placeholder!
return Tag.selfClosingInserting(componentPlaceholder);
});
}
```
--------------------------------
### Install Pipenv
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/readme.md
Install pipenv using your system's package manager. This is a prerequisite for managing project dependencies.
```bash
apt install pipenv
```
--------------------------------
### Create Styled Text Component
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/migration/bungeecord-chat-api.rst
Example of creating a styled text component using Adventure.
```java
Style style = Style.style(NamedTextColor.GOLD, TextDecoration.BOLD);
Component.text()
.append(Component.text("hello", style)
.append(Component.text(" world", style)))
.build()
```
--------------------------------
### BungeeCord ChatColor Example
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/migration/bungeecord-chat-api.rst
Demonstrates the concatenation of ChatColor codes for formatting messages in BungeeCord.
```java
player.sendMessage(ChatColor.GREEN + "Hi everyone, " + ChatColor.BOLD + "this message is in green and bold" + ChatColor.RESET + ChatColor.GREEN + "!");
```
--------------------------------
### SpongeAPI Plugin Setup with Guice
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/spongeapi.rst
Set up a SpongeAPI plugin using Guice dependency injection to obtain a SpongeAudiences instance. This instance can then be used to provide audiences for players or any MessageReceiver.
```java
@Plugin(/* [...] */)
public class MyPlugin {
private final SpongeAudiences adventure;
@Inject
MyPlugin(final SpongeAudiences adventure) {
this.adventure = adventure;
}
public @NonNull SpongeAudiences adventure() {
return this.adventure;
}
}
```
--------------------------------
### Initialize MinecraftServerAudiences (Java)
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/neoforge.rst
Set up the MinecraftServerAudiences instance within your @Mod-annotated class. This involves registering listeners for server start and stop events to manage the platform's lifecycle.
```java
@Mod("my_mod")
public class MyMod {
private volatile MinecraftServerAudiences adventure;
public MinecraftServerAudiences adventure() {
MinecraftServerAudiences ret = this.adventure;
if(ret == null) {
throw new IllegalStateException("Tried to access Adventure without a running server!");
}
return ret;
}
public MyMod() {
// Register with the server lifecycle callbacks
// This will ensure any platform data is cleared between game instances
// This is important on the integrated server, where multiple server instances
// can exist for one mod initialization.
NeoForge.EVENT_BUS.addListener((ServerStartingEvent e) -> this.platform = MinecraftServerAudiences.of(e.getServer()));
NeoForge.EVENT_BUS.addListener((ServerStoppedEvent e) -> this.platform = null);
}
}
```
--------------------------------
### Create a Custom Clickable Tag
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/dynamic-replacements.rst
Create a custom tag that makes its contents clickable by defining a TagResolver. This example creates a tag to get Javadocs of Adventure by a specified version.
```java
TagResolver.resolver("click-by-version", (args, context) -> {
final String version = args.popOr("version expected").value();
return Tag.styling(ClickEvent.openUrl("https://jd.advntr.dev/api/ " + version + "/"));
});
// creates a tag to get javadocs of adventure by the version:
```
--------------------------------
### Create an 'a' tag for links
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/api.rst
This example demonstrates how to create a custom 'a' tag that inserts a clickable link with specific styling. It requires the link as an argument and applies blue, underlined styling with hover text.
```java
Component aTagExample() {
final String input = "Hello, click me! but not me!";
final MiniMessage extendedInstance = MiniMessage.builder()
.editTags(b -> b.tag("a", MiniMessageTest::createA))
.build();
return extendedInstance.deserialize(input);
}
```
```java
static Tag createA(final ArgumentQueue args, final Context ctx) {
final String link = args.popOr("The tag requires exactly one argument, the link to open").value();
return Tag.styling(
NamedTextColor.BLUE,
TextDecoration.UNDERLINED,
ClickEvent.openUrl(link),
HoverEvent.showText(Component.text("Open " + link))
);
}
```
--------------------------------
### Register a command with custom argument types
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/fabric.rst
Register a command using Adventure's custom argument types for 'Key' and 'Component'. This example demonstrates an 'echo' command that repeats the provided message. Ensure Colonel_ mod is installed for vanilla client compatibility if using pre-1.19.
```java
// A potential method to be in the mod initializer class above
private static final String ARG_MESSAGE = "message";
void registerCommands(final CommandDispatcher dispatcher, final boolean isDedicated) {
dispatcher.register(literal("echo").then(argument(ARG_MESSAGE, component()).executes(ctx -> {
final Component message = component(ctx, ARG_MESSAGE);
ctx.getSource().sendMessage(Component.text("You said: ").append(message));
})))
}
```
--------------------------------
### Parse and Send Text with MiniMessage
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Demonstrates basic parsing of MiniMessage strings into Components and sending them to a player. Includes examples of colors, decorations, gradients, rainbows, click events, and hover events.
```java
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
MiniMessage mm = MiniMessage.miniMessage(); // default instance, all standard tags
// Parse and send
Component parsed = mm.deserialize(
"Hello world, isn't MiniMessage fun?"
);
player.sendMessage(parsed);
// Colors and decorations
player.sendMessage(mm.deserialize("Hello World!"));
player.sendMessage(mm.deserialize("This is important!"));
player.sendMessage(mm.deserialize("<#5e4fa2>Hex color support!#5e4fa2>"));
// Gradient and rainbow
player.sendMessage(mm.deserialize(
"Gradient text here"
));
player.sendMessage(mm.deserialize("||||||||||||||||||||"));
// Click and hover events
player.sendMessage(mm.deserialize(
"Click to show seed!"
));
player.sendMessage(mm.deserialize(
"This is a tooltip'>Hover over me!"
));
```
--------------------------------
### Get Client Audience (Java)
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/neoforge.rst
Obtain the MinecraftClientAudiences instance for client-side operations. This audience represents the client's player and is typically treated as a singleton.
```java
void doThing() {
// Get the audience
final Audience client = MinecraftClientAudiences.of().audience();
// Do something. This will only work when the player is ingame.
}
```
--------------------------------
### Create and Open a Book in Java
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/book.rst
Demonstrates how to construct a Book component with a title, author, and pages, and then open it for a target audience. Ensure all necessary components are created before assembling the Book.
```java
// Create and open a book about cats for the target audience
public void openMyBook(final @NonNull Audience target) {
Component bookTitle = Component.text("Encyclopedia of cats");
Component bookAuthor = Component.text("kashike");
Collection bookPages = Cats.getCatKnowledge();
Book myBook = Book.book(bookTitle, bookAuthor, bookPages);
target.openBook(myBook);
}
```
--------------------------------
### Initialize MinecraftServerAudiences
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/fabric.rst
Set up Adventure's server-side audience provider by registering it with server lifecycle events. This ensures proper initialization and cleanup between game instances.
```java
public class MyMod implements ModInitializer {
private volatile MinecraftServerAudiences adventure;
public MinecraftServerAudiences adventure() {
MinecraftServerAudiences ret = this.adventure;
if (ret == null) {
throw new IllegalStateException("Tried to access Adventure without a running server!");
}
return ret;
}
@Override
public void onInitialize() {
// Register with the server lifecycle callbacks
// This will ensure any platform data is cleared between game instances
// This is important on the integrated server, where multiple server instances
// can exist for one mod initialization.
ServerLifecycleEvents.SERVER_STARTING.register(server -> this.adventure = MinecraftServerAudiences.of(server));
ServerLifecycleEvents.SERVER_STOPPED.register(server -> this.adventure = null);
}
}
```
--------------------------------
### Create Custom Styling Tags
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/dynamic-replacements.rst
Demonstrates creating custom styling tags using Placeholder.styling with TextColor, HoverEvent, and ClickEvent.
```java
Placeholder.styling("fancy", TextColor.color(150, 200, 150)); // will replace the color between "" and ""
Placeholder.styling("myhover", HoverEvent.showText(Component.text("test"))); // will display your custom text as hover
Placeholder.styling("mycmd", ClickEvent.runCommand("/mycmd is cool")); // will create a clickable text which will run your specified command.
```
--------------------------------
### Show Simple Title
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/title.rst
Demonstrates how to create and display a basic title with main and subtitle components. Ensure the Audience object is available.
```java
public void showMyTitle(final @NonNull Audience target) {
final Component mainTitle = Component.text("This is the main title", NamedTextColor.WHITE);
final Component subtitle = Component.text("This is the subtitle", NamedTextColor.GRAY);
// Creates a simple title with the default values for fade-in, stay on screen and fade-out durations
final Title title = Title.title(mainTitle, subtitle);
// Send the title to your audience
target.showTitle(title);
}
```
--------------------------------
### Get and use client-side audience
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/fabric.rst
Obtain the client-side Adventure audience and send a message. This method should only be called when the player is ingame.
```java
void doThing() {
// Get the audience
final Audience client = MinecraftClientAudiences.of().audience();
// Do something. This will only work when the player is ingame.
client.sendMessage(Component.text("meow", NamedTextColor.DARK_PURPLE));
}
```
--------------------------------
### Inline MiniMessage Role
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/contributing.rst
The `:mm:` role inserts an inline code block with MiniMessage-highlighted text. Use this for short MiniMessage examples directly within prose.
```rst
:mm:`hello world`
```
--------------------------------
### Constructing and Displaying a Boss Bar
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/bossbar.rst
Shows how to create boss bars with different configurations (empty, half-filled, full) and display them to an audience. Also demonstrates how to store a boss bar to hide it later.
```java
private @Nullable BossBar activeBar;
public void showMyBossBar(final @NonNull Audience target) {
final Component name = Component.text("Awesome BossBar");
// Creates a red boss bar which has no progress and no notches
final BossBar emptyBar = BossBar.bossBar(name, 0, BossBar.Color.RED, BossBar.Overlay.PROGRESS);
// Creates a green boss bar which has 50% progress and 10 notches
final BossBar halfBar = BossBar.bossBar(name, 0.5f, BossBar.Color.GREEN, BossBar.Overlay.NOTCHED_10);
// etc..
final BossBar fullBar = BossBar.bossBar(name, 1, BossBar.Color.BLUE, BossBar.Overlay.NOTCHED_20);
// Send a bossbar to your audience
target.showBossBar(fullBar);
// Store it locally to be able to hide it manually later
this.activeBar = fullBar;
}
public void hideActiveBossBar(final @NonNull Audience target) {
target.hideBossBar(this.activeBar);
this.activeBar = null;
}
```
--------------------------------
### Create and Register a MessageFormat TranslationStore
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/localization.rst
Instantiate a TranslationStore for message formatting, register individual translations with specific locales, and add the store to the global translator.
```java
final TranslationStore myStore = TranslationStore.messageFormat(Key.key("mynamespace:mykey"));
myStore.register("mytranslation.key", Locale.US, new MessageFormat("Hello %s!", Locale.US));
GlobalTranslator.translator().addSource(myStore);
```
--------------------------------
### Query Audience Metadata
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Retrieve specific metadata about an Audience, such as their UUID or display name, using the get method. Provide a default component if the metadata is not present.
```java
// Query audience metadata via pointers
audience.get(Identity.UUID).ifPresent(uuid -> System.out.println("Player UUID: " + uuid));
Component displayName = audience.getOrDefault(Identity.DISPLAY_NAME,
Component.text("Unknown"));
```
--------------------------------
### Playing Sounds
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Demonstrates how to play built-in or custom sounds with various configurations and how to stop sounds selectively.
```APIDOC
## Sound — Playing Audio
The Sound API plays built-in Minecraft sounds or custom resource-pack sounds. Sounds have a source category (affects client volume sliders), volume radius, and pitch.
```java
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.sound.SoundStop;
// Built-in sound at standard volume/pitch
Sound disc = Sound.sound(Key.key("music_disc.13"), Sound.Source.MUSIC, 1f, 1f);
// Custom resource-pack sound with modified pitch
Sound custom = Sound.sound(Key.key("adventure", "rawr"), Sound.Source.AMBIENT, 1f, 1.1f);
// Play at the audience member's location
audience.playSound(disc);
// Play at an explicit world coordinate
audience.playSound(disc, 100, 64, 150);
// Play tracking the audience member's movement
audience.playSound(disc, Sound.Emitter.self());
// Play tracking a specific entity
audience.playSound(disc, someEntity);
// Stop sounds selectively
audience.stopSound(SoundStop.named(Key.key("music_disc.13"))); // one named sound
audience.stopSound(SoundStop.source(Sound.Source.WEATHER)); // all weather sounds
audience.stopSound(SoundStop.all()); // every sound
// Stop using the Sound object directly
audience.stopSound(disc); // convenience shortcut
```
```
--------------------------------
### Get Audience Identity Pointers in Java
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/audiences.rst
Retrieve the UUID or display name from an audience using the pointer system. Use getOrDefault for a fallback value if the pointer is not present.
```java
audience.get(Identity.UUID);
```
```java
audience.getOrDefault(Identity.DISPLAY_NAME, Component.text("no display name!"));
```
--------------------------------
### Constructing a Sound
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/sound.rst
Sounds are constructed using a key, sound source, volume, and pitch. Custom sounds from resource packs can be used.
```APIDOC
## Constructing a Sound
Sounds are composed of:
* A Key (also known as :java:`Identifier` or :java:`ResourceLocation`) that decides which sound to play. Any custom sounds from resource packs can be used. If a client does not know about sounds, it will ignore the sound (though a warning will be printed to the client log).
* A Sound source, used to tell the client what type of sound its hearing. The clients sound settings are also attributed to a source.
* A number, determining the radius where the sound can be heard
* A number from 0 to 2 determining the pitch the sound will be played at
**Examples:**
.. code:: java
// Create a built-in sound using standard volume and pitch
Sound musicDisc = Sound.sound(Key.key("music_disc.13"), Sound.Source.MUSIC, 1f, 1f);
// Create a sound from our resource pack with a higher pitch
Sound myCustomSound = Sound.sound(Key.key("adventure", "rawr"), Sound.Source.AMBIENT, 1f, 1.1f);
```
--------------------------------
### Create a Custom MiniMessage Translator
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/translator.rst
Extend MiniMessageTranslator and override getMiniMessageString to provide custom translations. This example hardcodes a translation for a specific key and locale, but you can fetch translations from various sources.
```java
public class MyMiniMessageTranslator extends MiniMessageTranslator {
public MyMiniMessageTranslator() {
// By default, the standard MiniMessage instance will be used.
// You can specify a custom one in the super constructor.
super(MiniMessage.miniMessage());
}
@Override
public @Nullable String getMiniMessageString(final @NotNull String key, final @NotNull Locale locale) {
// Creating a custom MiniMessage translator is as simple as overriding this one method.
// All you need to do is return a MiniMessage string for the provided key and locale.
// In this example we will hardcode this, but you could pull it from a resource bundle, a properties file, a config file or something else entirely.
if (key.equals("mykey") && locale == Locale.US) {
return "Hello, ! Today is ."
} else {
// Returning null "ignores" this translation.
return null;
}
}
}
```
--------------------------------
### Basic MiniMessage Formatting
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/index.rst
Demonstrates basic MiniMessage formatting with color, rainbow effect, and clickable links.
```mm
Hello world, isn't MiniMessage fun?
```
--------------------------------
### Display Keybinds
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/format.rst
Show the configured keybind for a specific action. Use the key tag followed by the keybind identifier.
```minimessage
Press to jump!
```
--------------------------------
### Using Placeholders with MiniMessage
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Shows how to use placeholders for dynamic content. Supports unparsed placeholders for safe user input and component placeholders for pre-built components or trusted markup.
```java
Component greeting = mm.deserialize(
"Hello !",
Placeholder.unparsed("name", userInputName), // sanitized
Placeholder.component("rank", rankComponent), // pre-built component
Placeholder.parsed("prefix", "[Admin]") // trusted markup
);
```
--------------------------------
### Customizing MiniMessage with Builder
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/api.rst
Demonstrates how to use the MiniMessage Builder to create a customized instance with specific tag resolvers.
```APIDOC
## Customizing MiniMessage with Builder
### Description
To make customizing MiniMessage easier, we provide a Builder. This allows for the registration of custom tag resolvers.
### Usage
```java
MiniMessage minimessage = MiniMessage.builder()
.tags(TagResolver.builder()
.resolver(StandardTags.color())
.resolver(StandardTags.decorations())
.resolver(this.someResolvers)
.build()
)
.build();
```
### Note
It's a good idea to initialize such a MiniMessage instance once, in a central location, and then use it for all your messages. Exception being if you want to customize MiniMessage based on permissions of a user.
```
--------------------------------
### Title
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Details on how to use the `Title` API to display full-screen titles and subtitles with customizable timing.
```APIDOC
## Title — Full-Screen Titles
`Title` displays large centered text (main title + subtitle) with configurable fade-in, on-screen, and fade-out durations.
```java
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.title.Title;
import java.time.Duration;
// Simple title with default timing
Title simple = Title.title(
Component.text("Welcome!", NamedTextColor.GOLD),
Component.text("Enjoy your stay", NamedTextColor.GRAY)
);
audience.showTitle(simple);
// Title with custom timing (fade-in 500 ms, stay 3 s, fade-out 1 s)
Title.Times times = Title.Times.times(
Duration.ofMillis(500),
Duration.ofMillis(3000),
Duration.ofMillis(1000)
);
Title timed = Title.title(
Component.text("Round Over!", NamedTextColor.RED),
Component.empty(),
times
);
audience.showTitle(timed);
// Clear the title immediately
audience.clearTitle();
// Reset title timing back to defaults
audience.resetTitle();
```
```
--------------------------------
### Construct Built-in and Custom Sounds
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/sound.rst
Create sounds using built-in keys or custom resource pack sounds. Specify sound source, volume, and pitch.
```java
Sound musicDisc = Sound.sound(Key.key("music_disc.13"), Sound.Source.MUSIC, 1f, 1f);
// Create a sound from our resource pack with a higher pitch
Sound myCustomSound = Sound.sound(Key.key("adventure", "rawr"), Sound.Source.AMBIENT, 1f, 1.1f);
```
--------------------------------
### Opening Written Books
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Shows how to create and open virtual written books to players, with each page represented as a Component.
```APIDOC
## Book — Openable Written Books
`Book` opens a virtual written book to the audience member without needing a physical book item. Each page is a `Component`.
```java
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import java.util.List;
Component title = Component.text("Encyclopedia of Cats");
Component author = Component.text("kashike");
List pages = List.of(
Component.text("Chapter 1: The Domestic Cat\n\nCats are small carnivorous mammals..."),
Component.text()
.content("Chapter 2: Cat Sounds\n\n")
.append(Component.text("Meow", NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" — standard greeting"))
.build(),
Component.text("Chapter 3: Cat Behaviour\n\nCats are obligate carnivores...")
);
Book book = Book.book(title, author, pages);
audience.openBook(book);
```
```
--------------------------------
### Add Maven Repository for Development Builds and Releases
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/modded.rst
Configure your build file to include repositories for both development snapshots and official releases of Adventure artifacts.
```groovy
repositories {
// for development builds
maven {
name = "sonatype-oss-snapshots1"
url = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
mavenContent { snapshotsOnly() }
}
// for releases
mavenCentral()
}
```
```kotlin
repositories {
// for development builds
maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/") {
name = "sonatype-oss-snapshots1"
mavenContent { snapshotsOnly() }
}
// for releases
mavenCentral()
}
```
--------------------------------
### Building a Restricted MiniMessage Instance
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Illustrates how to create a MiniMessage instance with a restricted set of allowed tags, such as only color and decoration tags.
```java
MiniMessage restricted = MiniMessage.builder()
.tags(TagResolver.builder()
.resolver(StandardTags.color())
.resolver(StandardTags.decorations())
.build()
)
.build();
```
--------------------------------
### Enabling Strict Mode and Debugging
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/api.rst
Explains how to enable strict mode for error handling and how to provide a debug consumer for parse failures.
```APIDOC
## Error Handling
### Description
By default, MiniMessage will never throw an exception caused by user input. Instead, it will treat any invalid tags as normal text. ``MiniMessage.Builder#strict(true)`` mode will enable strict mode, which throws exceptions on unclosed tags, but still will allow any improperly specified tags through.
To capture information on why a parse may have failed, ``MiniMessage.Builder#debug(Consumer)`` can be provided, which will accept debug logging for an input string.
### Usage
```java
// Enable strict mode
MiniMessage strictMiniMessage = MiniMessage.builder().strict(true).build();
// Enable debugging
MiniMessage debugMiniMessage = MiniMessage.builder()
.debug(errorMessage -> System.out.println("MiniMessage Debug: " + errorMessage))
.build();
```
```
--------------------------------
### Initialize and Close BukkitAudiences
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/bukkit.rst
Initialize a BukkitAudiences instance in onEnable and close it in onDisable to manage resources and ensure proper cleanup, especially for /reload.
```java
public class MyPlugin extends JavaPlugin {
private BukkitAudiences adventure;
public @NonNull BukkitAudiences adventure() {
if(this.adventure == null) {
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
}
return this.adventure;
}
@Override
public void onEnable() {
// Initialize an audiences instance for the plugin
this.adventure = BukkitAudiences.create(this);
// then do any other initialization
}
@Override
public void onDisable() {
if(this.adventure != null) {
this.adventure.close();
this.adventure = null;
}
}
}
```
--------------------------------
### Configure Maven Repository for Snapshots
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/getting-started.rst
Add the Sonatype OSS Snapshots repository to your Maven configuration to use snapshot builds.
```xml
sonatype-oss-snapshots1
https://s01.oss.sonatype.org/content/repositories/snapshots/
```
--------------------------------
### Component Serialization (JSON/Gson)
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Details how to serialize and deserialize Adventure Components to and from JSON strings using Gson.
```APIDOC
### JSON / Gson Serializer
```java
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
//Gson serializer — full 1.16+ RGB + hover format
GsonComponentSerializer gson = GsonComponentSerializer.gson();
// Serialize component → JSON string
String json = gson.serialize(
Component.text("Hello world!", NamedTextColor.LIGHT_PURPLE)
);
// → {"text":"Hello world!","color":"light_purple"}
// Deserialize JSON string → component
Component comp = gson.deserialize(json);
// Legacy-compatible serializer — downsamplings RGB, compatible with <1.16 clients
GsonComponentSerializer legacyGson = GsonComponentSerializer.colorDownsamplingGson();
// Generic JSON interface (useful when the backing JSON library may vary)
String jsonText = JSONComponentSerializer.json()
.serialize(Component.text("Hello world", NamedTextColor.LIGHT_PURPLE));
Component fromJson = JSONComponentSerializer.json().deserialize(jsonText);
```
```
--------------------------------
### Adventure ComponentBuilder Equivalent
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/migration/bungeecord-chat-api.rst
Provides the Adventure equivalent for building a component with color and appended text.
```java
Component.text()
.append(Component.text("hello", NamedTextColor.GOLD)
.append(Component.text(" world"))
.build()
```
--------------------------------
### Add NeoForge Repository (Gradle Kotlin)
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/neoforge.rst
Configure your Kotlin Gradle build to include the Sonatype OSS snapshots repository for development builds and Maven Central for releases.
```kotlin
repositories {
// for development builds
maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/") {
name = "sonatype-oss-snapshots1"
mavenContent { snapshotsOnly() }
}
// for releases
mavenCentral()
}
```
--------------------------------
### Add NeoForge Repository (Gradle Groovy)
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/neoforge.rst
Configure your Gradle build to include the Sonatype OSS snapshots repository for development builds and Maven Central for releases.
```groovy
repositories {
// for development builds
maven {
name = "sonatype-oss-snapshots1"
url = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
mavenContent { snapshotsOnly() }
}
// for releases
mavenCentral()
}
```
--------------------------------
### Open Virtual Books with Adventure API
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
The Book API allows opening a virtual written book to an audience member. Each page must be a Component. Configure title, author, and pages to create the book.
```java
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import java.util.List;
Component title = Component.text("Encyclopedia of Cats");
Component author = Component.text("kashike");
List pages = List.of(
Component.text("Chapter 1: The Domestic Cat\n\nCats are small carnivorous mammals..."),
Component.text()
.content("Chapter 2: Cat Sounds\n\n")
.append(Component.text("Meow", NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" — standard greeting"))
.build(),
Component.text("Chapter 3: Cat Behaviour\n\nCats are obligate carnivores...")
);
Book book = Book.book(title, author, pages);
audience.openBook(book);
```
--------------------------------
### Send an Optional Resource Pack
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/resource-pack.rst
Use this to send a single, optional resource pack to a target audience. The client can choose whether to accept it.
```java
public void sendOptionalResourcePack(final @NonNull Audience target) {
final ResourcePackRequest request = ResourcePackRequest.resourcePackRequest()
.packs(PACK_INFO)
.prompt(Component.text("Please download the resource pack!"))
.required(false)
.build();
// Send the resource pack request to the target audience
target.sendResourcePacks(request);
}
```
--------------------------------
### Serializing Component to MiniMessage String
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Shows how to convert an Adventure Component back into its MiniMessage string representation.
```java
String serialized = mm.serialize(Component.text("Hello", NamedTextColor.RED));
// → "Hello"
```
--------------------------------
### MiniMessage Dynamic Replacements
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Demonstrates how to use Placeholder and Formatter resolvers to inject dynamic runtime values into MiniMessage templates.
```APIDOC
## MiniMessage Dynamic Replacements — Placeholders and Formatters
MiniMessage's `Placeholder` and `Formatter` resolvers let you inject dynamic runtime values — strings, components, numbers, dates, and conditional choices — into MiniMessage templates safely and efficiently.
```java
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Formatter;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import java.time.LocalDateTime;
import java.time.ZoneId;
MiniMessage mm = MiniMessage.miniMessage();
// Component placeholder (pre-built Component)
mm.deserialize("Hello :)",
Placeholder.component("name", Component.text("TEST", NamedTextColor.RED)));
// Unparsed placeholder — user input is NOT parsed as MiniMessage tags
mm.deserialize("Hello ",
Placeholder.unparsed("name", "TEST :)")); // renders literally
// Parsed placeholder — content IS parsed; styles can bleed through
mm.deserialize("Hello :)",
Placeholder.parsed("name", "TEST"));
// result: "Hello " (gray) + "TEST :)" (red)
// Styling placeholder — applies a reusable style to a range of text
mm.deserialize("Hello :) How are you?",
Placeholder.styling("my-style",
ClickEvent.suggestCommand("/say hello"),
NamedTextColor.RED,
TextDecoration.BOLD));
// Number formatter with locale and format pattern
mm.deserialize("Balance: #.00;-#.00'>",
Formatter.number("amount", 1234.56));
// Date formatter
mm.deserialize("Current time: ",
Formatter.date("ts", LocalDateTime.now(ZoneId.systemDefault())));
// Choice formatter — pluralization
mm.deserialize("You met !",
Formatter.choice("c", 5));
// result: "You met many developers!"
// Custom tag resolver — dynamically versioned Javadoc links
TagResolver versionedJavadoc = TagResolver.resolver("jd", (args, ctx) -> {
String version = args.popOr("version argument required").value();
return Tag.styling(ClickEvent.openUrl("https://jd.advntr.dev/api/" + version + "/"));
});
MiniMessage extended = MiniMessage.builder()
.editTags(b -> b.resolver(versionedJavadoc))
.build();
extended.deserialize("View Javadocs");
```
```
--------------------------------
### Apply Decorations
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/format.rst
Decorate text with styles like bold, italic, strikethrough, underlined, or obfuscated. Use aliases for brevity or prepend with '!' to invert the decoration.
```minimessage
This is important!
```
--------------------------------
### Creating a Strict MiniMessage Instance
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Demonstrates how to configure MiniMessage to throw an exception when encountering unclosed tags, enforcing stricter parsing rules.
```java
MiniMessage strict = MiniMessage.builder().strict(true).build();
```
--------------------------------
### Color Transitions
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/format.rst
Use the `` tag for text that transitions between specified colors. The phase parameter controls the color progression.
```minimessage
|||||||||
```
```minimessage
Hello world [phase]
```
--------------------------------
### Configure Gradle Kotlin Repository for Snapshots
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/getting-started.rst
Add the Sonatype OSS Snapshots repository to your Gradle (Kotlin) build script to use snapshot builds.
```kotlin
repositories {
maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/") {
name = "sonatype-oss-snapshots"
}
}
```
--------------------------------
### Create Sound Stop from Sound Object
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/sound.rst
Generate a SoundStop object directly from a Sound instance to stop that specific sound.
```java
// Get a sound stop that will stop a specific sound
mySound.asStop();
```
--------------------------------
### Create and Manage BossBars
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Create BossBars with custom text, progress, color, and overlay. BossBars are mutable and update in real-time when shown to an audience. Use showBossBar and hideBossBar to manage their visibility.
```java
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
// Create boss bars with different configurations
BossBar emptyBar = BossBar.bossBar(
Component.text("Awaiting Players"),
0f,
BossBar.Color.RED,
BossBar.Overlay.PROGRESS
);
BossBar halfBar = BossBar.bossBar(
Component.text("Arena Battle"),
0.5f,
BossBar.Color.GREEN,
BossBar.Overlay.NOTCHED_10
);
BossBar fullBar = BossBar.bossBar(
Component.text("Boss: Dragon"),
1f,
BossBar.Color.PURPLE,
BossBar.Overlay.NOTCHED_20
);
// Show/hide to an audience
audience.showBossBar(fullBar);
audience.hideBossBar(fullBar); // removes it from the screen
// Mutate an active bar — updates in real time, no manual refresh needed
fullBar.name(Component.text("Boss: Dragon (Enraged!)", NamedTextColor.RED));
fullBar.progress(0.3f); // 30 % health remaining
fullBar.color(BossBar.Color.RED); // bar turns red
fullBar.overlay(BossBar.Overlay.NOTCHED_6);
```
--------------------------------
### Tab List Header and Footer
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Explains how to send and update the player list header and footer using Component objects.
```APIDOC
## Tab List — Header and Footer
`Audience` methods update the player-list header (shown above player names) and footer (shown below).
```java
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
// Set both header and footer together
Component header = Component.text("My Cool Server", NamedTextColor.BLUE);
Component footer = Component.text("players.mycoolserver.net", NamedTextColor.GRAY);
audience.sendPlayerListHeaderAndFooter(header, footer);
// Update only the footer (e.g., every second for a live clock)
audience.sendPlayerListFooter(Component.text("TPS: 20 | Players: 42"));
// Clear both
audience.sendPlayerListHeaderAndFooter(Component.empty(), Component.empty());
```
```
--------------------------------
### Click Event Actions
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/format.rst
Create clickable text that triggers actions like running a command or copying text to the clipboard. The action type and its corresponding value are specified.
```minimessage
Click to show the world seed!
```
```minimessage
Click this to copy your score!
```
--------------------------------
### Declare Dependency with Gradle (Kotlin)
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/shared/dependency.rst
Use this snippet in your Gradle build script (build.gradle.kts) for Kotlin projects. It sets up repositories and declares the dependency. Remember to substitute '|artifact|' and '|version|'.
```kotlin
repositories {
mavenCentral()
}
dependencies {
implementation("net.kyori:|artifact|:|version|")
}
```
--------------------------------
### Custom MiniMessage Builder with Tag Resolvers
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/minimessage/api.rst
Initialize a MiniMessage instance with custom tag resolvers for specific formatting. It's recommended to create one instance and reuse it.
```java
MiniMessage minimessage = MiniMessage.builder()
.tags(TagResolver.builder()
.resolver(StandardTags.color())
.resolver(StandardTags.decorations())
.resolver(this.someResolvers)
.build()
)
.build();
```
--------------------------------
### Create a Text Component with Appended Elements
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/text.rst
Constructs a chat component with mixed text, a colored word, a keybind, and styling. Use this for dynamic chat messages.
```java
final TextComponent textComponent = Component.text("You're a ")
.color(TextColor.color(0x443344))
.append(Component.text("Bunny", NamedTextColor.LIGHT_PURPLE))
.append(Component.text("! Press "))
.append(
Component.keybind("key.jump")
.color(NamedTextColor.LIGHT_PURPLE)
.decoration(TextDecoration.BOLD, true)
)
.append(Component.text(" to jump!"));
```
--------------------------------
### Initialize BungeeAudiences
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/bungeecord.rst
Obtain a BungeeAudiences instance using BungeeAudiences.create(plugin). This object is thread-safe and must be closed when the plugin is disabled.
```java
public class MyPlugin extends Plugin {
private BungeeAudiences adventure;
public @NonNull BungeeAudiences adventure() {
if(this.adventure == null) {
throw new IllegalStateException("Cannot retrieve audience provider while plugin is not enabled");
}
return this.adventure;
}
@Override
public void onEnable() {
this.adventure = BungeeAudiences.create(this);
}
@Override
public void onDisable() {
if(this.adventure != null) {
this.adventure.close();
this.adventure = null;
}
}
}
```
--------------------------------
### Register Echo Command with Component Argument in Java
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/platform/modded.rst
Shows how to register a simple 'echo' command in a modded environment using Brigadier. It utilizes a custom 'component' argument type to accept chat components as input.
```java
// A potential method to be in the mod initializer class above
private static final String ARG_MESSAGE = "message";
void registerCommands(final CommandDispatcher dispatcher, final boolean isDedicated) {
dispatcher.register(literal("echo").then(argument(ARG_MESSAGE, component()).executes(ctx -> {
final Component message = component(ctx, ARG_MESSAGE);
((Audience) ctx.getSource()).sendMessage(Component.text("You said: ").append(message));
})))
}
```
--------------------------------
### Play Sounds with Adventure API
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Use the Sound API to play built-in or custom sounds. Specify sound category, volume, pitch, and location. Sounds can be played at the audience's location, world coordinates, or attached to entities. Use SoundStop to selectively stop sounds.
```java
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.sound.SoundStop;
// Built-in sound at standard volume/pitch
Sound disc = Sound.sound(Key.key("music_disc.13"), Sound.Source.MUSIC, 1f, 1f);
// Custom resource-pack sound with modified pitch
Sound custom = Sound.sound(Key.key("adventure", "rawr"), Sound.Source.AMBIENT, 1f, 1.1f);
// Play at the audience member's location
audience.playSound(disc);
// Play at an explicit world coordinate
audience.playSound(disc, 100, 64, 150);
// Play tracking the audience member's movement
audience.playSound(disc, Sound.Emitter.self());
// Play tracking a specific entity
audience.playSound(disc, someEntity);
// Stop sounds selectively
audience.stopSound(SoundStop.named(Key.key("music_disc.13"))); // one named sound
audience.stopSound(SoundStop.source(Sound.Source.WEATHER)); // all weather sounds
audience.stopSound(SoundStop.all()); // every sound
// Stop using the Sound object directly
audience.stopSound(disc); // convenience shortcut
```
--------------------------------
### Create a Text Component using a Builder
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/text.rst
Builds a chat component using a mutable builder pattern, allowing for step-by-step construction of complex messages. This is an alternative to direct chaining.
```java
final TextComponent textComponent2 = Component.text()
.content("You're a ")
.color(TextColor.color(0x443344))
.append(Component.text().content("Bunny").color(NamedTextColor.LIGHT_PURPLE))
.append(Component.text("! Press "))
.append(
Component.keybind().keybind("key.jump")
.color(NamedTextColor.LIGHT_PURPLE)
.decoration(TextDecoration.BOLD, true)
.build()
)
.append(Component.text(" to jump!"))
.build();
```
--------------------------------
### Create Translatable Components
Source: https://context7.com/kyoripowered/adventure-docs/llms.txt
Generate translatable components for text that should be rendered in the player's client language. This is useful for game messages and item names.
```java
// Translatable component (rendered in the player's client language)
Component diamond = Component.translatable("block.minecraft.diamond_block");
Component namedHead = Component.translatable("block.minecraft.player_head.named",
Component.text("Alice"));
```
--------------------------------
### Add Adventure API Dependency
Source: https://github.com/kyoripowered/adventure-docs/blob/main/4/source/getting-started.rst
Add the Adventure API dependency to your project. This is the core library for using Adventure.
```xml
net.kyori
adventure-api
4.3.0
compile
```