Interrupt Service
Description
Offers interrupts to agents, decides whether each is accepted, and reports how it ended. Interest spots and service points are built on these interfaces, and your own sources can use them the same way. See Interrupts for how kinds and reactions are authored.
AgentInterruptReceiver
The component on each agent that takes offers. It is added to every agent as it starts, unless Auto Attach Receivers is off in module settings.
var receiver = agent.gameObject.GetComponent<AgentInterruptReceiver>();
| Name | Parameters | Return Type | Description |
|---|---|---|---|
| Offer | InterruptRequest request | InterruptResponse | Offers the agent an interrupt. Answers at once with accepted or declined. |
| TryCancel | N/A | bool | Withdraws the interrupt the agent is handling. False if there is none. |
| NotifyEnded | InterruptRequest request, InterruptOutcome outcome | void | Called by the tree running the reaction when it ends. You do not normally call this. |
| Active | N/A | InterruptRequest | The interrupt being handled, or null. |
| ActiveTarget | N/A | IInterruptTargetProvider | The target of the interrupt being handled, or null. |
| IsInterrupted | N/A | bool | Whether the agent is handling an interrupt. |
| Agent | N/A | IAgentService | The agent this receiver is on. |
InterruptRequest
What is offered. Created once and not changed afterwards.
new InterruptRequest(kind, source, target, tierOverride, weightOverride, issuedAt);
| Parameter | Type | Description |
|---|---|---|
| kind | InterruptKind | The kind of interrupt. Decides which reaction runs. |
| source | IInterruptSource | Who is offering. Told when the interrupt ends. |
| target | IInterruptTargetProvider | Optional. Where the agent should go. Needed by the Go to Interrupt Target action. |
| tierOverride | AbandonTier? | Optional. Used in place of the kind's default tier. |
| weightOverride | float? | Optional. Used in place of the kind's default weight. |
| issuedAt | float | Optional. The time of the offer. |
InterruptResponse
| Name | Type | Description |
|---|---|---|
| Accepted | bool | Whether the agent took the interrupt. |
| Reason | InterruptDeclineReason | Why it was declined. |
| Host | InterruptHost | Which tree is running the reaction: Work, Need or Reactive. |
The reasons are checked in this order, and the first that applies is given.
| Reason | When |
|---|---|
| Disabled | Interrupts are switched off in module settings. |
| AgentNotReady | The agent has not finished setting up. |
| AgentPaused | The agent is paused. |
| AlreadyInterrupted | The agent is handling another interrupt. |
| OnCooldown | The kind is on cooldown for this agent, or for this agent and source. |
| TargetInvalid | The request's target is no longer valid. |
| NoHandlerForKind | No tree the agent uses has a reaction for the kind. |
| HostUnavailable | A reaction exists on the agent's job, and the agent is off shift. |
| AbandonRefused | The tier does not allow cutting short the agent's current action. |
| GlobalCapReached | The limit on agents being interrupted at once has been reached. |
IInterruptSource
Implement this on whatever offers the interrupt.
| Name | Parameters | Return Type | Description |
|---|---|---|---|
| SourceId | N/A | string | A name for this source. Used by source cooldowns and the trace. |
| OnInterruptEnded | IAgentService agent, InterruptRequest request, InterruptOutcome outcome | void | Called once when an accepted interrupt ends. |
| Outcome | Meaning |
|---|---|
| Completed | The reaction ran to its end. |
| Failed | A step failed with nothing else to try, or the target stopped being valid. |
| Cancelled | The interrupt was withdrawn, the receiver was disabled, or the agent's shift ended. |
| AbandonRefused | The agent's action changed after accepting and could no longer be cut short. |
IInterruptTargetProvider
Where an agent goes for an interrupt.
| Name | Parameters | Return Type | Description |
|---|---|---|---|
| IsValid | N/A | bool | Whether the target can still be used. The agent gives up walking to one that is not. |
| GoalItem | N/A | Item | Optional. The item the agent's action is treated as using. |
| TryGetStandPoint | IAgentService agent, out Vector3 position, out Vector3? facing | bool | Where the agent stands and the direction it faces. |
A MarkClaim from a mark group is a ready-made target.
MarkGroup
| Name | Parameters | Return Type | Description |
|---|---|---|---|
| TryReserveNearest | IAgentService agent, out MarkClaim claim | bool | Gives the agent the nearest free mark. |
| TryReserve | int index, IAgentService agent, out MarkClaim claim | bool | Gives the agent a particular mark, if it is free. |
| Release | IAgentService agent | bool | Frees the mark the agent holds. |
| ReleaseAll | N/A | void | Frees every mark. |
| GetHeld | IAgentService agent | MarkClaim | The agent's claim, or null. |
| HolderOf | int index | IAgentService | The agent holding a mark, or null. |
| IsOccupied | int index | bool | Whether a mark is held. |
| HasSpace | N/A | bool | Whether any mark is free. |
| Count | N/A | int | How many marks the group has. |
| FreeCount | N/A | int | How many are free. |
| MarkReserved | N/A | event | Raised with the mark index and agent when a mark is taken. |
| MarkReleased | N/A | event | Raised with the mark index and agent when a mark is freed. |
IInterruptService
Registered with the module system.
var interrupts = ModuleInitializer.GetService<IInterruptService>();
| Name | Parameters | Return Type | Description |
|---|---|---|---|
| Enabled | N/A | bool | Whether interrupts are switched on. |
| Settings | N/A | InterruptSettings | The interrupt settings from module settings. |
| ActiveCount | N/A | int | How many agents are handling an interrupt. |
| RecentTrace | N/A | IReadOnlyList<InterruptTraceEntry> | The most recent offers and results. |
| TryAcquireCapacity | N/A | bool | Used by receivers to count towards the limit. |
| ReleaseCapacity | N/A | void | Used by receivers when an interrupt ends. |
| Trace | in InterruptTraceEntry entry | void | Adds an entry to the trace. |
Offering an interrupt from your own code
A bell that calls nearby agents to gather at it.
public class Bell : MonoBehaviour, IInterruptSource
{
[SerializeField] InterruptKind kind;
[SerializeField] MarkGroup marks;
public string SourceId => $"bell:{GetInstanceID()}";
public void Ring(AgentInterruptReceiver receiver)
{
if (!marks.TryReserveNearest(receiver.Agent, out var claim))
return;
var response = receiver.Offer(new InterruptRequest(kind, this, claim));
if (!response.Accepted)
claim.Release();
}
public void OnInterruptEnded(IAgentService agent, InterruptRequest request, InterruptOutcome outcome)
{
(request.Target as MarkClaim)?.Release();
}
}
Reserve the mark before offering, and release it if the agent declines and again when the interrupt ends.
Cutting an action short directly
AbandonAction on the agent's action processor is what an interrupt uses to stop the current action. It can be called on its own.
var result = agent.GetActionProcessor().AbandonAction(AbandonTier.Firm);
The agent's behaviour tree is left where it was, so the same step is issued again on the agent's next update. The result is Abandoned, NoAction, or one of the refusals: RefusedEndpointStarted, RefusedActionType, RefusedCustom, RefusedPickUp or RefusedMounted. See Tiers.