Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ElectroGamesDev/HyCitizens/llms.txt

Use this file to discover all available pages before exploring further.

CitizensManager is the primary API class in HyCitizens. Every operation that creates, queries, modifies, or removes a Citizen NPC goes through this single entry point. Retrieve the singleton instance at any time through the plugin accessor:
CitizensManager manager = HyCitizensPlugin.get().getCitizensManager();

Citizen CRUD

Methods for adding, updating, and removing Citizens from the world and from persistent storage.

addCitizen

public void addCitizen(CitizenData citizen, boolean save)
Registers a new CitizenData object, spawns the NPC entity in its configured world, and fires a CitizenAddedEvent. When save is true the Citizen is also written to disk immediately.
citizen
CitizenData
required
The fully-configured Citizen to add. The id field must be unique across all loaded Citizens.
save
boolean
required
When true, persists the Citizen to disk before spawning.

updateCitizen

public void updateCitizen(CitizenData citizen, boolean save)
Replaces the in-memory record for the given Citizen and fully respawns it in-world (despawns the existing NPC and hologram, then spawns fresh). Use this when appearance, model, or world has changed.
citizen
CitizenData
required
The updated CitizenData. The id must match an already-loaded Citizen.
save
boolean
required
When true, persists changes to disk.

updateCitizenNPC

public void updateCitizenNPC(CitizenData citizen, boolean save)
Respawns only the NPC entity (model, role, equipment, stats) without touching the nametag hologram entities. Prefer this over updateCitizen when only combat stats or equipment changed.
citizen
CitizenData
required
The updated CitizenData.
save
boolean
required
When true, persists changes to disk.

updateCitizenHologram

public void updateCitizenHologram(CitizenData citizen, boolean save)
Rebuilds only the nametag hologram entities for the Citizen without respawning the NPC. Use this after changing name, hideNametag, nametagOffset, or model-nametag settings.
citizen
CitizenData
required
The updated CitizenData.
save
boolean
required
When true, persists changes to disk after the hologram update.

removeCitizen

public void removeCitizen(String citizenId)
Despawns the NPC and all hologram entities, removes the Citizen from the in-memory registry, deletes the saved config entry and role file, and fires a CitizenRemovedEvent. This operation is irreversible.
citizenId
String
required
The unique ID of the Citizen to remove.

saveCitizen

public void saveCitizen(CitizenData citizen)
Writes the current state of a CitizenData object to disk without respawning anything. Call this after mutating fields directly on a Citizen when you do not need to refresh the in-world entity.
citizen
CitizenData
required
The Citizen whose state should be persisted.

Querying Citizens

getCitizen

@Nullable
public CitizenData getCitizen(String citizenId)
Returns the CitizenData for the given ID, or null if no Citizen with that ID is loaded.
citizenId
String
required
The unique Citizen ID to look up.

getAllCitizens

@Nonnull
public List<CitizenData> getAllCitizens()
Returns a snapshot list of all currently loaded CitizenData objects. The returned list is a copy and may be iterated freely without external synchronisation.

getCitizenCount

public int getCitizenCount()
Returns the total number of Citizens currently loaded in memory.

citizenExists

public boolean citizenExists(String citizenId)
Returns true if a Citizen with the given ID is present in the manager.
citizenId
String
required
The unique Citizen ID to check.

getCitizensNear

@Nonnull
public List<CitizenData> getCitizensNear(Vector3d position, double maxDistance)
Returns all Citizens whose spawn position is within maxDistance blocks of position. The check uses the configured spawn position, not the NPC’s current live position.
position
Vector3d
required
The origin point for the distance check.
maxDistance
double
required
Maximum inclusive distance in blocks.

getCitizensByGroup

@Nonnull
public List<CitizenData> getCitizensByGroup(String groupName)
Returns all Citizens whose group field exactly matches groupName (case-sensitive, slash-normalised). Does not return Citizens in child groups — use respawnCitizensInGroup with includeChildren = true for hierarchical traversal.
groupName
String
required
The exact group path to match, e.g. "Town/Guards".

Spawning & Respawning

spawnCitizen

public void spawnCitizen(CitizenData citizen, boolean save)
Spawns the NPC entity and hologram for a Citizen that is already registered in the manager. Skips Citizens that are currently awaiting a scheduled respawn. The spawn is deferred until the target world chunk is loaded.
citizen
CitizenData
required
The Citizen to spawn. Must already exist in the manager.
save
boolean
required
When true, saves the spawned UUID to disk after spawn.

respawnAllCitizens

public int respawnAllCitizens(boolean save)
Queues a full despawn-and-respawn cycle for every loaded Citizen. Returns the number of Citizens queued for respawn. Citizens with no accessible world at the time of the call are skipped.
save
boolean
required
When true, persists each Citizen after respawning.

respawnCitizensInGroup

public int respawnCitizensInGroup(String groupName, boolean includeChildren, boolean save)
Respawns all Citizens in a specific group. When includeChildren is true, Citizens in sub-groups (e.g. Town/Guards/Elite) are also included. Passing null or an empty string for groupName respawns every Citizen. Returns the number of Citizens queued.
groupName
String
The group path to target. Pass null or "" to target all Citizens.
includeChildren
boolean
required
When true, Citizens in child group paths are also respawned.
save
boolean
required
When true, persists each Citizen after respawning.

scheduleCitizenRespawn

public void scheduleCitizenRespawn(CitizenData citizen, long delayMs)
Marks the Citizen as awaiting respawn and schedules it to be spawned after delayMs milliseconds. The pending timestamp is persisted so respawns survive server restarts. Any previously scheduled respawn for this Citizen is cancelled first.
citizen
CitizenData
required
The Citizen to schedule a respawn for.
delayMs
long
required
Delay in milliseconds before the Citizen is respawned. Values below 0 are clamped to 0.

Teleporting

teleportCitizen

public void teleportCitizen(CitizenData citizen, Vector3d position, @Nullable Vector3f rotation)
Teleports a spawned Citizen’s NPC entity to position. If rotation is non-null, the entity’s facing direction is also updated. The Citizen’s leash point is moved to the new position. Has no effect if the Citizen has no live NPC entity.
citizen
CitizenData
required
The Citizen to teleport.
position
Vector3d
required
The target world-space position.
rotation
Vector3f
Optional new rotation (pitch/yaw/roll in radians). Pass null to keep the current rotation.

teleportCitizenToSpawn

public void teleportCitizenToSpawn(CitizenData citizen)
Convenience wrapper that teleports the Citizen to its configured spawn position and rotation as stored in CitizenData.
citizen
CitizenData
required
The Citizen to return to its spawn location.

Movement Control

startCitizenPatrol

public void startCitizenPatrol(String citizenId, String pathName)
Starts a named plugin-defined patrol path for the given Citizen. The Citizen’s movement behavior type must be PATROL; otherwise the call is ignored.
citizenId
String
required
The ID of the Citizen to start patrolling.
pathName
String
required
The name of the patrol path as defined in the patrol configuration.

stopCitizenPatrol

public void stopCitizenPatrol(String citizenId)
Stops any active patrol for the specified Citizen.
citizenId
String
required
The ID of the Citizen whose patrol should be stopped.

isCitizenPatrolling

public boolean isCitizenPatrolling(String citizenId)
Returns true if the specified Citizen is currently executing a patrol path.
citizenId
String
required
The ID of the Citizen to check.

getCitizenActivePatrolPath

@Nullable
public String getCitizenActivePatrolPath(String citizenId)
Returns the name of the patrol path the Citizen is currently following, or null if the Citizen is not patrolling.
citizenId
String
required
The ID of the Citizen to query.

moveCitizenToPosition

public void moveCitizenToPosition(String citizenId, Vector3d position)
Instructs the Citizen’s movement system to navigate to position. This works through the patrol manager’s move-target mechanism.
citizenId
String
required
The ID of the Citizen to move.
position
Vector3d
required
The world-space destination.

stopCitizenMovement

public void stopCitizenMovement(String citizenId)
Cancels any active movement target for the specified Citizen, causing it to stop moving.
citizenId
String
required
The ID of the Citizen to halt.

Runtime Configuration

setCitizenCombatConfig

public void setCitizenCombatConfig(String citizenId, CombatConfig combatConfig)
Replaces the Citizen’s CombatConfig, saves, and respawns the NPC entity to apply the new settings. Has no effect if no Citizen with citizenId is loaded.
citizenId
String
required
The ID of the target Citizen.
combatConfig
CombatConfig
required
The new combat configuration to apply.

setCitizenDetectionConfig

public void setCitizenDetectionConfig(String citizenId, DetectionConfig detectionConfig)
Replaces the Citizen’s DetectionConfig, saves, and respawns the NPC entity. Has no effect if no Citizen with citizenId is loaded.
citizenId
String
required
The ID of the target Citizen.
detectionConfig
DetectionConfig
required
The new detection configuration to apply.

setCitizenPathConfig

public void setCitizenPathConfig(String citizenId, PathConfig pathConfig)
Replaces the Citizen’s PathConfig, saves, and respawns the NPC entity. Has no effect if no Citizen with citizenId is loaded.
citizenId
String
required
The ID of the target Citizen.
pathConfig
PathConfig
required
The new path configuration to apply.

forceAttackEntity

public void forceAttackEntity(CitizenData citizen, String attackInteractionId)
Forces the Citizen to use a specific attack interaction ID on its next attack cycle. Clears any existing attack overrides first. The Citizen must have a live, valid NPC entity.
citizen
CitizenData
required
The Citizen to override the attack for.
attackInteractionId
String
required
The interaction asset ID of the attack to force, e.g. "Root_NPC_Attack_Melee".

autoResolveAttackType

public void autoResolveAttackType(CitizenData citizen)
Automatically resolves the Citizen’s attack type from its modelId using the built-in model-to-interaction map and writes the result directly to citizen.getCombatConfig().setAttackType(...). Call saveCitizen and updateCitizenNPC afterward if you want the change to be persisted and applied in-world.
citizen
CitizenData
required
The Citizen whose attack type should be resolved.

Combat State

isCitizenInCombat

public boolean isCitizenInCombat(CitizenData citizen)
Returns true if the Citizen’s current AI state name contains "combat" (case-insensitive). Returns false if the NPC entity is not valid or has no state.
citizen
CitizenData
required
The Citizen to inspect.

isCitizenInAiBusyState

public boolean isCitizenInAiBusyState(CitizenData citizen)
Returns true if the Citizen is in any of the following AI states: combat, alerted, investigate, returnhome, or search. Useful for blocking interactions or follow-citizen ticks during active AI engagement.
citizen
CitizenData
required
The Citizen to inspect.

Group Management

getAllGroups

@Nonnull
public List<String> getAllGroups()
Returns all registered group paths in ascending alphabetical order. Groups are automatically created and pruned as Citizens are added or removed.

createGroup

public void createGroup(String groupName)
Explicitly creates a group (and all of its parent segments) without assigning any Citizens to it. Useful for pre-creating groups in UI workflows.
groupName
String
required
The slash-delimited group path to create, e.g. "Town/Guards".

deleteGroup

public void deleteGroup(String groupName)
Deletes a group and all of its sub-groups. All Citizens whose group matches the deleted path (or any child path) have their group reset to "" and are saved immediately.
groupName
String
required
The group path to delete.

renameGroup

public boolean renameGroup(String oldName, String newName)
Renames a group path and updates all Citizens that belong to it or any of its sub-groups. Returns false if oldName does not exist, newName already exists, or either name is blank.
oldName
String
required
The current group path.
newName
String
required
The desired new group path.

groupExists

public boolean groupExists(String groupName)
Returns true if the normalised form of groupName is registered as a group.
groupName
String
required
The group path to check.

Events

Register listeners to be notified when Citizens are added, removed, interacted with, or killed. All listener interfaces are @FunctionalInterface, so lambdas work directly.
Unregister listeners when your plugin shuts down to avoid memory leaks. Each add*Listener method has a corresponding remove*Listener counterpart.
CitizensManager manager = HyCitizensPlugin.get().getCitizensManager();

CitizenAddedListener myListener = event -> {
    System.out.println("Citizen added: " + event.getCitizen().getName());
};

manager.addCitizenAddedListener(myListener);
// Later, to unregister:
manager.removeCitizenAddedListener(myListener);
MethodEvent fired when…
addCitizenAddedListener(CitizenAddedListener) / removeCitizenAddedListenerA new Citizen is registered via addCitizen.
addCitizenRemovedListener(CitizenRemovedListener) / removeCitizenRemovedListenerA Citizen is permanently deleted via removeCitizen.
addCitizenInteractListener(CitizenInteractListener) / removeCitizenInteractListenerA player left-clicks or presses F on a Citizen. Cancellable.
addCitizenDeathListener(CitizenDeathListener) / removeCitizenDeathListenerA Citizen’s NPC entity dies. Cancellable.
See the Events reference for full details on each event, its fields, and cancellation semantics.

Build docs developers (and LLMs) love