HUD
Text on a player's screen that never takes their controls: widgets, notices and big moments, designed widgets, anchors and the minimap.
Text on a player's screen that never takes their controls: widgets that stay (money, health, a quest tracker, a combat
timer), notices that pop in and out ("+120 coins", a kill), and big moments over the crosshair ("DOUBLE KILL"). Since
1.566.0, in net.exylia.lib.hud (Huds, HudWidget, HudNotice, HudAnchor). It shares the text-display
machinery of Screens.
Huds huds = Huds.of(this);
HudHandle money = huds.show(player, HudWidget.of("money", HudAnchor.TOP_LEFT,
p -> Text.of("{success}♦ {letters}" + Formats.money(balance(p))).build()));
money.refresh(); // read the text again now, instead of on its next period
money.remove();
huds.notify(player, HudNotice.of(Text.of("{success}+120 {letters}coins").build()).group("coins"));
huds.notify(player, HudNotice.moment(Text.of("{error}&lDOUBLE KILL").build()));Every method is safe from any thread. Without PacketEvents nothing is drawn and the handles still work, so a caller never branches on support.
Widgets
HudWidget.of(id, anchor, text) stays until it is removed. Showing another with the same id replaces it in place.
| Field | Copy | Default |
|---|---|---|
text (Function<Player, Component>) | read every every ticks | |
when (Predicate<Player>) | when(condition) | always |
order (place in the anchor's stack, lowest at the edge) | order(n) | 0 |
every (ticks between reads, at least 2) | every(ticks) | 10; a fixed Component 1200 |
background (ARGB, 0 none) | background(argb) | 0; HudWidget.PANEL is the palette's panel |
scale | scale(size) | 1 |
textandwhenrun on the player's own thread: read memory, never a database. A text equal to the one on screen sends nothing.- A
nullor blank text, or afalsecondition, shrinks the widget away and it pops back when it has something to say: "in combat", "low health", "inside a region". - Lines break only where the text has
\n. A corner is about a fifth of the screen wide before it reaches the middle.
Designed widgets
Since 1.582.0 a widget can be designed like a screen: boxes with backgrounds, gradients and outlines, rows and columns,
progress bars and img pictures, laid out by the screens' flexbox
(markup).
ScreenMarkup vitals = ScreenMarkup.load(folder.resolve("vitals.html"), folder.resolve("vitals.css"));
huds.show(player, HudWidget.markup("vitals", HudAnchor.TOP_LEFT, vitals).every(4));
// or a tree built in Java, null to hide it
huds.show(player, HudWidget.layout("boss", HudAnchor.TOP, p -> Node.column(...)));<column class="hud-card">
<row class="line"><text>{error}❤ {letters}Health</text><text>{error}${round(health())}</text></row>
<progress value="${health()}" max="20"/>
</column>- The tree is read again every
everyticks on the player's thread. A layout equal to the one on screen sends nothing. hud-cardis in the base theme: the dark see-through panel and thin outline that read over any sky. The HUD kit (1.585.0) addshud-row,hud-stack,hud-chip,hud-banner,hud-objective,hud-alert,hud-levelwithhud-bar,hud-profile,hud-panelwithhud-panel-titleandhud-map.border-radius: 2pxcuts each corner as pixel steps without a seam. Only a HUD draws it.- Minimap:
<img map="40" zoom="1" round ring="{primary}"/>is the ground around the player, turned so their facing is up, with an arrow in the middle: the map colour of each column's top block, shaded by height. Four displays whatever its size (8 to 64); it reads only loaded chunks the player's region owns. Give itevery: 10or more. - Clicks, hovers,
transition,animationandenterdo nothing on a HUD;item,item3d,windowand turning bodies are left out, and text shadows are never drawn. - Cost: one display per rect, per text and four per picture; an outline is four. An element draws at most 64, so keep designs small. Layers are spawned back to front because a client draws see-through displays in spawn order.
Notices
HudNotice.of(text) pops in at the top right, stays three seconds and shrinks away. Newer ones stand nearest the edge;
past five at one anchor the oldest leaves early.
| Field | Copy | Default |
|---|---|---|
anchor | anchor(where) | TOP_RIGHT |
seconds | seconds(time) | 3 |
group | group(key) | none |
scale | scale(size) | 1 |
A notice whose group matches one still up replaces it, counts (×3), pops and restarts its time: three kills in a row
are one line. HudNotice.moment(text) is twice the size, no panel, just above the crosshair for two seconds; a new moment
replaces the one on screen.
Anchors
| Anchor | Where | Stacks |
|---|---|---|
TOP_LEFT | the top left corner, free in vanilla | down |
TOP | the top centre, under one boss bar | down |
TOP_RIGHT | the top right, under the potion icons; notices | down |
LEFT | the left edge, above the chat | down |
CENTER | just above the crosshair; moments | down |
RIGHT | the right edge, where the sidebar goes | down |
ABOVE_HOTBAR | over the hotbar, hearts and experience bar | up |
BOTTOM_RIGHT | the bottom right corner | up |
HudAnchor.parse("top-left") reads the names a file writes. The held item covers BOTTOM_RIGHT (the client draws the hand
last), so keep it for things that can wait. Positions are measured on a 16:9 window at FOV 70.
How it stays put
Each element is one text display seated on the player for their client alone, with a camera-facing billboard sixteen blocks ahead, so walking, jumping and turning cost no packet. Only a changed text, a condition flipping, a reflowed stack or a pitch step (3°) sends anything.
- Fitted to the window (1.584.0): corners are placed for the player's own FOV and window shape, the ones they fit on their first screen or HUD, and elements are drawn larger by the same share (Screens).
- Sprinting narrows the HUD a little towards the middle with the world; it is not compensated.
- One stack per anchor across plugins: two plugins at one anchor stack one after the other.
- Steps aside while a screen is open, a camera shot plays, the player is dead or in spectator mode, and when the player
turned Show HUD off in
/settings(Huds.hidden(player, hide)from code). - Only translation and scale animate: elements grow from their middle, glide when their stack reflows and shrink back (1.588.0).
- Who sees it (1.591.0):
Huds.supports(player)is a Java client of 1.20.2 or newer with PacketEvents on the server;Huds.visible(player)adds "and did not turn it off". A widget shown to someone notvisibleis simply not drawn; branch only to show something else instead (a sidebar, a boss bar).%player_hud%gives the same answer to other plugins' files.
Try it with /exylialib hudtest show|notice [group]|moment|hide.
From a file
Any interaction list (menu clicks, screen actions, open items) can write
[HUD] {success}+120 {letters}coins;group:coins;seconds:4 and [MOMENT] {error}&lDOUBLE KILL. Options are the trailing
;key:value parts (anchor, seconds, group); the rest is the text, with the player's placeholders.
Something missing on this page? Tell us on Discord