203 lines
8.1 KiB
Markdown
203 lines
8.1 KiB
Markdown
# 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.* |