
DisplayUIEngine
A server-side engine for creating and managing interactive display-based UIs in Minecraft.
Список изменений
!Banner
HaoHan Display UI
HaoHan Display UI is a standalone engine plugin for building interactive, in-world interfaces on Paper and Purpur servers. It gives plugin developers a document-based API for composing text, items, blocks, buttons, and layered panels with Minecraft Display Entities.
The engine handles entity spawning, layout, interaction, visibility, updates, camera transforms, and cleanup. Consumer plugins remain responsible for deciding what the interface represents, making the engine suitable for machine controls, guide boards, paginated menus, item catalogs, command panels, documentation links, and private player interfaces.
HaoHan Display UI is a developer engine, not a ready-made gameplay menu. Install it when another plugin requires it, or use the built-in demo to explore its capabilities.
Why use HaoHan Display UI?
Display Entity interfaces normally require a large amount of repeated work: coordinate conversion, entity lifecycle management, rotation-aware raycasting, per-player visibility, text alignment, and click handling. HaoHan Display UI provides these systems behind one consistent API so consumer plugins can focus on their own gameplay logic.
No client mod is required. Players can join with a vanilla client, and a resource pack is optional unless a consumer plugin uses custom fonts or models.
Features
| Area | Included capabilities |
|---|---|
| Rendering | TextDisplay, ItemDisplay, BlockDisplay, layered panels, and depth ordering |
| Text | Adventure Components, RGB colors, multi-stop gradients, decorations, and animated text updates |
| Layout | Logical-pixel coordinates, box alignment, vertical placement, offsets, optical presets, and icon-plus-text rows |
| Interaction | Rotation-aware raycasting, invisible hit zones, hover descriptions, hit slop, callbacks, and Bukkit events |
| Actions | Safe URL prompts, player commands, console commands, and suggested commands |
| Camera | Fixed, yaw-only, pitch-only, camera-facing, per-axis locks, and X/Y/Z angle offsets |
| Visibility | Per-player audiences, manual show/hide overrides, front-face checks, and view-distance limits |
| Lifecycle | Update, move, chunk respawn, owner-based removal, and automatic orphan cleanup |
| Optimization | In-place text updates, visibility caching, and metadata updates only for changed nodes |
Requirements
- Minecraft
1.21.11 - Paper or Purpur server
- Java 21 or newer
- No client-side installation
- No required dependencies
Installation
- Download the latest
HaoHanDisplayUIJAR. - Place it in the server's
plugins/directory. - Restart the server.
- Run
/hhdui infoto verify that the API service is available. - Run
/hhdui demoin game to open the built-in five-page demonstration.
Avoid /reload on production servers when consumer plugins retain UI handles. A clean restart provides predictable lifecycle behavior.
For plugin developers
Declare HaoHan Display UI as a required dependency in the consumer plugin's plugin.yml:
depend: [HaoHanDisplayUI]
The API can currently be published to Maven Local from source:
gradle publishToMavenLocal
Then add it to the consumer project:
repositories {
mavenLocal()
}
dependencies {
compileOnly 'dev.haohansmp:HaoHanDisplayUI:1.0.0'
}
Load the service
HaoHan Display UI registers its public API through Bukkit's ServicesManager:
DisplayUiService ui = Bukkit.getServicesManager().load(DisplayUiService.class);
if (ui == null) {
throw new IllegalStateException("HaoHanDisplayUI is not installed");
}
Create an interface
Documents are immutable snapshots. Add visual nodes and interaction zones, then create a scene at a world location:
AlignedTextNode title = new AlignedTextNode(
Component.text("Ancient Forge", NamedTextColor.GOLD),
-80, -48,
160, 18,
UiTextAlignment.LEFT
)
.fontSize(10)
.shadowed(true);
UiIconNode icon = new UiIconNode(
new ItemStack(Material.GOLD_INGOT),
-76, -18,
24, 24,
16, 16
);
UiDocument document = UiDocument.builder()
.add(new BlockNode(
Material.BLACK_CONCRETE.createBlockData(),
-90, -58, 0,
180, 116, 2
))
.add(title)
.add(icon)
.button(UiButton.forIcon("gold", icon)
.describedBy(Component.text("Gold ingot", NamedTextColor.YELLOW)))
.build();
UiHandle handle = ui.create(
"example:forge_panel",
panelLocation,
document,
UiOptions.defaults(),
player -> player.hasPermission("example.forge.use")
);
handle.onClick(click -> {
if (click.button().id().equals("gold")) {
click.player().sendMessage("Gold clicked");
}
});
The default coordinate system uses logical pixels: X increases to the right, Y increases downward, and larger depth values render closer to the viewer. The default scale is 40 logical pixels per block.
Update and remove scenes
Keep the returned UiHandle for as long as the corresponding menu or machine exists:
handle.update(nextDocument);
handle.move(nextLocation);
handle.audience(nextAudience);
handle.cameraTransform(UiCameraTransform.cameraFacing());
handle.show(player);
handle.hide(player);
handle.remove();
Call remove() when the owning object is removed. Modules can also use removeOwnedBy(ownerKey) to clean up every scene under a namespaced owner key.
Interaction and actions
Buttons use invisible hit zones in the same logical-pixel space as the document. The engine projects the player's camera ray onto the transformed UI plane, resolves the nearest matching button, fires UiButtonClickEvent, and then runs the configured action or callback if the event was not cancelled.
Built-in actions include:
UiButtonAction.openUrl("https://example.com");
UiButtonAction.playerCommand("warp spawn");
UiButtonAction.consoleCommand("give {player} diamond");
UiButtonAction.suggestCommand("msg {player} hello");
URL actions always require client confirmation. Console actions run with full server authority and must only be created from trusted code or configuration.
Camera and visibility
Interfaces can remain fixed in the world, follow the camera, or lock selected axes. Rotation is applied consistently to rendering and raycasting, so buttons remain aligned with tilted or camera-facing content.
Scenes can be limited to a player or group with an audience predicate. View distance, front-face requirements, and runtime show/hide overrides provide additional control without requiring separate documents for every player.
Commands and permissions
| Command | Description |
|---|---|
/hhdui info | Show the active scene count and registered API service |
/hhdui demo | Open a private five-page feature demonstration |
/hhdui clear | Remove all managed demo scenes |
Administrative commands require haohansmp.displayui.admin, which is granted to server operators by default.
Demo contents
The built-in demo covers rich and animated text, item lists, icon-and-text rows, hover and click interactions, camera modes, axis locks, rotations, URLs, and command actions. Aim at a button to display its hover description, right-click to interact, and use the footer arrows to switch pages.
Performance guidance
Display Entities do not have mob AI or pathfinding, but they are still tracked server entities. A scene containing roughly 10–30 displays is normally lightweight. For larger systems:
- Create scenes only when they are needed.
- Use appropriate audiences and view distances.
- Prefer text-only updates for animations.
- Do not rebuild unchanged documents every tick.
- Remove scenes when their owning menu or machine is deleted.
- Avoid thousands of persistent displays or high-frequency metadata animations.
Source and documentation
- Source code and full API documentation
- HaoHanSMP website
