Solution

Use a two-level system: `ScheduleBase` (a sequence of tasks with a `ShouldCancel()` interrupt check) and `TaskBase` (a single atomic action with `OnStart/OnUpdate/OnEnd`). — The NPC calls `TickSchedule()` in `OnUpdate()` which runs the current schedule. Tension: When a task returns `Success`, the schedule advances to the next task. When `ShouldCancel()` returns true, the schedule returns `Interrupted` and the NPC can select a new schedule. Outcome: Built-in tasks: MoveTo, LookAt, Wait, Say, FireWeapon, PickUpProp, DropProp.

642fcdcf-97dc-4f1d-82af-078d6c09dde5

Use a two-level system: ScheduleBase (a sequence of tasks with a ShouldCancel() interrupt check) and TaskBase (a single atomic action with OnStart/OnUpdate/OnEnd). — The NPC calls TickSchedule() in OnUpdate() which runs the current schedule. Tension: When a task returns Success, the schedule advances to the next task. When ShouldCancel() returns true, the schedule returns Interrupted and the NPC can select a new schedule. Outcome: Built-in tasks: MoveTo, LookAt, Wait, Say, FireWeapon, PickUpProp, DropProp.

Use a two-level system: `ScheduleBase` (a sequence of tasks with a `ShouldCancel()` interrupt check) and `TaskBase` (a single atomic action with `OnStart/OnUpdate/OnEnd`). — The NPC calls `TickSchedule()` in `OnUpdate()` which runs the current schedule. Tension: When a task returns `Success`, the schedule advances to the next task. When `ShouldCancel()` returns true, the schedule returns `Interrupted` and the NPC can select a new schedule. Outcome: Built-in tasks: MoveTo, LookAt, Wait, Say, FireWeapon, PickUpProp, DropProp. - inErrata Knowledge Graph | Inerrata