Skip to main content
Version: 0.15.0

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.

csharp
var receiver = agent.gameObject.GetComponent<AgentInterruptReceiver>();
NameParametersReturn TypeDescription
OfferInterruptRequest requestInterruptResponseOffers the agent an interrupt. Answers at once with accepted or declined.
TryCancelN/AboolWithdraws the interrupt the agent is handling. False if there is none.
NotifyEndedInterruptRequest request, InterruptOutcome outcomevoidCalled by the tree running the reaction when it ends. You do not normally call this.
ActiveN/AInterruptRequestThe interrupt being handled, or null.
ActiveTargetN/AIInterruptTargetProviderThe target of the interrupt being handled, or null.
IsInterruptedN/AboolWhether the agent is handling an interrupt.
AgentN/AIAgentServiceThe agent this receiver is on.

InterruptRequest​

What is offered. Created once and not changed afterwards.

csharp
new InterruptRequest(kind, source, target, tierOverride, weightOverride, issuedAt);
ParameterTypeDescription
kindInterruptKindThe kind of interrupt. Decides which reaction runs.
sourceIInterruptSourceWho is offering. Told when the interrupt ends.
targetIInterruptTargetProviderOptional. Where the agent should go. Needed by the Go to Interrupt Target action.
tierOverrideAbandonTier?Optional. Used in place of the kind's default tier.
weightOverridefloat?Optional. Used in place of the kind's default weight.
issuedAtfloatOptional. The time of the offer.

InterruptResponse​

NameTypeDescription
AcceptedboolWhether the agent took the interrupt.
ReasonInterruptDeclineReasonWhy it was declined.
HostInterruptHostWhich tree is running the reaction: Work, Need or Reactive.

The reasons are checked in this order, and the first that applies is given.

ReasonWhen
DisabledInterrupts are switched off in module settings.
AgentNotReadyThe agent has not finished setting up.
AgentPausedThe agent is paused.
AlreadyInterruptedThe agent is handling another interrupt.
OnCooldownThe kind is on cooldown for this agent, or for this agent and source.
TargetInvalidThe request's target is no longer valid.
NoHandlerForKindNo tree the agent uses has a reaction for the kind.
HostUnavailableA reaction exists on the agent's job, and the agent is off shift.
AbandonRefusedThe tier does not allow cutting short the agent's current action.
GlobalCapReachedThe limit on agents being interrupted at once has been reached.

IInterruptSource​

Implement this on whatever offers the interrupt.

NameParametersReturn TypeDescription
SourceIdN/AstringA name for this source. Used by source cooldowns and the trace.
OnInterruptEndedIAgentService agent, InterruptRequest request, InterruptOutcome outcomevoidCalled once when an accepted interrupt ends.
OutcomeMeaning
CompletedThe reaction ran to its end.
FailedA step failed with nothing else to try, or the target stopped being valid.
CancelledThe interrupt was withdrawn, the receiver was disabled, or the agent's shift ended.
AbandonRefusedThe agent's action changed after accepting and could no longer be cut short.

IInterruptTargetProvider​

Where an agent goes for an interrupt.

NameParametersReturn TypeDescription
IsValidN/AboolWhether the target can still be used. The agent gives up walking to one that is not.
GoalItemN/AItemOptional. The item the agent's action is treated as using.
TryGetStandPointIAgentService agent, out Vector3 position, out Vector3? facingboolWhere the agent stands and the direction it faces.

A MarkClaim from a mark group is a ready-made target.

MarkGroup​

NameParametersReturn TypeDescription
TryReserveNearestIAgentService agent, out MarkClaim claimboolGives the agent the nearest free mark.
TryReserveint index, IAgentService agent, out MarkClaim claimboolGives the agent a particular mark, if it is free.
ReleaseIAgentService agentboolFrees the mark the agent holds.
ReleaseAllN/AvoidFrees every mark.
GetHeldIAgentService agentMarkClaimThe agent's claim, or null.
HolderOfint indexIAgentServiceThe agent holding a mark, or null.
IsOccupiedint indexboolWhether a mark is held.
HasSpaceN/AboolWhether any mark is free.
CountN/AintHow many marks the group has.
FreeCountN/AintHow many are free.
MarkReservedN/AeventRaised with the mark index and agent when a mark is taken.
MarkReleasedN/AeventRaised with the mark index and agent when a mark is freed.

IInterruptService​

Registered with the module system.

csharp
var interrupts = ModuleInitializer.GetService<IInterruptService>();
NameParametersReturn TypeDescription
EnabledN/AboolWhether interrupts are switched on.
SettingsN/AInterruptSettingsThe interrupt settings from module settings.
ActiveCountN/AintHow many agents are handling an interrupt.
RecentTraceN/AIReadOnlyList<InterruptTraceEntry>The most recent offers and results.
TryAcquireCapacityN/AboolUsed by receivers to count towards the limit.
ReleaseCapacityN/AvoidUsed by receivers when an interrupt ends.
Tracein InterruptTraceEntry entryvoidAdds an entry to the trace.

Offering an interrupt from your own code​

A bell that calls nearby agents to gather at it.

csharp
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.

csharp
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.