Skip to main content

NPC and Boss Patrols

EliteMobs can make configured NPCs and Custom Bosses follow authored routes using native Minecraft navigation. The same route system also gives Lua scripts controlled walk_to, hold, and teleport operations.

Quick authoring workflow

  1. Spawn or place the NPC or Custom Boss you want to edit.
  2. Look directly at it from within 12 blocks and run /em patrol edit.
  3. Stand at each destination and run /em patrol add. Node 0 is the actor's authored spawn location.
  4. Use /em patrol mode LOOP to connect the last node back to the first, or /em patrol mode REVERSE to walk back through the list.
  5. Run /em patrol save to write the route and refresh that actor.

The editor previews the resolved walk, not just straight lines between nodes. /em patrol undo, /em patrol remove, /em patrol status, and /em patrol cancel are available while authoring. All patrol authoring commands are player-only and require elitemobs.patrol.admin.

If one NPC file has several spawnLocations, saving a route for one placed NPC creates a separate leaf NPC file for that location. This prevents one set of relative offsets from being applied to every copy of the NPC.

Configuration

Patrol nodes are x,y,z offsets from the actor's authored spawn location, not absolute world coordinates.

patrol:
enabled: true
mode: LOOP
speed: 1.0
virtualSpeed: 0.2
nodes:
- 0,0,0
- 1000,0,0
- 1000,0,250
KeyValuesDefaultDescription
patrol.enabledtrue / falsetrue when nodes existEnables this route.
patrol.modeLOOP / REVERSELOOPLOOP connects the final node to node 0; REVERSE walks back through the list.
patrol.speedpositive number1.0Native navigation speed multiplier.
patrol.virtualSpeedpositive numberobserved movement speedBlocks advanced per tick while a persistent actor has no loaded body. Usually leave this unset.
patrol.nodeslist of at least two offsetsnoneOrdered route destinations. String entries (x,y,z) and x/y/z maps are accepted.

There is no public maximum-leg setting. A 1,000-block leg is valid. The old experimental patrol.maxLegDistance key is obsolete and has no effect.

Long-distance pathfinding

Long legs are solved automatically. EliteMobs asks MagmaCore for a rolling route through the currently loaded terrain, splits it into short native-navigation destinations, and replans as the actor advances.

Terrain access and route search are deliberately separated:

  • Loaded chunk snapshots are captured on the server thread through MagmaCore's shared tick-budget workload system.
  • The bounded A* search runs asynchronously over those immutable snapshots.
  • The final short legs are still validated and walked by Minecraft's native pathfinder.
  • Patrol planning never force-loads chunks. If the next terrain is unavailable, the actor waits at the end of the last verified path and continues when that area is entity-ticking again.

This makes routes across a city practical without scanning the whole city in one tick or pretending a straight line through an unloaded building is safe. Flying and aquatic mobs use volume-aware searches; ground mobs require support and clearance and avoid common hazards.

Actor behavior

  • NPC patrols automatically enable the NPC body's AI and custom-model movement synchronization. syncMovement still controls non-patrol custom-model behavior, but it is not a second patrol switch.
  • Custom Boss patrols require ai: true, a positive movement speed, and a body that is not riding another entity.
  • A boss pauses its patrol during combat and resumes afterward.
  • Persistent NPCs and persistent non-instanced bosses retain their safe route position in patrol-state.yml across chunk detachment and reloads.
  • An actor only rematerializes inside the entity-ticking area. Unloaded or unknown terrain freezes route time instead of moving the actor through unchecked blocks.
  • A passenger cannot own a patrol; route its mount instead.

Lua control

These methods exist on context.npc and context.boss when that actor has a configured patrol controller. Coordinates are offsets from the actor's authored spawn location, and each method returns whether the request was accepted.

MethodBehavior
patrol_pause()Stops the current route without losing its configuration.
patrol_resume()Clears a scripted hold or temporary walk and resumes the configured route.
walk_to(x, y, z)Walks to the offset, then resumes the configured patrol.
hold(x, y, z)Walks to the offset and stays there until patrol_resume() is called.
teleport(x, y, z)Teleports to the offset when that destination is in the entity-ticking area, then resumes the route.
return {
api_version = 1,
on_npc_interact = function(context)
context.npc:walk_to(40, 0, -12)
end
}

walk_to uses the same long-distance solver as configured patrol legs. It does not require authors to break a distant destination into manual waypoints.

Diagnostics

Look at the actor and run /em patrol status. The output includes its runtime state, current and target node, route fraction, logical location, virtual speed, whether a body is present, and any hold reason. terrain_unavailable means the planner is waiting for loaded, entity-ticking terrain; it is not a failed straight-line movement attempt.