CitizenData
CitizenData is the full mutable model for one citizen. You edit fields on this object, then call an appropriate CitizensManager update method to apply changes.
Field edits are not live by themselves
Changing a field does nothing in-world until you call a manager update method such as updateCitizen, updateCitizenNPC, or updateCitizenHologram.
Constructor
Use the full constructor. There is no no-arg constructor in the current API.
CitizenData citizen = new CitizenData(
"town_captain",
"Captain Rhea",
"Player",
worldUuid,
new Vector3d(0, 70, 0),
new Vector3f(0, 0, 0),
1.0f,
null,
new ArrayList<>(),
"",
"",
List.of(),
true,
false,
"Simon",
null,
0L,
true
);
Identity And Placement
| Field | Notes |
|---|---|
getId() | Unique internal key (read-only). |
getName()/setName() | Display name. \n creates multiple lines. |
getModelId()/setModelId() | Entity model ID. Use "Player" with setPlayerModel(true) for player models. |
getWorldUUID()/setWorldUUID() | Target world identity. |
getPosition()/setPosition() | Configured spawn location. |
getRotation()/setRotation() | Spawn rotation. |
getCurrentPosition() | Runtime-tracked position for moving citizens. |
After changing model/world/position/rotation, prefer manager.updateCitizen(citizen, true).
Nametag And Visibility
| Field | Meaning |
|---|---|
setHideNametag(boolean) | Hide all nametag rendering. |
setHideNpc(boolean) | Hide NPC entity body. Nametag can still render as separate entities. |
setNametagOffset(float) | Vertical nametag offset; non-zero forces separate nametag entities. |
Adaptive behavior:
- Inline NPC nameplate for single-line names, visible NPC, and offset zero.
- Separate nametag entities for multiline, hidden NPC, or non-zero offset.
hideNametag=truedisables both modes.
After changing name/visibility/offset fields, call manager.updateCitizenHologram(citizen, true).
Appearance And Skin
| Field | Notes |
|---|---|
isPlayerModel()/setPlayerModel() | Use player skin pipeline when true. |
getScale()/setScale() | NPC scale (min clamp is handled by spawn logic). |
setSkinUsername() | Username source for Mojang skin fetches. |
setUseLiveSkin() | Enable periodic skin refresh. |
setCachedSkin() | Direct cached skin control (advanced use). |
For skin changes, call manager.updateCitizenSkin(citizen, true) or manager.updateCitizenNPC(citizen, true) depending on your workflow.
Equipment
Item IDs are stored as strings. Set to null to clear.
| Setter | Slot |
|---|---|
setNpcHand(String) | Main hand |
setNpcOffHand(String) | Off hand |
setNpcHelmet(String) | Head |
setNpcChest(String) | Chest |
setNpcGloves(String) | Hands |
setNpcLeggings(String) | Legs |
After editing equipment, call:
manager.updateCitizenNPCItems(citizen);
manager.saveCitizen(citizen);
Behavior And Combat
| Field | Purpose |
|---|---|
setAttitude(String) | PASSIVE, NEUTRAL, AGGRESSIVE. |
setTakesDamage(boolean) | Damage toggle (PASSIVE remains invulnerable). |
setOverrideHealth(boolean) + setHealthAmount(float) | Custom max health. |
setOverrideDamage(boolean) + setDamageAmount(float) | Custom attack damage. |
setAttackOtherEntities(boolean) | Allow the citizen to attack non-player entities (other NPCs, mobs, etc.). |
setRotateTowardsPlayer(boolean) | Idle facing behavior. |
getLookAtDistance()/setLookAtDistance(float) | Maximum distance (blocks) at which the citizen rotates toward a player. Default: 25.0. |
After behavior/combat edits, call manager.updateCitizenNPC(citizen, true).
Respawn
| Field | Purpose |
|---|---|
isRespawnOnDeath()/setRespawnOnDeath(boolean) | Whether the citizen respawns after being killed. |
getRespawnDelaySeconds()/setRespawnDelaySeconds(float) | Seconds to wait before respawning. |
Health Regeneration
| Field | Purpose |
|---|---|
isHealthRegenEnabled()/setHealthRegenEnabled(boolean) | Toggle health regeneration. |
getHealthRegenAmount()/setHealthRegenAmount(float) | Health restored per interval tick. |
getHealthRegenIntervalSeconds()/setHealthRegenIntervalSeconds(float) | How often (in seconds) health is restored. |
getHealthRegenDelayAfterDamageSeconds()/setHealthRegenDelayAfterDamageSeconds(float) | Seconds after taking damage before regeneration resumes. |
Interaction Command Selection
@Nonnull String getCommandSelectionMode()
void setCommandSelectionMode(@Nonnull String mode)
Controls how interaction commands are selected: "ALL" (default), "RANDOM", or "SEQUENTIAL". This field lives directly on CitizenData, not inside a sub-config.
First-Time Interaction
When enabled, the first time a player interacts with a citizen they receive a unique set of messages and commands instead of the normal ones. Subsequent interactions from the same player fall back to normal behavior (or are suppressed, depending on postFirstInteractionBehavior).
| Field | Purpose |
|---|---|
isFirstInteractionEnabled()/setFirstInteractionEnabled(boolean) | Toggle the first-time interaction system. |
getFirstInteractionCommandActions()/setFirstInteractionCommandActions(List<CommandAction>) | Commands to run on first interaction. |
getFirstInteractionMessagesConfig()/setFirstInteractionMessagesConfig(MessagesConfig) | Messages to send on first interaction. |
getFirstInteractionCommandSelectionMode()/setFirstInteractionCommandSelectionMode(String) | Selection mode for first-interaction commands: "ALL", "RANDOM", or "SEQUENTIAL". |
getPostFirstInteractionBehavior()/setPostFirstInteractionBehavior(String) | What happens on subsequent interactions: "NORMAL" (default) runs the normal pipeline. |
isRunNormalOnFirstInteraction()/setRunNormalOnFirstInteraction(boolean) | If true, also runs the normal messages/commands on first interaction in addition to the first-time ones. |
getPlayersWhoCompletedFirstInteraction() | Set of player UUIDs (as strings) who have already triggered the first-time interaction. Modify to manually reset or pre-complete for specific players. |
Sub-Configs
| Config | Setter |
|---|---|
| Messages | setMessagesConfig(MessagesConfig) |
| Commands | setCommandActions(List<CommandAction>) |
| Animations | setAnimationBehaviors(List<AnimationBehavior>) |
| Movement | setMovementBehavior(MovementBehavior) |
| Path | setPathConfig(PathConfig) |
| Detection | setDetectionConfig(DetectionConfig) |
| Combat | setCombatConfig(CombatConfig) |
| Death | setDeathConfig(DeathConfig) |
Permissions And Grouping
| Field | Notes |
|---|---|
setRequiredPermission(String) | Permission gate for interactions. |
setNoPermissionMessage(String) | Message when permission check fails. |
setGroup(String) | Group label for batch operations. |
Runtime State (Read Mostly)
| Getter | What it represents |
|---|---|
getSpawnedUUID() | Current NPC entity UUID, if spawned. |
getNpcRef() | Current live entity ref (check validity before use). |
getHologramLineUuids() | Separate nametag entity UUID list (internal/runtime, normally do not set manually). |
getSequentialMessageIndex() | Per-player sequential message progress. |
Practical Pattern
CitizenData citizen = manager.getCitizen("gate_guard");
if (citizen == null) {
return;
}
citizen.setName("Gate Guard");
citizen.setHideNpc(false);
citizen.setHideNametag(false);
citizen.setNametagOffset(0f);
manager.updateCitizenHologram(citizen, true);