# BPC_RareEventSystem — Rare Event System ## Blueprint Spec — UE 5.5–5.7 --- ### Parent Class `ActorComponent` ### Dependencies - **Requires:** [`DA_RareEvent`](../14-data-assets/DA_RareEvent.md) — Rare event definitions with probability and conditions - **Requires:** [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) — Reads narrative flags for eligibility conditions - **Required By:** [`BPC_AdaptiveEnvironmentDirector`](BPC_AdaptiveEnvironmentDirector.md) — Requests rare event roll - **Engine/Plugin Requirements:** GameplayTags, Timer system, Random stream ### Purpose Controls ultra-rare, randomised world events that can occur once per session or with very low probability: hidden messages, brief hallucinations, entity sightings, environmental easter eggs. Tracks which rare events have already fired to prevent repeats and evaluates complex eligibility conditions. --- ## 1. Enums *No new enums defined. Uses GameplayTags for event and condition identification.* --- ## 2. Structs ### `S_RareEventCondition` | Field | Type | Description | |-------|------|-------------| | `RequiredFlags` | Array of GameplayTag | All must be true for eligibility | | `ForbiddenFlags` | Array of GameplayTag | None must be true for eligibility | | `RequiredPlaystyleTag` | GameplayTag | Player must currently have this playstyle | | `MinSessionTime` | Float | Minimum session elapsed seconds | | `MinDeathCount` | Integer | Minimum player deaths this session | | `RequiredChapterTag` | GameplayTag | Current chapter must match | --- ## 3. Variables ### Configuration (Instance Editable, Expose On Spawn) | Variable | Type | Default | Category | Description | |----------|------|---------|----------|-------------| | `RareEventPool` | Array of DA_RareEvent | Empty | RareEventConfig | All available rare events for this session | ### Internal (Private / Protected, No Expose) | Variable | Type | Default | Category | Description | |----------|------|---------|----------|-------------| | `FiredRareEvents` | Set of GameplayTag | Empty | Internal | Already triggered rare events (prevent repeat) | | `EligibilityConditions` | Map (GameplayTag → S_RareEventCondition) | Empty | Internal | Resolved eligibility conditions per event | | `RollTimer` | TimerHandle | — | Internal | Periodic roll timer | | `RollInterval` | Float | 60.0 | Internal | Seconds between rare event roll checks | --- ## 4. Functions ### Public Functions #### `RollForRareEvent` → `DA_RareEvent` - **Description:** Evaluates all eligible rare events, rolls probability, and returns a selected event (or None). Fires the event if one is selected. - **Parameters:** None - **Blueprint Authority:** Any - **Flow:** Filter pool by eligibility → exclude fired events → for each eligible, roll probability → if roll passes, select and fire → add to FiredRareEvents → broadcast OnRareEventFired → return selected event #### `IsEventEligible` → `Bool` - **Description:** Checks if a specific rare event's conditions are currently met. - **Parameters:** | Param | Type | Description | |-------|------|-------------| | `EventTag` | GameplayTag | Rare event identifier | - **Blueprint Authority:** Any - **Flow:** Read S_RareEventCondition from map → check RequiredFlags against narrative state → check ForbiddenFlags → check playstyle match → check session time → check death count → check chapter → return true if all pass #### `ForceRareEvent` → `void` - **Description:** Fires a specific rare event immediately, bypassing probability and eligibility checks. - **Parameters:** | Param | Type | Description | |-------|------|-------------| | `EventTag` | GameplayTag | Rare event to fire | - **Blueprint Authority:** Any #### `GetFiredEvents` → `Set of GameplayTag` - **Description:** Returns all rare events that have already fired this session. - **Parameters:** None - **Blueprint Authority:** Any #### `GetEligibleEvents` → `Array of DA_RareEvent` - **Description:** Returns all rare events that are currently eligible (conditions met, not yet fired). - **Parameters:** None - **Blueprint Authority:** Any #### `ResetSession` → `void` - **Description:** Clears fired events and resets eligibility. Called on new game. - **Parameters:** None - **Blueprint Authority:** Any #### `SetRollInterval` → `void` - **Description:** Adjusts the periodic roll check interval. - **Parameters:** | Param | Type | Description | |-------|------|-------------| | `Interval` | Float | New interval in seconds | - **Blueprint Authority:** Any --- ## 5. Event Dispatchers | Dispatcher | Parameters | Bind Access | Description | |------------|-----------|-------------|-------------| | `OnRareEventFired` | EventTag: GameplayTag | Public | A rare event was triggered | | `OnRareEventFailed` | EventTag: GameplayTag | Public | Probability roll failed for an eligible event | | `OnAllRareEventsFired` | — | Public | All events in pool have been fired | --- ## 6. Overridden Events / Custom Events ### Event: `BeginPlay` - **Description:** Initialises the rare event pool and starts the periodic roll timer. - **Flow:** 1. Build EligibilityConditions map from RareEventPool entries 2. Start RollTimer with RollInterval 3. Perform initial roll check ### Event: `TickRoll` - **Description:** Timer callback. Performs a rare event roll check. - **Flow:** 1. Call RollForRareEvent 2. If event fired → broadcast OnRareEventFired 3. If all events in pool are fired → stop timer and broadcast OnAllRareEventsFired --- ## 7. Blueprint Graph Logic Flow ```mermaid flowchart TD A[BeginPlay] --> B[Build EligibilityConditions map] B --> C[Start RollTimer at RollInterval] C --> D[Timer fires] D --> E[GetEligibleEvents] E --> F{Any eligible events?} F -->|No| G[Wait for next tick] F -->|Yes| H[For each eligible event:] H --> I[Roll random against DA_RareEvent.Probability] I --> J{Roll <= Probability?} J -->|Yes| K[Fire the rare event] J -->|No| L[Broadcast OnRareEventFailed] K --> M[Add to FiredRareEvents] M --> N[Broadcast OnRareEventFired] N --> O{All events fired?} O -->|Yes| P[Stop RollTimer] O -->|No| G L --> H P --> Q[Broadcast OnAllRareEventsFired] ``` --- ## 8. Communication Matrix | Who Talks | How | What Is Sent | |-----------|-----|-------------| | [`BPC_AdaptiveEnvironmentDirector`](BPC_AdaptiveEnvironmentDirector.md) | Direct call | `RollForRareEvent()` | | [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) | Direct read | Narrative flags for eligibility condition checks | | [`BPC_PlaystyleClassifier`](BPC_PlaystyleClassifier.md) | Direct read | `CurrentPlaystyleTag` for playstyle-gated events | | [`GS_CoreGameState`](../01-core/06_GS_CoreGameState.md) | Direct read | `ElapsedPlayTime`, `ActiveChapterTag` | | [`DA_RareEvent`](../14-data-assets/DA_RareEvent.md) | Data asset read | Event def: tag, probability, conditions, actions | --- ## 9. Validation / Testing Checklist - [ ] S_RareEventCondition struct has all 6 fields - [ ] RareEventPool is populated with DA_RareEvent assets - [ ] IsEventEligible correctly checks all condition types - [ ] RollForRareEvent respects probability values (0.0 = never, 1.0 = always) - [ ] FiredRareEvents prevents repeat triggering - [ ] ForceRareEvent bypasses all checks for scripted/debug use - [ ] RollTimer stops when all events exhausted - [ ] Edge case: RareEventPool empty → no errors, timer still runs harmlessly - [ ] Edge case: all events fired → OnAllRareEventsFired broadcasts once - [ ] Edge case: rapid probability rolls don't fire same event twice (FiredRareEvents set check) --- ## 10. Reuse Notes - RareEventPool is population-defined — populate per project with unique events - Probability values in DA_RareEvent are designer-tuned per event (0.001 for ultra-rare, 0.1 for uncommon) - Eligibility conditions support complex gating (chapter, playstyle, time, death count) - For non-horror games, fill pool with easter eggs and hidden secrets instead of scary events - Extend S_RareEventCondition with project-specific gates (e.g., specific item held, specific ending achieved) --- *Specification based on Master Section 9.9, line 2922.*