This guide demonstrates how to create, customize, and manage HUD elements using the BetterHud API.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/toxicity188/BetterHud/llms.txt
Use this file to discover all available pages before exploring further.
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
