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.describe()duringsetup()to register UI metadata NameplateRegistrystores display names, targets, examples, and variant lists- The UI reads from
NameplateRegistryto populate Available Blocks
Runtime Flow
- Mods call
NameplateAPI.register()or write toNameplateDatadirectly NameplateDatastores segment text asMap<String, String>on the entityNameplateAggregatorSystemticks every frame
Aggregation Flow (Per Frame)
For each visible entity withNameplateData:
- 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
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:- An invisible “anchor” entity (
ProjectileComponent+Intangible+NetworkId) is spawned above the real entity - Nameplate text is routed to the anchor instead of the real entity
- Anchor follows the real entity every tick
- Cleaned up on death or when offset returns to zero
View-Cone Filtering
When enabled per-viewer:- Dot-product math checks if the viewer is looking at the entity
- ~25 degree half-angle cone, up to 30 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.