add blueprints

This commit is contained in:
Lefteris Notas
2026-05-19 13:22:27 +03:00
parent f71bc678b2
commit 411edea8ce
138 changed files with 23330 additions and 0 deletions

View File

@@ -0,0 +1,194 @@
# BPC_PlaystyleClassifier — Playstyle Classifier
## Blueprint Spec — UE 5.55.7
---
### Parent Class
`ActorComponent`
### Dependencies
- **Requires:** [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) — Reads behaviour metrics (AggressionScore, CautionScore, ExplorationScore)
- **Required By:** [`BPC_AdaptiveEnvironmentDirector`](BPC_AdaptiveEnvironmentDirector.md) — Subscribes to `OnPlaystyleChanged`
- **Required By:** [`BPC_BehaviourVariantSelector`](../09-ai/BPC_BehaviourVariantSelector.md) — AI adapts to playstyle
- **Required By:** [`BPC_PacingDirector`](BPC_PacingDirector.md) — Pacing adjusted by playstyle
- **Engine/Plugin Requirements:** GameplayTags (for playstyle tag output), Timer system
### Purpose
Analyses player behaviour metrics from BPC_PlayerMetricsTracker and classifies their playstyle in real time. Outputs a dominant playstyle tag (Aggressive, Cautious, Explorer, etc.) that feeds into the adaptive environment director and AI behaviour systems.
---
## 1. Enums
```text
Enum Name: E_PlaystyleTag
(DisplayName = "Playstyle Tag")
Values:
Aggressive = 0 // Player favours combat and direct confrontation
Cautious = 1 // Player favours hiding, sneaking, and avoidance
Explorer = 2 // Player favours off-path exploration and discovery
Passive = 3 // Player avoids interaction, moves slowly
Speedrunner = 4 // Player rushes through content, skips optional
Completionist = 5 // Player exhaustively searches every area
```
*Values are used as Gameplay Tags for routing to adaptive systems.*
---
## 2. Structs
*No new structs defined. Reads from [`S_BehaviourEvent`](../02-player/15_BPC_PlayerMetricsTracker.md).*
---
## 3. Variables
### Configuration (Instance Editable, Expose On Spawn)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `ClassificationInterval` | Float | 15.0 | Classifier | Seconds between playstyle re-evaluations |
| `AggressionWeight` | Float | 1.0 | Classifier | Multiplier for aggression score influence |
| `CautionWeight` | Float | 1.0 | Classifier | Multiplier for caution score influence |
| `ExplorationWeight` | Float | 1.0 | Classifier | Multiplier for exploration score influence |
| `ClassificationThreshold` | Float | 10.0 | Classifier | Minimum score delta required to change classification |
### Internal (Private / Protected, No Expose)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `CurrentPlaystyleTag` | GameplayTag | Explorer | Internal | Dominant playstyle classification |
| `PreviousPlaystyleTag` | GameplayTag | None | Internal | Last classification for change detection |
| `ClassificationTimer` | TimerHandle | — | Internal | Timer for periodic re-evaluation |
---
## 4. Functions
### Public Functions
#### `ClassifyPlaystyle` → `GameplayTag`
- **Description:** Reads metrics from BPC_PlayerMetricsTracker, calculates weighted scores, and determines the dominant playstyle tag.
- **Parameters:** None
- **Blueprint Authority:** Any
- **Flow:** Get metrics → multiply by weights → find highest scoring playstyle → return tag
#### `GetCurrentPlaystyle` → `GameplayTag`
- **Description:** Returns the current dominant playstyle tag.
- **Parameters:** None
- **Blueprint Authority:** Any
#### `GetPlaystyleScores` → `Map (GameplayTag → Float)`
- **Description:** Returns the weighted score for each playstyle tag for external analysis.
- **Parameters:** None
- **Blueprint Authority:** Any
#### `ForcePlaystyle` → `void`
- **Description:** Overrides the playstyle classification for debugging or scripted sequences.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `PlaystyleTag` | GameplayTag | Forced classification |
- **Blueprint Authority:** Any
---
## 5. Event Dispatchers
| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnPlaystyleChanged` | OldTag: GameplayTag, NewTag: GameplayTag | Public | Playstyle classification changed |
| `OnPlaystyleReclassified` | NewTag: GameplayTag | Public | Periodic re-evaluation completed (fires even if unchanged) |
---
## 6. Overridden Events / Custom Events
### Event: `BeginPlay`
- **Description:** Starts the classification timer. Subscribes to metrics changes if needed.
- **Flow:**
1. Start ClassificationTimer with ClassificationInterval repeating
2. Perform initial classification immediately
### Event: `TickClassification`
- **Description:** Timer callback. Runs ClassifyPlaystyle and broadcasts if changed.
- **Flow:**
1. Read BPC_PlayerMetricsTracker.AggressionScore, CautionScore, ExplorationScore
2. Calculate weighted scores
3. Determine dominant playstyle tag (highest weighted score)
4. If new tag differs from CurrentPlaystyleTag AND score delta exceeds ClassificationThreshold:
- Set PreviousPlaystyleTag = CurrentPlaystyleTag
- Set CurrentPlaystyleTag = new tag
- Broadcast OnPlaystyleChanged
5. Always broadcast OnPlaystyleReclassified
---
## 7. Blueprint Graph Logic Flow
```mermaid
flowchart TD
A[BeginPlay] --> B[Start ClassificationTimer]
B --> C[Timer fires each ClassificationInterval seconds]
C --> D[Read AggressionScore from BPC_PlayerMetricsTracker]
D --> E[Read CautionScore from BPC_PlayerMetricsTracker]
E --> F[Read ExplorationScore from BPC_PlayerMetricsTracker]
F --> G[Calculate weighted scores:]
G --> H[AggressionScore * AggressionWeight]
H --> I[CautionScore * CautionWeight]
I --> J[ExplorationScore * ExplorationWeight]
J --> K[Also factor in: DeathCount, HideCount, ItemsCollected, DistanceTravelled]
K --> L[Map derived values to playstyle tags]
L --> M[Find highest weighted playstyle tag]
M --> N{New tag != CurrentPlaystyleTag?}
N -->|Yes| O{Score delta >= ClassificationThreshold?}
O -->|Yes| P[Broadcast OnPlaystyleChanged]
O -->|No| Q[Keep current classification]
N -->|No| Q
P --> R[Update CurrentPlaystyleTag]
R --> S[Broadcast OnPlaystyleReclassified]
Q --> S
```
---
## 8. Communication Matrix
| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) | Direct read | `AggressionScore`, `CautionScore`, `ExplorationScore`, `DeathCount`, `HideCount` |
| [`BPC_AdaptiveEnvironmentDirector`](BPC_AdaptiveEnvironmentDirector.md) | Dispatcher (`OnPlaystyleChanged`) | `OldTag: GameplayTag`, `NewTag: GameplayTag` |
| [`BPC_BehaviourVariantSelector`](../09-ai/BPC_BehaviourVariantSelector.md) | Dispatcher (`OnPlaystyleChanged`) | `NewTag: GameplayTag` |
| [`BPC_PacingDirector`](BPC_PacingDirector.md) | Direct read | `CurrentPlaystyleTag` |
| [`SS_AchievementSystem`](../11-meta/SS_AchievementSystem.md) | Dispatcher (`OnPlaystyleChanged`) | Playstyle tag for adaptive achievement checks |
---
## 9. Validation / Testing Checklist
- [ ] E_PlaystyleTag enum has all 6 values defined
- [ ] ClassificationInterval timer fires at correct interval
- [ ] Weighted scores correctly calculated from metrics
- [ ] OnPlaystyleChanged fires when classification changes significantly
- [ ] ClassificationThreshold prevents minor fluctuations from causing changes
- [ ] ForcePlaystyle overrides the automatic classification
- [ ] Edge case: BPC_PlayerMetricsTracker not present → default to Explorer
- [ ] Edge case: all scores zero → classify as Passive
- [ ] Edge case: timer fires during cutscene → classification still runs, adapt on exit
---
## 10. Reuse Notes
- AggressionWeight, CautionWeight, ExplorationWeight can be tuned per project to prioritise different behaviours
- ClassificationThreshold prevents "flickering" between similar playstyles on minor metric changes
- For non-adaptive games, set ClassificationInterval to 0 to disable or force a fixed playstyle
- Extend with new E_PlaystyleTag values per project (e.g., "Pacifist", "Collector")
- Classification is player-pawn-relative — in co-op, each player has their own classifier
---
*Specification based on Master Section 9.1, line 2699.*