Boss bars

Show a boss bar at the top of players' screens and drive its progress.

A boss bar is the coloured bar that stretches across the top of the screen - the one you see while fighting the Ender Dragon. It carries a title, a colour, a segment style, and a progress value from 0.0 to 1.0, and you choose which players see it. It's the natural fit for anything time-based or global: an event countdown, a raid timer, a server-wide objective.

Create and show a bar

Ask the server for a bar, then attach the players who should see it. A bar with no players attached simply isn't drawn:

src/endstone_my_plugin/my_plugin.py
from endstone.boss import BarColor, BarStyle

bar = self.server.create_boss_bar("Event starting", BarColor.BLUE, BarStyle.SOLID)
bar.add_player(player)

create_boss_bar starts the bar full (progress = 1.0). BarColor covers the eight client colours; BarStyle is either SOLID or one of the SEGMENTED_6 / _10 / _12 / _20 notched styles.

Drive the progress

The bar earns its keep when you update it over time. Hold onto the instance and change progress, title, or color from a scheduled task. This plugin runs a ten-second countdown, draining the bar one tick at a time and flipping it when time's up:

src/endstone_my_plugin/my_plugin.py
from endstone.boss import BarColor, BarFlag, BarStyle
from endstone.event import event_handler, PlayerJoinEvent
from endstone.plugin import Plugin

class MyPlugin(Plugin):
    api_version = "0.11"

    TOTAL = 200  # ticks, about ten seconds

    def on_enable(self) -> None:
        self.bar = self.server.create_boss_bar("Raid in 10s", BarColor.RED, BarStyle.SEGMENTED_10)
        self.bar.add_flag(BarFlag.DARKEN_SKY)  # dim the sky like a real boss fight
        for player in self.server.online_players:
            self.bar.add_player(player)

        self.remaining = self.TOTAL
        self.task = self.server.scheduler.run_task(self, self.countdown, delay=0, period=1)
        self.register_events(self)

    @event_handler
    def on_player_join(self, event: PlayerJoinEvent) -> None:
        self.bar.add_player(event.player)  # late joiners see it too

    def countdown(self) -> None:
        self.remaining -= 1
        self.bar.progress = max(self.remaining / self.TOTAL, 0.0)
        if self.remaining <= 0:
            self.bar.title = "Raid!"
            self.bar.color = BarColor.PURPLE
            self.task.cancel()

    def on_disable(self) -> None:
        self.bar.remove_all()

A few details worth knowing:

  • progress is clamped to [0.0, 1.0] - a value outside that range raises ValueError, so clamp it yourself as the example does.
  • Flags add atmosphere. BarFlag.DARKEN_SKY darkens the sky and BarFlag.CREATE_FOG rolls in fog; add and remove them with add_flag / remove_flag.
  • Attachment is per player. add_player and remove_player control exactly who sees the bar; remove_all clears everyone, which is the tidy thing to do in on_disable. You can also hide a bar from all its viewers without detaching them by setting is_visible = False.

A bar per player

The example above shares one bar across everyone. For a value that differs per player - personal stamina, a quest timer - create a separate bar for each and keep them in a dict keyed by the player's unique_id, which stays stable even if they rename:

    def show_stamina(self, player, fraction: float) -> None:
        bar = self.bars.get(player.unique_id)
        if bar is None:
            bar = self.server.create_boss_bar("Stamina", BarColor.GREEN, BarStyle.SOLID)
            bar.add_player(player)
            self.bars[player.unique_id] = bar
        bar.progress = fraction

Drop each bar when its player leaves, so you're not holding bars for people who are gone:

from endstone.event import event_handler, PlayerQuitEvent

    @event_handler
    def on_player_quit(self, event: PlayerQuitEvent) -> None:
        bar = self.bars.pop(event.player.unique_id, None)
        if bar is not None:
            bar.remove_all()

On this page