Overview
The Placeholder API allows you to create custom placeholders that can be used in HUDs, popups, and other BetterHud components. Placeholders provide dynamic text replacement based on player data and game state.
HudPlaceholder Interface
The HudPlaceholder<T> interface represents a placeholder that returns values of type T.
Package
kr.toxicity.hud.api.placeholder.HudPlaceholder
Type Parameters
The return type of the placeholder (Number, String, or Boolean)
Methods
invoke
Creates a function from the given arguments that will be evaluated for each player.
@NotNull Function<HudPlayer, T> invoke(
@NotNull @Unmodifiable List<String> args,
@NotNull UpdateEvent reason
)
The arguments provided to the placeholder (e.g., from %placeholder_arg1_arg2%)
The event that triggered this placeholder evaluation
A function that takes a HudPlayer and returns the placeholder value
getRequiredArgsLength
Gets the number of required arguments for this placeholder.
int getRequiredArgsLength()
The minimum number of arguments required
PlaceholderContainer Interface
Manages a group of related placeholders.
Package
kr.toxicity.hud.api.placeholder.PlaceholderContainer
Type Parameters
The return type of placeholders in this container
Methods
addPlaceholder
Adds a placeholder to this container.
void addPlaceholder(@NotNull String name, @NotNull HudPlaceholder<T> placeholder)
The name/identifier for the placeholder
placeholder
HudPlaceholder<T>
required
The placeholder implementation
getAllPlaceholders
Gets all registered placeholders.
@NotNull @Unmodifiable Map<String, HudPlaceholder<?>> getAllPlaceholders()
return
Map<String, HudPlaceholder<?>>
An unmodifiable map of all placeholders in this container
HudPlaceholder.Builder
A builder for creating placeholder implementations.
Methods
requiredArgsLength
Sets the required number of arguments.
@NotNull Builder<T> requiredArgsLength(int requiredArgsLength)
The number of required arguments
function
Sets the placeholder function.
@NotNull Builder<T> function(@NotNull PlaceholderFunction<T> function)
function
PlaceholderFunction<T>
required
The function that computes the placeholder value
build
Builds the placeholder.
@NotNull HudPlaceholder<T> build()
The constructed placeholder
add
Builds and adds the placeholder to a container.
void add(@NotNull String name, @NotNull PlaceholderContainer<T> container)
The name for the placeholder
container
PlaceholderContainer<T>
required
The container to add the placeholder to
PlaceholderFunction
A functional interface for placeholder logic.
@FunctionalInterface
interface PlaceholderFunction<T> extends BiFunction<List<String>, UpdateEvent, Function<HudPlayer, T>>
Signature: (List<String> args, UpdateEvent event) -> (HudPlayer player) -> T
Usage Examples
Creating a Simple Placeholder
import kr.toxicity.hud.api.BetterHud;
import kr.toxicity.hud.api.placeholder.HudPlaceholder;
import kr.toxicity.hud.api.placeholder.PlaceholderContainer;
import kr.toxicity.hud.api.player.HudPlayer;
public class SimplePlaceholderExample {
public void registerHealthPlaceholder() {
// Get the number placeholder container
PlaceholderContainer<Number> numberContainer =
BetterHud.inst().getPlaceholderManager().getNumberContainer();
// Create a simple placeholder using static method
HudPlaceholder<Number> healthPlaceholder = HudPlaceholder.of(
(args, event) -> (HudPlayer player) -> {
// Return player's health
if (player.handle() instanceof org.bukkit.entity.Player p) {
return p.getHealth();
}
return 0;
}
);
// Register the placeholder
numberContainer.addPlaceholder("player_health", healthPlaceholder);
// Usage in config: %player_health%
}
}
Using the Builder Pattern
import kr.toxicity.hud.api.placeholder.HudPlaceholder;
import kr.toxicity.hud.api.BetterHud;
public void registerLevelPlaceholder() {
PlaceholderContainer<Number> numberContainer =
BetterHud.inst().getPlaceholderManager().getNumberContainer();
// Build and add placeholder in one go
HudPlaceholder.<Number>builder()
.requiredArgsLength(0)
.function((args, event) -> player -> {
if (player.handle() instanceof org.bukkit.entity.Player p) {
return p.getLevel();
}
return 0;
})
.add("player_level", numberContainer);
// Usage in config: %player_level%
}
Placeholder with Arguments
public void registerStatPlaceholder() {
PlaceholderContainer<Number> numberContainer =
BetterHud.inst().getPlaceholderManager().getNumberContainer();
HudPlaceholder.<Number>builder()
.requiredArgsLength(1) // Requires 1 argument
.function((args, event) -> player -> {
String statName = args.get(0);
if (player.handle() instanceof org.bukkit.entity.Player p) {
return switch (statName.toLowerCase()) {
case "health" -> p.getHealth();
case "food" -> p.getFoodLevel();
case "level" -> p.getLevel();
case "exp" -> p.getExp();
default -> 0;
};
}
return 0;
})
.add("player_stat", numberContainer);
// Usage in config: %player_stat_health%
// Usage in config: %player_stat_food%
}
String Placeholder
public void registerNamePlaceholder() {
PlaceholderContainer<String> stringContainer =
BetterHud.inst().getPlaceholderManager().getStringContainer();
HudPlaceholder.<String>builder()
.requiredArgsLength(0)
.function((args, event) -> player -> player.name())
.add("player_name", stringContainer);
// Usage in config: %player_name%
}
Boolean Placeholder
import org.bukkit.entity.Player;
public void registerFlyingPlaceholder() {
PlaceholderContainer<Boolean> booleanContainer =
BetterHud.inst().getPlaceholderManager().getBooleanContainer();
HudPlaceholder.<Boolean>builder()
.requiredArgsLength(0)
.function((args, event) -> player -> {
if (player.handle() instanceof Player p) {
return p.isFlying();
}
return false;
})
.add("is_flying", booleanContainer);
// Usage in config: %is_flying%
}
Advanced: World-Specific Placeholder
public void registerWorldPlaceholder() {
PlaceholderContainer<String> stringContainer =
BetterHud.inst().getPlaceholderManager().getStringContainer();
HudPlaceholder.<String>builder()
.requiredArgsLength(1)
.function((args, event) -> player -> {
String property = args.get(0);
if (player.handle() instanceof Player p) {
return switch (property.toLowerCase()) {
case "name" -> p.getWorld().getName();
case "time" -> String.valueOf(p.getWorld().getTime());
case "difficulty" -> p.getWorld().getDifficulty().name();
default -> "unknown";
};
}
return "unknown";
})
.add("world", stringContainer);
// Usage: %world_name%, %world_time%, %world_difficulty%
}
Using Update Event Context
import kr.toxicity.hud.api.update.UpdateEvent;
public void registerEventPlaceholder() {
PlaceholderContainer<String> stringContainer =
BetterHud.inst().getPlaceholderManager().getStringContainer();
HudPlaceholder.<String>builder()
.requiredArgsLength(0)
.function((args, event) -> player -> {
// Access the update event context
return "Event: " + event.getType().name();
})
.add("event_type", stringContainer);
}
Math Operations Placeholder
public void registerMathPlaceholder() {
PlaceholderContainer<Number> numberContainer =
BetterHud.inst().getPlaceholderManager().getNumberContainer();
HudPlaceholder.<Number>builder()
.requiredArgsLength(2)
.function((args, event) -> player -> {
String operation = args.get(0);
double value = Double.parseDouble(args.get(1));
if (player.handle() instanceof Player p) {
double health = p.getHealth();
return switch (operation.toLowerCase()) {
case "add" -> health + value;
case "sub" -> health - value;
case "mul" -> health * value;
case "div" -> health / value;
default -> health;
};
}
return 0;
})
.add("health_math", numberContainer);
// Usage: %health_math_add_5%, %health_math_mul_2%
}
Conditional Placeholder
import org.bukkit.GameMode;
public void registerConditionalPlaceholder() {
PlaceholderContainer<String> stringContainer =
BetterHud.inst().getPlaceholderManager().getStringContainer();
HudPlaceholder.<String>builder()
.requiredArgsLength(0)
.function((args, event) -> player -> {
if (player.handle() instanceof Player p) {
if (p.getGameMode() == GameMode.CREATIVE) {
return "Creative Mode";
} else if (p.getGameMode() == GameMode.SURVIVAL) {
return "Survival Mode";
} else {
return p.getGameMode().name();
}
}
return "Unknown";
})
.add("gamemode_display", stringContainer);
}
Complete Placeholder Registration System
import kr.toxicity.hud.api.BetterHud;
import kr.toxicity.hud.api.placeholder.PlaceholderContainer;
import org.bukkit.plugin.java.JavaPlugin;
public class PlaceholderRegistry {
private final JavaPlugin plugin;
public PlaceholderRegistry(JavaPlugin plugin) {
this.plugin = plugin;
}
public void registerAll() {
PlaceholderContainer<Number> numbers =
BetterHud.inst().getPlaceholderManager().getNumberContainer();
PlaceholderContainer<String> strings =
BetterHud.inst().getPlaceholderManager().getStringContainer();
PlaceholderContainer<Boolean> booleans =
BetterHud.inst().getPlaceholderManager().getBooleanContainer();
// Register number placeholders
registerNumberPlaceholders(numbers);
// Register string placeholders
registerStringPlaceholders(strings);
// Register boolean placeholders
registerBooleanPlaceholders(booleans);
plugin.getLogger().info("Registered custom placeholders!");
}
private void registerNumberPlaceholders(PlaceholderContainer<Number> container) {
HudPlaceholder.<Number>builder()
.function((args, event) -> player -> {
if (player.handle() instanceof Player p) {
return p.getHealth();
}
return 0;
})
.add("health", container);
// Add more number placeholders...
}
private void registerStringPlaceholders(PlaceholderContainer<String> container) {
HudPlaceholder.<String>builder()
.function((args, event) -> player -> player.name())
.add("name", container);
// Add more string placeholders...
}
private void registerBooleanPlaceholders(PlaceholderContainer<Boolean> container) {
HudPlaceholder.<Boolean>builder()
.function((args, event) -> player -> {
if (player.handle() instanceof Player p) {
return p.isFlying();
}
return false;
})
.add("flying", container);
// Add more boolean placeholders...
}
}
Accessing Placeholder Containers
Get placeholder containers from the PlaceholderManager:
import kr.toxicity.hud.api.BetterHud;
import kr.toxicity.hud.api.manager.PlaceholderManager;
PlaceholderManager manager = BetterHud.inst().getPlaceholderManager();
// Get typed containers
PlaceholderContainer<Number> numbers = manager.getNumberContainer();
PlaceholderContainer<String> strings = manager.getStringContainer();
PlaceholderContainer<Boolean> booleans = manager.getBooleanContainer();
- HUD API - Use placeholders in HUDs
- Popup API - Use placeholders in popups
- Triggers - Placeholders can use trigger event context
See Also
- HudPlaceholder interface:
kr.toxicity.hud.api.placeholder.HudPlaceholder
- PlaceholderContainer interface:
kr.toxicity.hud.api.placeholder.PlaceholderContainer
- PlaceholderFunction:
kr.toxicity.hud.api.placeholder.HudPlaceholder.PlaceholderFunction
- PlaceholderManager:
kr.toxicity.hud.api.manager.PlaceholderManager