Chat Events
The chat event has evolved a few times over the years.
This guide will explain how to properly use the new AsyncChatEvent
and its ChatRenderer.
The AsyncChatEvent
is an improved version of the old AsyncPlayerChatEvent
that allows you to render chat messages individually for each player.
AsyncChatEvent vs ChatEventThe key difference between AsyncChatEvent
and ChatEvent is that
AsyncChatEvent is fired asynchronously.
This means that it does not block the main thread and sends the chat message when the listener has completed.
Be aware that using the Bukkit API in an asynchronous context (i.e. the event handler) is unsafe and exceptions may be thrown.
If you need to use the Bukkit API, you can use ChatEvent.
However, we recommend using BukkitScheduler.
Understanding the renderer
Before we can start using the new chat event, we need to understand how the new renderer works.
The renderer is Paper's way of allowing plugins to modify the chat message before it is sent to the player.
This is done by using the ChatRenderer interface with its
render
method. Previously, this was done by using the AsyncPlayerChatEvent
with its setFormat method.
public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) {
// ...
}
- The
rendermethod is called when a chat message is sent to the player. - The
sourceparameter is the player that sent the message. - The
sourceDisplayNameparameter is the display name of the player that sent the message. - The
messageparameter is the message that was sent. - The
viewerparameter is the player that is receiving the message.
ChatRenderer.ViewerUnawareIf your renderer does not need to know about the viewer, you can use the
ChatRenderer.ViewerUnaware
interface instead of the ChatRenderer interface.
This will benefit performance as the message will only be rendered once instead of each individual player.
Using the renderer
There are two ways to use the renderer.
- Implementing the
ChatRendererinterface in a class. - Using a lambda expression.
Depending on the complexity of your renderer, you may want to use one or the other.
Implementing the ChatRenderer interface
The first way of using the renderer is by implementing the ChatRenderer
interface in a class. In this example, we will be using our ChatListener class.
Next, we need to tell the event to use the renderer by using the
renderer method.
public class ChatListener implements Listener, ChatRenderer { // Implement the ChatRenderer and Listener interface
// Listen for the AsyncChatEvent
@EventHandler
public void onChat(AsyncChatEvent event) {
event.renderer(this); // Tell the event to use our renderer
}
// Override the render method
@Override
public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) {
// ...
}
}
If you decide to create a separate class for your renderer, it is important to know that you don't need to instantiate the class every time the event is called. In this case, you can use the singleton pattern to create a single instance of the class.
Using a lambda expression
Another way of using the renderer is by using a lambda expression.
public class ChatListener implements Listener {
@EventHandler
public void onChat(AsyncChatEvent event) {
event.renderer((source, sourceDisplayName, message, viewer) -> {
// ...
});
}
}
Rendering the message
Now that we have our renderer, we can start rendering the message.
Let's say we want to render our chat to look like this:
![]()
To do this, we need to return a new Component that contains the message we want to send.
public class ChatListener implements Listener, ChatRenderer {
// Listener logic
@Override
public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) {
return sourceDisplayName
.append(Component.text(": "))
.append(message);
}
}
Now you can see that the message is rendered as we wanted it to be.
Conclusion
That is all you need to know about the new chat event and its renderer. Of course there are many more things you can do with components in general. If you want to learn more about components, you can read the Component Documentation.