8.1 KiB
8.1 KiB
BPC_PlaystyleClassifier — Playstyle Classifier
Blueprint Spec — UE 5.5–5.7
Parent Class
ActorComponent
Dependencies
- Requires:
BPC_PlayerMetricsTracker— Reads behaviour metrics (AggressionScore, CautionScore, ExplorationScore) - Required By:
BPC_AdaptiveEnvironmentDirector— Subscribes toOnPlaystyleChanged - Required By:
BPC_BehaviourVariantSelector— AI adapts to playstyle - Required By:
BPC_PacingDirector— 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
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.
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 PlaystyleTagGameplayTag 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:
- Start ClassificationTimer with ClassificationInterval repeating
- Perform initial classification immediately
Event: TickClassification
- Description: Timer callback. Runs ClassifyPlaystyle and broadcasts if changed.
- Flow:
- Read BPC_PlayerMetricsTracker.AggressionScore, CautionScore, ExplorationScore
- Calculate weighted scores
- Determine dominant playstyle tag (highest weighted score)
- If new tag differs from CurrentPlaystyleTag AND score delta exceeds ClassificationThreshold:
- Set PreviousPlaystyleTag = CurrentPlaystyleTag
- Set CurrentPlaystyleTag = new tag
- Broadcast OnPlaystyleChanged
- Always broadcast OnPlaystyleReclassified
7. Blueprint Graph Logic Flow
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 |
Direct read | AggressionScore, CautionScore, ExplorationScore, DeathCount, HideCount |
BPC_AdaptiveEnvironmentDirector |
Dispatcher (OnPlaystyleChanged) |
OldTag: GameplayTag, NewTag: GameplayTag |
BPC_BehaviourVariantSelector |
Dispatcher (OnPlaystyleChanged) |
NewTag: GameplayTag |
BPC_PacingDirector |
Direct read | CurrentPlaystyleTag |
SS_AchievementSystem |
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.