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.

PatrolManager controls all patrol path operations for spawned Citizens. It is accessible via CitizensManager.getPatrolManager() and runs an internal monitor loop every 250 ms that ticks each active patrol session, handles waypoint advancement, pause durations, and automatic stuck-recovery logic.
PatrolManager patrolManager = HyCitizensPlugin.get().getCitizensManager().getPatrolManager();
Most patrol operations are available directly on CitizensManager and are the recommended entry point for external plugins. PatrolManager exposes lower-level path management for cases where direct access is needed.

CitizensManager Patrol Methods

These methods on CitizensManager are the preferred API for controlling patrols from an external plugin. They delegate to PatrolManager internally and include additional validation (for example, startCitizenPatrol checks that the Citizen’s movement behavior type is PATROL before starting).

startCitizenPatrol(String citizenId, String pathName)

Starts a patrol for the given Citizen along the named path. The Citizen’s movementBehavior.type must equal "PATROL" or the call is silently ignored. The path must exist and contain at least one waypoint.
manager.startCitizenPatrol("guard-001", "NorthWallPatrol");

stopCitizenPatrol(String citizenId)

Cancels the active patrol session for the Citizen and removes its move-target marker entity from the world.
manager.stopCitizenPatrol("guard-001");

isCitizenPatrolling(String citizenId)

Returns true if the Citizen currently has an active patrol session running.
boolean patrolling = manager.isCitizenPatrolling("guard-001");

getCitizenActivePatrolPath(String citizenId)

Returns the name of the patrol path the Citizen is currently walking, or null if the Citizen is not patrolling.
String pathName = manager.getCitizenActivePatrolPath("guard-001");

moveCitizenToPosition(String citizenId, Vector3d position)

Cancels any active patrol and moves the Citizen toward a specific world position by spawning a move-target marker entity at that location.
manager.moveCitizenToPosition("guard-001", new Vector3d(100, 64, 200));

stopCitizenMovement(String citizenId)

Stops all movement for the Citizen — equivalent to calling stopCitizenPatrol and removing the move-target marker.
manager.stopCitizenMovement("guard-001");

renamePatrolPath(String oldName, String newName)

Renames a patrol path and updates every CitizenData record that references the old name in either PathConfig.pluginPatrolPath or PathConfig.pathName. Returns false if the rename fails because the old name was not found or the new name already exists.
boolean success = manager.renamePatrolPath("OldPath", "NewPath");

Direct PatrolManager Methods

These methods bypass the CitizensManager validation layer. Use them when you need lower-level access — for example, when starting a patrol from a schedule entry or in contexts where the movement-behavior check is not appropriate.
MethodReturnsDescription
startPatrol(String citizenId, String pathName)voidStarts a patrol session directly.
stopPatrol(String citizenId)voidStops a patrol session and cleans up the move target.
moveCitizenToPosition(String citizenId, Vector3d position)voidCancels any active patrol and moves the Citizen toward the given position by placing a fresh move-target marker there.
stopMoving(String citizenId)voidAlias for stopPatrol — stops all movement and removes the move-target marker.
isPatrolling(String citizenId)booleanReturns true if an active session exists.
isPatrolPaused(String citizenId)booleanReturns true if the Citizen is currently in a waypoint pause.
getActivePatrolPath(String citizenId)String (nullable)Active path name, or null if not patrolling.
renamePath(String oldName, String newName)booleanRenames a path in memory and on disk; returns false on failure.
updateMoveTargetPosition(String citizenId, Vector3d position)voidUpdates the position of the existing move-target marker without replacing it.
ensureMoveTargetNow(CitizenData citizen, World world, Vector3d position)voidEnsures a move-target marker entity exists at the given position, creating one if necessary.
getPath(String name)PatrolPath (nullable)Returns the named path, or null if it does not exist.
getAllPaths()Collection<PatrolPath>Returns an unmodifiable view of all loaded patrol paths.
getAllPathNames()List<String>Returns a sorted list of all path names.
savePath(PatrolPath path)voidPersists a path to the config file.
deletePath(String name)booleanRemoves a path from memory and disk.
addWaypoint(String pathName, PatrolWaypoint waypoint)booleanAppends a waypoint to an existing path.
removeWaypoint(String pathName, int index)booleanRemoves the waypoint at the given index.
setWaypointPause(String pathName, int index, float pauseSeconds)booleanSets the pause duration at a specific waypoint.

Patrol Path Data Model

PatrolPath

FieldTypeDescription
nameStringUnique identifier for the path.
loopModePatrolPath.LoopModeEither LOOP (wrap around) or PING_PONG (reverse at each end).
waypointsList<PatrolWaypoint>Ordered list of waypoints the Citizen walks between.

PatrolWaypoint

FieldTypeDescription
x, y, zdoubleWorld position of this waypoint.
pauseSecondsfloatTime in seconds the Citizen waits at this waypoint before continuing (0 = no pause).
Patrol paths are persisted to the mods/HyCitizensData/ config under the paths.* key and are loaded automatically on startup.

Stuck Recovery

The patrol monitor automatically detects Citizens that stop making progress toward a waypoint. After 10 000 ms without movement it attempts up to three escalating recovery stages:
  1. Soft reset — the move-target marker position is refreshed in place.
  2. Route reset — the Citizen is redirected to the nearest waypoint.
  3. Teleport reset — the Citizen is teleported back to its spawn position and the patrol restarts from waypoint 0.

Code Example

CitizensManager manager = HyCitizensPlugin.get().getCitizensManager();

// Start a patrol
manager.startCitizenPatrol("guard-001", "NorthWallPatrol");

// Check patrol status
if (manager.isCitizenPatrolling("guard-001")) {
    System.out.println("Currently patrolling: " + manager.getCitizenActivePatrolPath("guard-001"));
}

// Stop patrol
manager.stopCitizenPatrol("guard-001");

// Rename a path (also updates all Citizens using it)
boolean renamed = manager.renamePatrolPath("OldPath", "NewPath");

Build docs developers (and LLMs) love