Skip to content

Player bossbar

PlayerBossbar is a thin wrapper over vanilla ServerBossEvent. One PlayerBossbar instance is a single named bar (e.g. “round-timer”) shared across a lobby; the methods own a per-player map so you can attach, setProgress, setColor, and removeAll without juggling boss-event instances yourself.

  • You want a per-player round timer that shrinks as the round progresses.
  • You want a celebration-phase bar that counts down to the next round.
  • You’re tracking a per-player HUD value that fits a 0..1 progress bar.
package me.zlex.conduit.bossbar;
public final class PlayerBossbar {
public void attach(ServerPlayer player, Component name, float progress,
BossEvent.BossBarColor color);
public void attach(ServerPlayer player, Component name, float progress,
BossEvent.BossBarColor color, BossEvent.BossBarOverlay overlay);
public void setName(ServerPlayer player, Component name);
public void setProgress(ServerPlayer player, float progress);
public void setColor(ServerPlayer player, BossEvent.BossBarColor color);
public @Nullable ServerBossEvent get(ServerPlayer player);
public void remove(ServerPlayer player);
public void removeAll();
}

Progress is clamped to [0, 1] automatically.

import me.zlex.conduit.bossbar.PlayerBossbar;
import net.minecraft.network.chat.Component;
import net.minecraft.world.BossEvent;
public final class SprintRaceHud {
private static final PlayerBossbar TIMER = new PlayerBossbar();
private static final int ROUND_SECONDS = 60;
public static void onRoundStart(Collection<ServerPlayer> players) {
for (ServerPlayer p : players) {
TIMER.attach(p, Component.literal("Race — 60s"),
1.0f, BossEvent.BossBarColor.GREEN);
}
}
public static void onSecondTick(Collection<ServerPlayer> players, int elapsed) {
float fraction = 1f - (elapsed / (float) ROUND_SECONDS);
for (ServerPlayer p : players) {
TIMER.setProgress(p, fraction);
TIMER.setName(p, Component.literal("Race — " + (ROUND_SECONDS - elapsed) + "s"));
if (fraction < 0.25f) TIMER.setColor(p, BossEvent.BossBarColor.RED);
else if (fraction < 0.5f) TIMER.setColor(p, BossEvent.BossBarColor.YELLOW);
}
}
public static void onRoundEnd() {
TIMER.removeAll();
}
}
  • Always call removeAll at end-of-round so the internal map doesn’t grow.
  • Players who disconnect are pruned by vanilla — the underlying ServerBossEvent drops them automatically.
  • attach replaces any existing bar this instance owned for that player — calling it twice doesn’t stack bars.