Understanding HUD Components
HUD elements in BetterHud are persistent displays that appear on the player’s screen. They can show:- Player statistics (health, mana, experience)
- Custom metrics and counters
- Dynamic text and images
- Conditional content based on game state
Getting HUD Manager
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.manager.HudManager;
import kr.toxicity.hud.api.hud.Hud;
public class HudHelper {
public static HudManager getManager() {
return BetterHudAPI.inst().getHudManager();
}
public static Hud getHud(String name) {
return getManager().getHud(name);
}
public static Set<String> getAllHudNames() {
return getManager().getAllNames();
}
public static Set<Hud> getAllHuds() {
return getManager().getAllHuds();
}
}
Player HUD Management
Getting Player’s Active HUDs
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.player.HudPlayer;
import kr.toxicity.hud.api.hud.Hud;
import org.bukkit.entity.Player;
import java.util.Set;
public class PlayerHudManager {
public static Set<Hud> getPlayerHuds(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
return hudPlayer.getHuds();
}
return Set.of();
}
public static boolean hasHud(Player player, String hudName) {
Set<Hud> huds = getPlayerHuds(player);
return huds.stream()
.anyMatch(hud -> hud.getName().equals(hudName));
}
public static void listPlayerHuds(Player player) {
Set<Hud> huds = getPlayerHuds(player);
if (huds.isEmpty()) {
player.sendMessage("You have no active HUDs");
} else {
player.sendMessage("Active HUDs:");
huds.forEach(hud ->
player.sendMessage("- " + hud.getName())
);
}
}
}
Enabling/Disabling HUDs
Toggle HUD Display
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.player.HudPlayer;
import org.bukkit.entity.Player;
public class HudToggle {
public static void enableHud(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.setHudEnabled(true);
player.sendMessage("HUD enabled");
}
}
public static void disableHud(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.setHudEnabled(false);
player.sendMessage("HUD disabled");
}
}
public static void toggleHud(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
boolean currentState = hudPlayer.isHudEnabled();
hudPlayer.setHudEnabled(!currentState);
player.sendMessage("HUD " + (!currentState ? "enabled" : "disabled"));
}
}
public static boolean isHudEnabled(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
return hudPlayer != null && hudPlayer.isHudEnabled();
}
}
Custom HUD Component
Creating Additional Components
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.component.PixelComponent;
import kr.toxicity.hud.api.component.WidthComponent;
import kr.toxicity.hud.api.player.HudPlayer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player;
import java.util.List;
public class CustomHudComponent {
public static void addCustomComponent(Player player, String text) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer == null) return;
// Create a custom width component
WidthComponent component = new WidthComponent() {
@Override
public int getWidth() {
return text.length() * 6; // Approximate width
}
@Override
public Component getComponent() {
return Component.text(text).color(NamedTextColor.GOLD);
}
};
// Set as additional component
hudPlayer.setAdditionalComponent(component);
}
public static void removeCustomComponent(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.setAdditionalComponent(null);
}
}
public static WidthComponent createPixelComponent(String imageName, int width, int height) {
return new WidthComponent() {
@Override
public int getWidth() {
return width;
}
@Override
public Component getComponent() {
// Create component from pixel/image data
return Component.text("[" + imageName + "]");
}
};
}
}
HUD Color Customization
Boss Bar Color
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.player.HudPlayer;
import net.kyori.adventure.bossbar.BossBar;
import org.bukkit.entity.Player;
public class HudColorManager {
public static void setBarColor(Player player, BossBar.Color color) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.setBarColor(color);
}
}
public static BossBar.Color getBarColor(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
return hudPlayer.getBarColor();
}
return null;
}
public static void setHealthBasedColor(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
double healthPercent = player.getHealth() / player.getMaxHealth();
BossBar.Color color;
if (healthPercent > 0.7) {
color = BossBar.Color.GREEN;
} else if (healthPercent > 0.3) {
color = BossBar.Color.YELLOW;
} else {
color = BossBar.Color.RED;
}
hudPlayer.setBarColor(color);
}
}
}
HUD Update Management
Manual Updates
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.player.HudPlayer;
import org.bukkit.entity.Player;
public class HudUpdater {
public static void forceUpdate(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.update();
}
}
public static void reloadPlayer(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.reload();
}
}
public static long getPlayerTick(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
return hudPlayer.getTick();
}
return 0;
}
}
HUD Task Management
Start/Stop Update Tasks
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.player.HudPlayer;
import org.bukkit.entity.Player;
public class HudTaskManager {
public static void startHudTick(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.startTick();
}
}
public static void stopHudTick(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.cancelTick();
}
}
public static void restartHudTick(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer != null) {
hudPlayer.cancelTick();
hudPlayer.startTick();
}
}
}
Complete Example: Dynamic Health HUD
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.player.HudPlayer;
import kr.toxicity.hud.api.placeholder.HudPlaceholder;
import net.kyori.adventure.bossbar.BossBar;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
public class DynamicHealthHud implements Listener {
public static void initialize() {
// Register health-related placeholders
var manager = BetterHudAPI.inst().getPlaceholderManager();
HudPlaceholder.<Number>builder()
.function((args, event) -> player -> {
Player p = (Player) player.handle();
return p.getHealth();
})
.build()
.add("current_health", manager.getNumberContainer());
HudPlaceholder.<Number>builder()
.function((args, event) -> player -> {
Player p = (Player) player.handle();
return p.getMaxHealth();
})
.build()
.add("max_health", manager.getNumberContainer());
HudPlaceholder.<Number>builder()
.function((args, event) -> player -> {
Player p = (Player) player.handle();
return (p.getHealth() / p.getMaxHealth()) * 100;
})
.build()
.add("health_percent", manager.getNumberContainer());
}
@EventHandler
public void onDamage(EntityDamageEvent event) {
if (event.getEntity() instanceof Player player) {
updateHealthColor(player);
}
}
@EventHandler
public void onHeal(EntityRegainHealthEvent event) {
if (event.getEntity() instanceof Player player) {
updateHealthColor(player);
}
}
private void updateHealthColor(Player player) {
var playerManager = BetterHudAPI.inst().getPlayerManager();
HudPlayer hudPlayer = playerManager.getHudPlayer(player.getUniqueId());
if (hudPlayer == null) return;
double healthPercent = player.getHealth() / player.getMaxHealth();
BossBar.Color color;
if (healthPercent > 0.7) {
color = BossBar.Color.GREEN;
} else if (healthPercent > 0.4) {
color = BossBar.Color.YELLOW;
} else if (healthPercent > 0.2) {
color = BossBar.Color.RED;
} else {
color = BossBar.Color.PURPLE; // Critical health
}
hudPlayer.setBarColor(color);
hudPlayer.update();
}
}
Conditional HUD Display
import kr.toxicity.hud.api.BetterHudAPI;
import kr.toxicity.hud.api.placeholder.HudPlaceholder;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
public class ConditionalHud {
public static void registerConditionalPlaceholders() {
var manager = BetterHudAPI.inst().getPlaceholderManager();
// Show different values based on game mode
HudPlaceholder.<Boolean>builder()
.function((args, event) -> player -> {
Player p = (Player) player.handle();
return p.getGameMode() == GameMode.SURVIVAL;
})
.build()
.add("is_survival", manager.getBooleanContainer());
// Show based on world
HudPlaceholder.<Boolean>builder()
.function((args, event) -> player -> {
Player p = (Player) player.handle();
return p.getWorld().getName().equals("world_nether");
})
.build()
.add("in_nether", manager.getBooleanContainer());
// Show based on permission
HudPlaceholder.<Boolean>builder()
.requiredArgsLength(1)
.function((args, event) -> {
String permission = args.get(0);
return player -> {
Player p = (Player) player.handle();
return p.hasPermission(permission);
};
})
.build()
.add("has_permission", manager.getBooleanContainer());
}
}
Best Practices
Performance Optimization
Performance Optimization
- Cache HudPlayer instances when possible
- Avoid frequent updates in tight loops
- Use conditional rendering with boolean placeholders
- Batch multiple changes before calling
update()
Error Handling
Error Handling
- Always check if HudPlayer is null before operations
- Validate HUD names exist before accessing
- Handle exceptions when updating components
- Log warnings for debugging
Memory Management
Memory Management
- Remove custom components when no longer needed
- Clear player data on disconnect
- Don’t store unnecessary references to HudPlayer
- Use weak references for long-term storage
Next Steps
Custom Popup
Create dynamic popup notifications
Placeholders
Advanced placeholder patterns
HUD Manager
Complete HUD Manager API
Player API
Full HudPlayer reference
