Skip to content

HUD System

The Hytale HUD system provides comprehensive control over the player’s heads-up display, including built-in components, custom overlays, notifications, and event titles.

HudManager (per-player)
├── visibleHudComponents - Set of currently visible built-in HUD components
├── customHud - Optional custom HUD overlay
└── Methods for visibility control and custom HUD management
CustomUIHud (abstract)
├── build() - Define HUD structure using UICommandBuilder
├── show() - Display the HUD to the player
└── update() - Send incremental updates

The HudManager class controls HUD visibility and custom overlays for individual players. Each player has their own HudManager instance accessible via the Player component.

import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.hud.HudManager;
// From a Player component
Player playerComponent = store.getComponent(entityRef, Player.getComponentType());
HudManager hudManager = playerComponent.getHudManager();

Replace the entire set of visible HUD components:

import com.hypixel.hytale.protocol.packets.interface_.HudComponent;
// Show only specific components (replaces all)
hudManager.setVisibleHudComponents(playerRef,
HudComponent.Hotbar,
HudComponent.Health,
HudComponent.Chat,
HudComponent.Reticle
);
// Using a Set
Set<HudComponent> components = Set.of(
HudComponent.Hotbar,
HudComponent.Health,
HudComponent.Stamina
);
hudManager.setVisibleHudComponents(playerRef, components);

Add or remove components without replacing the entire set:

// Show additional components
hudManager.showHudComponents(playerRef,
HudComponent.Compass,
HudComponent.ObjectivePanel
);
// Hide specific components
hudManager.hideHudComponents(playerRef,
HudComponent.KillFeed,
HudComponent.Notifications
);
// Reset to default components and clear custom HUD
hudManager.resetHud(playerRef);
// Reset entire UI state (closes menus, etc.)
hudManager.resetUserInterface(playerRef);
Set<HudComponent> visible = hudManager.getVisibleHudComponents();
// Returns an unmodifiable view of the current components

All built-in HUD components available in the game:

ComponentValueDescription
Hotbar0Player hotbar/inventory bar
StatusIcons1Status effect icons
Reticle2Crosshair/targeting reticle
Chat3Chat window
Requests4Friend/party requests
Notifications5Toast notifications
KillFeed6Kill/death messages
InputBindings7Key binding hints
PlayerList8Tab player list
EventTitle9Event title display area
Compass10Navigation compass
ObjectivePanel11Quest/objective tracker
PortalPanel12Portal-related UI
BuilderToolsLegend13Builder tools legend
Speedometer14Speed indicator
UtilitySlotSelector15Utility slot selection
BlockVariantSelector16Block variant picker
BuilderToolsMaterialSlotSelector17Builder material slot
Stamina18Stamina bar
AmmoIndicator19Ammunition counter
Health20Health bar
Mana21Mana bar
Oxygen22Oxygen/breath bar
Sleep23Sleep indicator

The following components are visible by default:

Set.of(
HudComponent.UtilitySlotSelector,
HudComponent.BlockVariantSelector,
HudComponent.StatusIcons,
HudComponent.Hotbar,
HudComponent.Chat,
HudComponent.Notifications,
HudComponent.KillFeed,
HudComponent.InputBindings,
HudComponent.Reticle,
HudComponent.Compass,
HudComponent.Speedometer,
HudComponent.ObjectivePanel,
HudComponent.PortalPanel,
HudComponent.EventTitle,
HudComponent.Stamina,
HudComponent.AmmoIndicator,
HudComponent.Health,
HudComponent.Mana,
HudComponent.Oxygen,
HudComponent.BuilderToolsLegend,
HudComponent.Sleep
)

Create custom HUD overlays that display alongside or replace built-in components.

import com.hypixel.hytale.server.core.entity.entities.player.hud.CustomUIHud;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.universe.PlayerRef;
public class BossHealthHud extends CustomUIHud {
private String bossName;
private float healthPercent;
public BossHealthHud(PlayerRef playerRef, String bossName) {
super(playerRef);
this.bossName = bossName;
this.healthPercent = 1.0f;
}
@Override
protected void build(UICommandBuilder builder) {
// Append a UI document from assets
builder.append("#hud-root", "ui/custom/boss_health.ui");
// Set initial values
builder.set("#boss-name", bossName);
builder.set("#health-bar-fill", healthPercent);
}
public void updateHealth(float percent) {
this.healthPercent = percent;
UICommandBuilder builder = new UICommandBuilder();
builder.set("#health-bar-fill", healthPercent);
// Send incremental update (clear=false)
update(false, builder);
}
public void setBossDefeated() {
UICommandBuilder builder = new UICommandBuilder();
builder.set("#boss-name", bossName + " (Defeated)");
builder.set("#health-bar-fill", 0.0f);
update(false, builder);
}
}
// Create and show custom HUD
BossHealthHud bossHud = new BossHealthHud(playerRef, "Dragon Lord");
hudManager.setCustomHud(playerRef, bossHud);
// Later, update the HUD
bossHud.updateHealth(0.5f);
// Remove custom HUD
hudManager.setCustomHud(playerRef, null);

The UICommandBuilder class provides methods for manipulating UI elements:

MethodDescription
append(selector, documentPath)Append UI document as child
append(documentPath)Append UI document to root
appendInline(selector, document)Append inline UI definition
insertBefore(selector, documentPath)Insert UI document before element
insertBeforeInline(selector, document)Insert inline UI before element
remove(selector)Remove element from DOM
clear(selector)Clear element’s children
set(selector, value)Set element property (string, number, boolean, Message)
setNull(selector)Set property to null
setObject(selector, data)Set complex object (Area, ItemStack, etc.)
// Strings
builder.set("#label", "Hello World");
// Numbers
builder.set("#progress", 0.75f);
builder.set("#count", 42);
builder.set("#value", 3.14159);
// Booleans
builder.set("#visible", true);
// Messages (with formatting)
builder.set("#title", Message.translation("game.boss.name"));
// Complex objects
builder.setObject("#item-slot", itemStack);
builder.setObject("#area", new Area(0, 0, 100, 50));

Display large announcement titles on the player’s screen.

import com.hypixel.hytale.server.core.util.EventTitleUtil;
import com.hypixel.hytale.server.core.Message;
// Show title to a single player
EventTitleUtil.showEventTitleToPlayer(
playerRef,
Message.raw("Zone Discovered"), // Primary title
Message.raw("Welcome to the Dark Forest"), // Secondary title
true, // isMajor (large display)
"ui/icons/forest.png", // Optional icon
4.0f, // Duration (seconds)
1.5f, // Fade in duration
1.5f // Fade out duration
);
// Simplified version with defaults
EventTitleUtil.showEventTitleToPlayer(
playerRef,
Message.translation("zone.darkforest.name"),
Message.translation("zone.darkforest.desc"),
true // isMajor
);
// Hide title early
EventTitleUtil.hideEventTitleFromPlayer(playerRef, 0.5f);
// Show to all players in a world
EventTitleUtil.showEventTitleToWorld(
Message.raw("Wave 5"),
Message.raw("Prepare for battle!"),
true, // isMajor
"ui/icons/warning.png", // icon
4.0f, // duration
1.5f, // fadeIn
1.5f, // fadeOut
store // EntityStore
);
// Show to all players in the universe
EventTitleUtil.showEventTitleToUniverse(
Message.raw("Server Event"),
Message.raw("Double XP Weekend!"),
true,
null,
10.0f,
2.0f,
2.0f
);
// Hide from all players in a world
EventTitleUtil.hideEventTitleFromWorld(1.0f, store);
FieldTypeDescription
fadeInDurationfloatSeconds to fade in
fadeOutDurationfloatSeconds to fade out
durationfloatSeconds to display
iconStringOptional icon path
isMajorbooleanLarge vs small display
primaryTitleFormattedMessageMain title text
secondaryTitleFormattedMessageSubtitle text

Display toast notifications in the notification area.

import com.hypixel.hytale.server.core.util.NotificationUtil;
import com.hypixel.hytale.protocol.packets.interface_.NotificationStyle;
// Simple notification
NotificationUtil.sendNotification(
playerRef.getPacketHandler(),
"Quest completed!"
);
// With style
NotificationUtil.sendNotification(
playerRef.getPacketHandler(),
Message.raw("Achievement Unlocked"),
NotificationStyle.Success
);
// With icon
NotificationUtil.sendNotification(
playerRef.getPacketHandler(),
Message.translation("item.received"),
"ui/icons/chest.png",
NotificationStyle.Default
);
// Full notification with all options
NotificationUtil.sendNotification(
playerRef.getPacketHandler(),
Message.raw("New Item"), // Primary message
Message.raw("Diamond Sword"), // Secondary message
"ui/icons/sword.png", // Icon
itemWithMetadata, // Item to display
NotificationStyle.Success
);
StyleValueDescription
Default0Standard notification
Danger1Red/danger styling
Warning2Yellow/warning styling
Success3Green/success styling
// To entire world
NotificationUtil.sendNotificationToWorld(
Message.raw("Server message"),
null, // Secondary message
"ui/icons/server.png", // Icon
null, // Item
NotificationStyle.Default,
store
);
// To entire universe
NotificationUtil.sendNotificationToUniverse(
Message.raw("Server restarting in 5 minutes"),
NotificationStyle.Warning
);

Display kill/death messages in the kill feed.

import com.hypixel.hytale.protocol.packets.interface_.KillFeedMessage;
import com.hypixel.hytale.protocol.FormattedMessage;
// Create kill feed message
KillFeedMessage message = new KillFeedMessage(
killerMessage.getFormattedMessage(), // Killer name/info
decedentMessage.getFormattedMessage(), // Victim name/info
"ui/icons/sword.png" // Kill icon
);
// Send to player
playerRef.getPacketHandler().writeNoCache(message);

The kill feed system fires events that can be intercepted:

import com.hypixel.hytale.server.core.modules.entity.damage.event.KillFeedEvent;
// Customize kill feed display
getEventRegistry().register(KillFeedEvent.Display.class, event -> {
// Modify broadcast targets
event.getBroadcastTargets().clear();
event.getBroadcastTargets().addAll(nearbyPlayers);
// Change icon
event.setIcon("ui/icons/custom_kill.png");
// Or cancel entirely
// event.setCancelled(true);
});
// Customize decedent message
getEventRegistry().register(KillFeedEvent.DecedentMessage.class, event -> {
event.setMessage(Message.raw("was eliminated"));
});
// Customize killer message
getEventRegistry().register(KillFeedEvent.KillerMessage.class, event -> {
event.setMessage(Message.raw("eliminated"));
});

Sends custom HUD commands to the client:

FieldTypeDescription
clearbooleanClear existing custom HUD first
commandsCustomUICommand[]Array of UI commands

Updates which built-in HUD components are visible:

FieldTypeDescription
visibleComponentsHudComponent[]Array of visible components

Resets the entire UI state (closes menus, resets HUD). This packet has no fields.

Displays an event title:

FieldTypeDescription
fadeInDurationfloatFade in time
fadeOutDurationfloatFade out time
durationfloatDisplay duration
iconStringOptional icon
isMajorbooleanMajor/minor display
primaryTitleFormattedMessageMain title
secondaryTitleFormattedMessageSubtitle

Hides the current event title:

FieldTypeDescription
fadeOutDurationfloatFade out time

Sends a toast notification:

FieldTypeDescription
messageFormattedMessagePrimary message
secondaryMessageFormattedMessageSecondary message
iconStringOptional icon
itemItemWithAllMetadataOptional item display
styleNotificationStyleVisual style

Sends a kill feed entry:

FieldTypeDescription
killerFormattedMessageKiller info
decedentFormattedMessageVictim info
iconStringKill method icon
public class MinigameHud extends CustomUIHud {
private int score = 0;
private int timeRemaining = 300;
public MinigameHud(PlayerRef playerRef) {
super(playerRef);
}
@Override
protected void build(UICommandBuilder builder) {
builder.append("ui/minigame/scoreboard.ui");
builder.set("#score-value", score);
builder.set("#time-value", formatTime(timeRemaining));
}
public void updateScore(int newScore) {
this.score = newScore;
UICommandBuilder builder = new UICommandBuilder();
builder.set("#score-value", score);
update(false, builder);
}
public void updateTime(int seconds) {
this.timeRemaining = seconds;
UICommandBuilder builder = new UICommandBuilder();
builder.set("#time-value", formatTime(seconds));
update(false, builder);
}
private String formatTime(int seconds) {
return String.format("%d:%02d", seconds / 60, seconds % 60);
}
}
public void enterCinematicMode(PlayerRef playerRef, HudManager hudManager) {
// Hide most HUD elements
hudManager.setVisibleHudComponents(playerRef,
HudComponent.Chat // Keep chat visible
);
}
public void exitCinematicMode(PlayerRef playerRef, HudManager hudManager) {
// Restore default HUD
hudManager.resetHud(playerRef);
}
public void startBossFight(PlayerRef playerRef, HudManager hudManager, String bossName) {
// Show boss health HUD
BossHealthHud bossHud = new BossHealthHud(playerRef, bossName);
hudManager.setCustomHud(playerRef, bossHud);
// Show event title
EventTitleUtil.showEventTitleToPlayer(
playerRef,
Message.raw("BOSS FIGHT"),
Message.raw(bossName),
true,
"ui/icons/skull.png",
3.0f,
0.5f,
0.5f
);
// Show danger notification
NotificationUtil.sendNotification(
playerRef.getPacketHandler(),
Message.raw("A powerful enemy approaches!"),
NotificationStyle.Danger
);
}
public void endBossFight(PlayerRef playerRef, HudManager hudManager, boolean victory) {
// Remove boss HUD
hudManager.setCustomHud(playerRef, null);
if (victory) {
EventTitleUtil.showEventTitleToPlayer(
playerRef,
Message.raw("VICTORY"),
Message.raw("The boss has been defeated!"),
true
);
NotificationUtil.sendNotification(
playerRef.getPacketHandler(),
Message.raw("Boss defeated!"),
NotificationStyle.Success
);
}
}
  1. Minimize updates - Batch HUD updates when possible to reduce network traffic
  2. Use incremental updates - Pass clear=false to update() for partial updates
  3. Cache HUD instances - Reuse CustomUIHud instances rather than recreating them
  4. Respect player preferences - Consider allowing players to toggle optional HUD elements
  5. Clean up on disconnect - Custom HUDs are automatically cleared when players disconnect
  6. Use appropriate notification styles - Match the style to the message importance
  7. Keep event titles brief - They should be scannable at a glance
  8. Test different screen sizes - HUD elements should work across resolutions