Documentation Index
Fetch the complete documentation index at: https://mintlify.com/xMrAfonso/Runway/llms.txt
Use this file to discover all available pages before exploring further.
The ScoreboardListener intercepts scoreboard-related packets to format objective titles and score entry text. This enables sidebar scoreboards to use MiniMessage formatting and placeholders for dynamic, per-player content.
Packet Types
Intercepts three packet types:
PacketType.Play.Server.SCOREBOARD_OBJECTIVE - Scoreboard objective creation/update
PacketType.Play.Server.UPDATE_SCORE - Individual score entry updates
PacketType.Play.Server.DISPLAY_SCOREBOARD - Scoreboard display position changes
Configuration
listeners:
scoreboards: true
When disabled, scoreboard packets are sent unmodified to the client.
Class Structure
public class ScoreboardListener extends AbstractListener {
public ScoreboardListener(ProcessHandler processHandler, ConfigManager configManager) {
super(processHandler, configManager);
}
@Override
public void onPacketPlaySend(PacketPlaySendEvent e) {
// Implementation
}
}
Source: ScoreboardListener.java:13-44
Implementation Details
1. Packet Type Validation
PacketTypeCommon type = e.getPacketType();
if (!config.getOrDefault("listeners.scoreboards", true) || (
type != PacketType.Play.Server.SCOREBOARD_OBJECTIVE &&
type != PacketType.Play.Server.UPDATE_SCORE) &&
type != PacketType.Play.Server.DISPLAY_SCOREBOARD) {
return;
}
Source: ScoreboardListener.java:20-27
The listener exits early if:
- The listener is disabled in the configuration
- The packet type doesn’t match any of the three scoreboard packet types
2. Objective Title Processing
Player player = e.getPlayer();
if (type == PacketType.Play.Server.SCOREBOARD_OBJECTIVE) {
WrapperPlayServerScoreboardObjective packet = new WrapperPlayServerScoreboardObjective(e);
packet.setDisplayName(handler.processComponent(packet.getDisplayName(), player));
}
Source: ScoreboardListener.java:29-34
When a scoreboard objective is created or updated:
- Wraps the packet in
WrapperPlayServerScoreboardObjective
- Extracts the display name (objective title)
- Processes it through
ProcessHandler
- Sets the formatted display name back to the packet
3. Display Scoreboard Handling
else if (type == PacketType.Play.Server.DISPLAY_SCOREBOARD) {
WrapperPlayServerDisplayScoreboard packet = new WrapperPlayServerDisplayScoreboard(e);
packet.setScoreName("testing");
}
Source: ScoreboardListener.java:35-38
This implementation sets a hardcoded score name “testing”. This appears to be debug code and may need refinement for production use.
4. Score Entry Processing
else {
WrapperPlayServerUpdateScore packet = new WrapperPlayServerUpdateScore(e);
packet.setEntityDisplayName(handler.processComponent(packet.getEntityDisplayName(), player));
}
Source: ScoreboardListener.java:39-42
When a score entry is updated:
- Wraps the packet in
WrapperPlayServerUpdateScore
- Extracts the entity display name (score line text)
- Processes it through
ProcessHandler
- Sets the formatted display name back to the packet
Usage Example
When creating a scoreboard:
Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
Objective objective = scoreboard.registerNewObjective(
"sidebar",
"dummy",
Component.text("<gradient:gold:yellow>Server Stats</gradient>")
);
Score playerScore = objective.getScore("<green>Players: %server_online%");
playerScore.setScore(1);
Score balanceScore = objective.getScore("<yellow>Balance: $%player_balance%");
balanceScore.setScore(2);
player.setScoreboard(scoreboard);
The listener will:
- Objective Title: Process the gradient formatting for “Server Stats”
- Score Entries:
- Resolve
%server_online% placeholder
- Resolve per-player
%player_balance% placeholder
- Apply color codes (
<green>, <yellow>)
Result:
- Title displays with a gold-to-yellow gradient
- Each player sees personalized balance
- Player count is shared across all players
Processing Flow
Objective Creation
Score Updates
Objective Registered
Server sends SCOREBOARD_OBJECTIVE packet
Interception
ScoreboardListener intercepts the packet
Title Extraction
Extracts the objective display name
Processing
Resolves placeholders and MiniMessage formatting
Update
Sets formatted title back to the packet
Display
Scoreboard title appears on player’s screen
Score Changed
Server sends UPDATE_SCORE packet
Interception
ScoreboardListener intercepts the packet
Text Extraction
Extracts the score entry display name
Processing
Resolves placeholders and formatting
Update
Sets formatted text back to the packet
Display
Score line updates on the scoreboard
Per-Player Scoreboards
Since processing includes the player parameter, each player can see personalized scoreboards:
Objective objective = scoreboard.registerNewObjective(
"stats",
"dummy",
Component.text("<rainbow>%player_name%'s Stats</rainbow>")
);
Score rank = objective.getScore("Rank: <gold>%player_rank%</gold>");
Score kills = objective.getScore("Kills: <red>%player_kills%</red>");
Score deaths = objective.getScore("Deaths: <gray>%player_deaths%</gray>");
Each player sees their own:
- Name in the title
- Rank, kills, and death count
- Personalized statistics
Team-Based Scoreboards
The listener processes display names for score entries, which are often used with team-based scoreboard implementations where teams control line text formatting.
Many scoreboard libraries use teams to create dynamic scoreboards. This listener ensures that team-based score entries are properly formatted with placeholders and MiniMessage syntax.
Dependencies
- PacketEvents: For packet interception
- WrapperPlayServerScoreboardObjective: Packet wrapper for objective packets
- WrapperPlayServerUpdateScore: Packet wrapper for score update packets
- WrapperPlayServerDisplayScoreboard: Packet wrapper for display position packets
- ProcessHandler: For placeholder resolution and formatting
Common Use Cases
-
Server Information Boards
- Display player count, TPS, server stats
- Show server IP or website
- Real-time status indicators
-
Player Statistics
- Personal stats like kills, deaths, playtime
- Economy balance and rank
- Level and experience progress
-
Game Information
- Match timers and scores
- Team information
- Objective progress
-
Dynamic Content
- Rotating tips or announcements
- Event countdowns
- Leaderboards