Documentation Index
Fetch the complete documentation index at: https://docs.nameplatebuilder.frotty27.com/llms.txt
Use this file to discover all available pages before exploring further.
This documentation is written for NameplateBuilder >= v4.260326.7 with API >= v2.2.0.
Project Modules
NameplateBuilder is split into three Gradle modules:| Module | Purpose |
|---|---|
nameplate-api | Lightweight API jar for mod developers. Contains NameplateAPI, NameplateData, SegmentTarget, and exception classes. |
nameplate-server | The server plugin. Contains the aggregator, UI, persistence, admin config, and all internal systems. |
nameplate-example-mod | Working example mod demonstrating all API patterns. |
File Tree
Data Flow
Registration Flow
- Mods call
NameplateAPI.define()duringsetup()to register UI metadata and optional resolvers NameplateRegistrystores display names, targets, examples, variant lists, and resolver functions- The UI reads from
NameplateRegistryto populate Available Blocks
Runtime Flow
- Resolvers compute text per entity automatically, or mods call
NameplateAPI.setText()/ write toNameplateDatadirectly NameplateDatastores segment text asMap<String, String>on the entityNameplateAggregatorSystemticks every frame
Aggregation Flow (Per Frame)
For each visible entity withNameplateData:
- Check per-viewer Enable Nameplates toggle - skip entirely if disabled for this viewer (sends EMPTY_UPDATE immediately when disabled)
- Check crouch state via
MovementStatesComponent.crouching- skip player entities that are crouching - Check regex pattern blacklist - skip NPC entities whose role name matches any configured pattern
- Resolve segment keys from the component (skip
_-prefixed and admin-disabled keys) - Apply viewer preferences: ordering, enabled/disabled, format variants
- Resolve variant text: check suffixed key, fall back to base key
- Apply prefix/suffix wrapping and bar fill replacement
- Enforce admin-required segments
- Composite all segments with per-block separators
- Queue nameplate update to each viewer
Entity Source Detection
The aggregator identifies entity sources to determine which entities receive nameplates. Hytale-namespace NPCs are auto-seeded as before. Mod-provided NPCs are detected by inspecting the entity’s source plugin, allowing NameplateBuilder to correctly attribute NPC entities that originate from other mods.Resolver Key Cache Invalidation
Resolver results are cached per entity based oncacheTicks(). When the admin configuration changes (e.g. a segment is required or disabled), all resolver key caches are invalidated immediately. This ensures that admin config changes take effect without waiting for individual cache timers to expire.
Death Cleanup
When an entity receives aDeathComponent:
- Aggregator sends empty nameplate to all viewers
NameplateDatacomponent is removed from the entity- If anchor entities exist for this entity, they are cleaned up
Anchor Entities
When a player configures a vertical offset for NPC entities:- An invisible “anchor” entity (
ProjectileComponent+Intangible+TransformComponent+NetworkId) is spawned above the real NPC - Nameplate text is routed to the anchor instead of the real entity
- Anchor follows the real entity every tick using velocity-based predictive positioning to compensate for the 1-tick CommandBuffer delay
- Anchors use
AddReason.LOADto prevent disk persistence during chunk saves - No explicit removal: when entities die or are removed, anchors are simply untracked and left in the world with blank nameplates until chunk unload (avoids chunk serialization race conditions)
Crouch Detection
Player nameplates are hidden when the player is crouching. The aggregator checksMovementStatesComponent.crouching on the target entity each tick. When crouching is true, the nameplate is replaced with an empty update for all viewers.
View-Cone Filtering
When enabled per-viewer (applies to NPC nameplates only - player nameplates are always visible):- Dot-product math checks if the viewer is looking at the entity
- ~25 degree half-angle cone, up to 12 blocks range
- Entities outside the cone receive an empty nameplate update
Key Design Decisions
Why ECS Components?
NameplateData is a standard Hytale ECS component. This means:
- It participates in archetype queries - the aggregator only ticks entities that have nameplate data
- It’s automatically cleaned up when entities are destroyed
- Multiple mods can read/write to it without coordination
- The
CommandBufferpattern handles structural changes safely
Why Per-Viewer?
Each player sees their own customized view of every nameplate. This enables:- Personal segment ordering and selection
- Format variant choices per segment per player
- Admin-required segments overlaid on personal preferences
- View-cone filtering based on the viewer’s camera direction
Why Tick-Based?
The aggregator runs every frame to ensure nameplate text always reflects the latest data. SincesetText() is just a HashMap.put(), the cost of frequent updates is minimal.