Skip to main content
This documentation is written for NameplateBuilder >= v4.260326.7 with API >= v2.2.0.
This page covers features you’ll rarely need, but are good to know about.

Replacing Built-in Segments

When your mod provides a better name for an entity than the default role name, use replaces() to automatically hide the built-in segment on entities where your segment has a value. On all other entities, the built-in segment shows normally. Why this exists: NameplateBuilder uses one chain per entity type (NPC/Player). All NPCs share the same chain. Without replaces, a player who has both “Entity Name” and “Pet Name” in their chain would see Bear - Fluffy on a named pet. With replaces, they see just Fluffy on the pet and Bear on wild NPCs - without changing anything in their chain.
How it works:
  • When your resolver returns a value (e.g. "Fluffy") for an entity, the target segment (entity-name) is hidden for that entity
  • When your resolver returns null (entity has no pet name), the target segment shows normally
  • The replacement is per-entity - it only affects entities where your segment has a value
  • Players do not need to change their chain. Both segments can be in the chain, and the right one shows automatically
  • Multiple segments can replace the same target. They all show - only the target is hidden
Restrictions:
  • replaces() can only target NameplateBuilder’s built-in segments: entity-name, player-name, health, stamina, mana
  • A segment cannot replace itself
  • Circular replacements (A replaces B, B replaces A) are safe - neither gets suppressed
When to use it: When your segment provides a context-specific version of information that a built-in segment already shows. Common examples:
  • A pet naming mod replacing entity-name with the pet’s custom name
  • A disguise mod replacing player-name with a fake name
  • A shield mod replacing health with a combined health+shield display
When NOT to use it: When your segment shows additional information alongside the built-in (like elite tier, guild tag, or buff icons). Those should be separate segments in the chain, not replacements.

Default Segments

By default, new players start with empty chains and have to manually add segments via /npb. If you want your segment to appear in a player’s chain automatically (so it works out of the box), use enabledByDefault():
This adds the segment to both the NPC and Player chains for any player who hasn’t customized their chains yet. Once a player edits their chain in /npb, their preferences take over and the default no longer applies. You can also target a specific chain:
Limit: Each mod can mark at most 3 segments as enabledByDefault. This prevents mods from flooding new players’ chains. If you exceed the limit, NameplateBuilder logs a warning and ignores the extra defaults.

Hidden Metadata Keys

Sometimes you need to store per-entity data alongside your visible segments - things like spawn timestamps, internal state flags, or tracking counters. You don’t want players to see this data in their nameplate. Any key that starts with _ (underscore) is hidden. It’s stored in the NameplateData component like any other key, but NameplateBuilder’s aggregator skips it when building the nameplate text. It never appears in the player UI either.
Why use this instead of a separate ECS component? Convenience. If you only need a couple of small values per entity and they’re closely tied to your nameplate logic, hidden keys save you from registering and managing a separate component. For larger or more structured data, a dedicated component is still the better choice.

Automatic Cleanup

NameplateBuilder handles two cleanup scenarios automatically. You don’t need to write any code for either.

Entity Death

When an entity receives a DeathComponent, NameplateBuilder immediately:
  1. Sends an empty nameplate to all viewers (clears the text above the entity)
  2. Removes the NameplateData component from the entity
This prevents stale nameplate text from lingering during death animations.

Plugin Unload

When your mod is unloaded (server shutdown, hot reload, etc.), NameplateBuilder automatically removes all segment definitions that your plugin registered. You don’t need a shutdown hook or cleanup code.

Removing a Segment at Runtime with undefine()

In rare cases, you might want to remove a segment from the UI while the server is running. For example, a minigame mod that adds segments when a game starts and removes them when it ends:
After calling undefine():
  • The segment disappears from the /npb UI
  • Players who had it in their chain no longer see it rendered
  • Any NameplateData text on entities is not removed - it stays until the entity dies or you explicitly clear it
Most mods will never need this. If your segment exists for the lifetime of your plugin, the automatic plugin-unload cleanup is sufficient.

Common Mistakes

Using store.addComponent() inside a tick system

Problem: The entity store is locked during tick processing. Adding a component directly throws IllegalStateException: Store is currently processing. Fix: Use commandBuffer.putComponent() instead. The CommandBuffer queues the change and applies it after the tick finishes. See Manual Text - Tick System Pattern.

Using NameplateAPI.setText() inside a tick system on a new entity

Problem: setText() tries to add a NameplateData component if the entity doesn’t have one, which hits the same store-lock issue. Fix: Build a NameplateData object manually and use commandBuffer.putComponent():

Forgetting the manifest dependency

Problem: Calling any NameplateAPI method throws NameplateNotInitializedException. Fix: Add the dependency to your manifest.json:

Calling undefine() in a shutdown hook

Problem: Unnecessary - NameplateBuilder already cleans up all your segments when your plugin unloads. Fix: Remove the undefine() call from your shutdown code.

Removing nameplate data on entity death

Problem: Unnecessary - NameplateBuilder already handles death cleanup automatically. Fix: Remove your death-cleanup code. Let NameplateBuilder handle it.

Not handling the default case in variant switches

Problem: If a player selects a variant index your resolver doesn’t handle, it returns null and the segment disappears. Fix: Always include a default case that returns the base format:

Complete Plugin Example

A full plugin using both resolvers and manual text, with format variants:

Further Reading