# 60 — BPC_AlertSystem ## Blueprint Spec — UE 5.5–5.7 --- ### Parent Class `ActorComponent` ### Dependencies - [`BPC_AIControllerBase`](55_BPC_AIControllerBase.md) — Owner controller - [`BP_EnemyBase`](58_BP_EnemyBase.md) — Pawn that receives commands - [`DA_AIProfile`](../12-content/63_DA_AIProfileDataAsset.md) — Alert thresholds and response times - [`BPC_PerceptionComponent`](56_BPC_PerceptionComponent.md) — Stimulus input source - [`BPC_AIStateMachine`](61_BPC_AIStateMachine.md) — State transition triggers - [`I_Damageable`](../01-foundation/05_I_Damageable.md) — Damage stimulus source ### Purpose Manages AI threat levels, alert escalation, and reinforcement propagation. Receives stimuli from perception and damage systems, evaluates threat severity, escalates through alert levels (Unaware → Suspicious → Alert → Combat), and notifies nearby AI units. Acts as the central threat-response coordinator for each AI. ### Enums | Enum | Values | Description | |------|--------|-------------| | `EAlertLevel` | Unaware, Suspicious, Alert, Combat | Current alert tier | | `EAlertCause` | SightStimulus, HearingStimulus, DamageTaken, AllyAlert, Environmental | What triggered the alert | ### Structs | Struct | Fields | Description | |--------|--------|-------------| | `FAlertState` | AlertLevel: EAlertLevel, AlertCause: EAlertCause, LastAlertTime: Float, SourceLocation: FVector, KnownTarget: AActor, bHasValidTarget: Bool, SuspicionValue: Float, CombatTimer: Float | Snapshot of current alert status | | `FAlertPropagationInfo` | AlertLevel: EAlertLevel, SourceLocation: FVector, Target: AActor, PropagationRadius: Float, Timestamp: Float | Data sent to nearby AI | ### Variables | Name | Type | Description | |------|------|-------------| | `CurrentAlertState` | FAlertState | Live alert tracking | | `AlertThresholds` | FVector2D | Suspicion threshold X, Combat threshold Y | | `SuspicionDecayRate` | Float | Points per second lost when no stimulus | | `SuspicionGrowthRate` | Float | Points per second gained on stimulus | | `CombatExitDelay` | Float | Time without combat before dropping to Alert | | `ReinforcementRadius` | Float | Max distance to notify allies | | `bCanCallReinforcements` | Bool | Permission to propagate | | `ReinforcementCooldown` | Float | Min seconds between calls | | `LastReinforcementTime` | Float | Cooldown tracker | | `bIsInCombat` | Bool | Fast check for combat state | | `InvestigationTimer` | Float | Time spent investigating last known position | | `MaxInvestigationTime` | Float | Give up after this long | ### Functions | Name | Inputs | Outputs | Description | |------|--------|---------|-------------| | `EvaluateStimulus` | StimulusType: EAlertCause, Intensity: Float, Location: FVector, Instigator: AActor | — | Process incoming stimulus | | `CalculateThreatScore` | StimulusType: EAlertCause, Intensity: Float, Distance: Float | Float | Compute weighted threat value | | `EscalateAlert` | NewLevel: EAlertLevel, Cause: EAlertCause | — | Raise alert level | | `DeescalateAlert` | — | — | Lower alert level (decay timer) | | `UpdateSuspicion` | DeltaTime: Float | — | Tick suspicion up/down | | `CheckAlertTransition` | — | EAlertLevel | Determine if threshold crossed | | `EnterCombat` | Target: AActor | — | Transition to combat state | | `ExitCombat` | — | — | Transition out of combat | | `CallReinforcements` | — | — | Broadcast alert to allies | | `ReceiveReinforcementCall` | Info: FAlertPropagationInfo | — | Handle ally alert broadcast | | `GetCurrentAlertLevel` | — | EAlertLevel | Getter for blackboard updates | | `GetKnownTarget` | — | AActor | Current combat target | | `IsInCombat` | — | Bool | Combat state check | | `SetInvestigationPoint` | Location: FVector | — | Mark last known target position | | `ClearInvestigationPoint` | — | — | Reset investigation | | `ShouldGiveUpSearch` | — | Bool | Timeout check for investigation | ### Blueprint Flow ``` [EvaluateStimulus] └─► Calculate Threat Score └─► If Score > AlertThresholds.Y --> Escalate to Combat └─► Else If Score > AlertThresholds.X --> Escalate to Suspicious └─► Else --> Update SuspicionValue (accumulate) └─► If AlertLevel >= Suspicious: Set Investigation Point If AlertLevel == Combat: Set KnownTarget EnterCombat If bCanCallReinforcements: CallReinforcements [Event Tick] └─► UpdateSuspicion(DeltaTime): If no stimulus: SuspicionValue -= SuspicionDecayRate * DeltaTime If SuspicionValue <= 0: DeescalateAlert (back to Unaware) If AlertLevel == Combat: CombatTimer += DeltaTime If CombatTimer > CombatExitDelay && no damage/stimulus: ExitCombat -> set AlertLevel = Alert If AlertLevel == Suspicious: InvestigationTimer += DeltaTime If InvestigationTimer > MaxInvestigationTime: ClearInvestigationPoint DeescalateAlert [CallReinforcements] └─► If (Time - LastReinforcementTime) < ReinforcementCooldown: return └─► Get all AI controllers within ReinforcementRadius └─► For each: Call ReceiveReinforcementCall with current alert info └─► LastReinforcementTime = CurrentTime [ReceiveReinforcementCall] └─► If CurrentAlertLevel >= Info.AlertLevel: ignore (already higher) └─► Else: EscalateAlert(Info.AlertLevel, Environmental) Set InvestigationPoint = Info.SourceLocation If Info.AlertLevel == Combat: Set KnownTarget = Info.Target ``` ### Event Dispatchers | Name | Delegate Signature | Purpose | |------|-------------------|---------| | `OnAlertLevelChanged` | EAlertLevel, EAlertCause | UI, sound, state machine listeners | | `OnCombatEntered` | AActor Target | Combat music, HUD, behavior tree | | `OnCombatExited` | — | Combat cleanup | | `OnReinforcementCalled` | FAlertPropagationInfo | Debug logging, analytics | | `OnInvestigationStarted` | FVector Location | Sound/investigation music | | `OnInvestigationEnded` | — | Return to patrol | ### Communications With | Target | Method | Why | |--------|--------|-----| | [`BPC_AIStateMachine`](61_BPC_AIStateMachine.md) | Call | Request state change | | [`BPC_AIControllerBase`](55_BPC_AIControllerBase.md) | Owner reference | Coordinate BB values | | [`BPC_PerceptionComponent`](56_BPC_PerceptionComponent.md) | Direct call | Get stimulus data | | [`BP_EnemyBase`](58_BP_EnemyBase.md) | Owner reference | Trigger combat animations | | [`WBP_HUD`](../06-ui/36_WBP_HUD.md) | Event dispatcher | Show combat indicator | | [`BPC_CombatFeedback`](../08-combat/54_BPC_CombatFeedbackComponent.md) | Event dispatcher | Combat music/vignette | ### Reuse Notes - Attached to AIControllerBase; profiles tune thresholds per enemy type - Works with any perception system that produces EAlertCause stimuli - Reinforcement chain prevents infinite loops by comparing alert levels - Investigation system handles "last seen" behavior without combat - Decay system ensures AI eventually returns to patrol state