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:
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:
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:
progressis clamped to[0.0, 1.0]- a value outside that range raisesValueError, so clamp it yourself as the example does.- Flags add atmosphere.
BarFlag.DARKEN_SKYdarkens the sky andBarFlag.CREATE_FOGrolls in fog; add and remove them withadd_flag/remove_flag. - Attachment is per player.
add_playerandremove_playercontrol exactly who sees the bar;remove_allclears everyone, which is the tidy thing to do inon_disable. You can also hide a bar from all its viewers without detaching them by settingis_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 = fractionDrop 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()