Guide3 min read0 sections

Scripted patrol actors

docs/SCRIPTED_PATROLS.mdSource updated 2026-10-24
Markdown
On this page 0 sections

A format-4 scene object may bind patrol: {name, color, route, conversationSeconds} to a dialogue interaction through its existing interaction field. It has an explicit authored UUID, unit scale, an invisible box render placeholder and no collider. The reusable actor rig renders the NPC through canonical PatrolActor, Transform and PlaceMembership components; it is never inserted into the room's player roster or RemoteActor lifecycle. games/engine-zoo/patrol.ts is independent reference content.

The world permits eight patrols. Names, palette selections, horizontal routes, route speed and dialogue content are validated. Patrols follow authored straight legs with waypoint waits and loop, ping-pong or one-way modes. Facing follows the current leg; explicit locomotion selects walking or idle. These scripted actors are nonblocking. Authors must provide a clear, walkable route: pathfinding, navmesh revisions, dynamic obstacle avoidance and actor collision are still roadmap work.

The existing persisted room clock drives both platforms and NPCs. An NPC-only world also receives that clock. The relay stamps incoming conversation requests with room time; the elected browser checks proximity against the moving handle at that time. Shared npcs entries store a route phase, lease deadline and owner. The first nearby speaker pauses the NPC, competing speakers are rejected, and only the owner can renew or end an active conversation. The player renews every three seconds while dialogue is open; closing the dialogue releases the pause. The authored lease is 8–30 seconds (12 for Mara), so a disconnected or closed speaker cannot hold the actor forever. Existing request deduplication, revision/epoch fencing and fsync-before-ack persistence cover these changes. The elected browser remains trusted; this is not trusted server AI.

A late join reconstructs the same route phase and conversation deadline. Host handoff does not restart the clock. Relay restart uses elapsed wall time from its persisted origin, including downtime; as with the ferry, this assumes an accurate server clock. Losing clock samples freezes the shared simulation. A locally sampled clock never regresses when a newly delivered sample trails its prior extrapolation.

Local saves retain NPC clock and pause state. Full checkpoints retain the exact canonical actor state and add the PatrolActor@1 descriptor only for content that uses it. Older worlds keep their existing catalogs and profiles. Restore validates the actor's identity, hidden source mesh, transform and component data against its authored route and saved clock; arbitrary parent changes or forged NPC component state are rejected.

The conversation UI takes its speaker name from content, including through graphics recovery. The garden playtest uses the current temporary rig; the user-requested final character redesign remains deferred. Tests cover pure route/lease rules, moving interaction admission, canonical projection, save/checkpoint round trips, stale-clock recovery, actual relay handoff/restart and rendered two-browser conversation renewal/resumption.

End of Scripted patrols