Files
UE5-Modular-Game-Framework/docs/blueprints/10-adaptive/99_BPC_PlaystyleClassifier.md
Lefteris Notas 411edea8ce add blueprints
2026-05-19 13:22:27 +03:00

194 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.*