Configuration
AstralHud loads five files from its data folder, each reloaded together by /hud reload: config.yml, bossbar.yml, actionbar.yml, scoreboard.yml, and image-manipulation.yml. AstralHud#loadConfiguration() loads the first four unconditionally; image-manipulation.yml is wrapped in a try/catch — a malformed file logs a warning (Failed to load image-manipulation.yml configuration...) instead of aborting the rest of the reload.
config.yml
A single top-level backgrounds section.
backgrounds
Field | Type | Description |
|---|---|---|
|
| The resource-pack font that supplies the background glyphs, e.g. |
|
| Maps a pixel-width value to the single character in that font which is exactly that many pixels wide. Must include |
BackgroundsConfiguration#build(length) greedily covers the requested pixel width using the largest mapped values first (256, 128, 64, …), each preceded by a NEG_1 negative-space codepoint so consecutive background glyphs overlap into one continuous image instead of stacking side by side; it starts with the 0-glyph and ends with the 256-glyph plus a negative-space offset sized to the total width. Only powers of two present in mappings are used, so removing an entry (e.g. 64) forces the builder to reach the same width using smaller pieces. See Background images for how the boss bar uses this.
bossbar.yml
Field | Type | Description |
|---|---|---|
| long (ms) | How often an unchanged container's placeholders are re-rendered ("refresh"). |
| long (ms) | How often the next-priority eligible container in each slot is selected ("rotate"). |
|
| The pool of displayable entries, keyed by an arbitrary map key (the container's own |
InfoContainer fields
Field | Type | Description |
|---|---|---|
| String | The container's identity, used in log messages and cache lookups. |
| int | Containers sharing a |
| int | Within a slot, eligible containers are shown in descending priority order as rotation advances. |
|
| The rendered text — a placeholder-aware MiniMessage string. |
|
| Gates eligibility; a container whose requirements fail is skipped during rotation. Omit for an always-eligible container. |
| int | Extra pixels padded onto this container's background width, e.g. to leave room around the text. Defaults to |
Here slot 1 has two containers (test, health); BossBarUpdateTask rotates between them every refresh-rate ms, always picking the highest-priority one that's currently eligible, while slot 0 (name) has nothing to rotate into. Each slot's current text is separated from the next by two spaces.
actionbar.yml
Same container shape as the boss bar (InfoContainer), minus the background-image step — the action bar has no extra-length-driven backdrop. One extra timing field:
Field | Type | Description |
|---|---|---|
| long (ms) | Refresh interval — same meaning as the boss bar's. |
| long (ms) | Rotation interval — same meaning as the boss bar's. |
| long (ms) | How often the last-rendered component is re-sent to the client even if unchanged. Needed because the vanilla client hides the action bar a few seconds after each packet. |
|
| Same shape as boss bar containers (its |
scoreboard.yml
Field | Type | Description |
|---|---|---|
| long (ms) | How often the eligible-container selection is re-evaluated ( |
| long (ms) | How often the currently-selected container's title/content are re-rendered ( |
|
| The pool of displayable scoreboards, keyed by an arbitrary map key. |
SBContainer fields
Field | Type | Description |
|---|---|---|
| String | The container's identity. |
| int | Containers are compared across the entire surface (no |
|
| The scoreboard's title line. |
|
| The scoreboard's body lines, top to bottom. |
|
| Gates eligibility, same as the bar surfaces. |
With this example, players below 20 health see the health container (higher priority, requirement passes); everyone else falls through to name. If no container's requirements pass, the scoreboard is removed until one does.
image-manipulation.yml
Backs the imgmanip, imgprovider, and stringprovider placeholders. Every entry is pre-rendered into an in-memory cache once, on load — none of it is re-evaluated per placeholder call except the placeholder's own lookup key.
Field | Type | Description |
|---|---|---|
| List of | Repeated-glyph "meters" — an element string repeated N times, for every N in a bounded range. Backs |
|
| Per-id lookup tables keyed by integer. Backs |
|
| Per-id lookup tables keyed by string. Backs |
ImageManipulationEntry
Field | Type | Description |
|---|---|---|
| String | Looked up by the first path token after |
|
| The glyph/text repeated to build each amount's image. Resolved once at load time (against an empty placeholder container), not per-player — don't put player-specific placeholders in |
|
| Not used at cache-build time; consumed by |
| int | The inclusive range of amounts pre-rendered and cached ( |
The shipped default image-manipulation.yml ships with all three sections empty ([]).
Update timing
Every surface's per-player update task runs every 5 ticks (~250ms) regardless of configuration and, each run, checks the surface's own intervals against that player's last-action timestamps:
Surface | "Rotate" check | "Refresh" check | Extra |
|---|---|---|---|
Boss bar |
|
| — |
Action bar | Same as boss bar | Same as boss bar |
|
Scoreboard |
|
| — |
Note the scoreboard's field names are the reverse of what they sound like: update-rate drives container selection and rotation-rate drives placeholder re-rendering — match the boss bar/action bar's refresh-rate behavior, not their own names. A rotate/select always implies a re-render in the same pass; the refresh-only branch only fires when a rotate/select didn't already happen that run.
See also
Overview — how the boss bar, action bar, and scoreboard fit together conceptually.
Placeholders — the
imgmanip/imgprovider/stringproviderplaceholders backed byimage-manipulation.yml.Commands —
/hud reload.