187 lines
7.2 KiB
Markdown
187 lines
7.2 KiB
Markdown
# 82 — BPC_AnalyticsTracker
|
||
|
||
## Blueprint Spec — UE 5.5–5.7
|
||
|
||
---
|
||
|
||
### Parent Class
|
||
`ActorComponent`
|
||
|
||
### Dependencies
|
||
- [`SS_SaveManager`](../05-saveload/28_SS_SaveManager.md) — Queue flush on save
|
||
- [`BPC_StatsTracker`](../11-polish/75_BPC_StatsTracker.md) — Stat aggregation
|
||
- [`BPC_PlayerMetricsTracker`](../02-player/14_BPC_PlayerMetricsTracker.md) — Player action feed
|
||
- [`BPC_NarrativeState`](../07-narrative/36_BPC_NarrativeState.md) — Story progression events
|
||
- [`BPC_PerformanceScaler`](../10-adaptive/68_BPC_PerformanceScaler.md) — Performance data
|
||
|
||
### Purpose
|
||
Anonymous gameplay analytics and telemetry tracker for development telemetry. Records anonymized player behavior, system performance, progression bottlenecks, and usage patterns. Designed for optional opt-in collection (GDPR/CCPA compliant). Outputs formatted JSON event logs to disk for developer analysis. Never collects personally identifiable information.
|
||
|
||
### Enums
|
||
|
||
**EAnalyticsEventType**
|
||
|
||
| Value | Description |
|
||
|-------|-------------|
|
||
| Session | Session start/end |
|
||
| Progression | Level/chapter events |
|
||
| Combat | Enemy encounter data |
|
||
| Death | Player death events |
|
||
| Performance | FPS, load time data |
|
||
| Settings | Options changed |
|
||
| Crash | Game quit unexpectedly |
|
||
| Achievement | Achievement earned |
|
||
| Interaction | Object interaction |
|
||
| Exploration | Zone discovery |
|
||
|
||
**EAnalyticsPrivacyLevel**
|
||
|
||
| Value | Description |
|
||
|-------|-------------|
|
||
| Full | All events |
|
||
| Minimal | Session/progression only |
|
||
| None | No tracking |
|
||
|
||
### Structs
|
||
|
||
**FAnalyticsEvent**
|
||
|
||
| Field | Type | Description |
|
||
|-------|------|-------------|
|
||
| EventID | FName | Event identifier |
|
||
| EventType | EAnalyticsEventType | Category |
|
||
| Timestamp | Float | Game time in seconds |
|
||
| SessionID | FString | Unique session identifier |
|
||
| DataPayload | TMap\<FString, FString\> | Event-specific data |
|
||
| bAnonymized | Bool | No PII flag |
|
||
|
||
### Variables
|
||
|
||
| Name | Type | Description |
|
||
|------|------|-------------|
|
||
| `bAnalyticsEnabled` | Bool | Master toggle |
|
||
| `PrivacyLevel` | EAnalyticsPrivacyLevel | User consent level |
|
||
| `SessionID` | FString | Unique session GUID |
|
||
| `EventQueue` | TArray\<FAnalyticsEvent\> | Pending upload |
|
||
| `QueueFlushInterval` | Float | Write to disk interval |
|
||
| `bIsFlushing` | Bool | Currently writing |
|
||
| `MaxQueueSize` | Int32 | Events before flush (50) |
|
||
| `bIncludePerformance` | Bool | Performance telemetry |
|
||
| `bIncludeSettings` | Bool | Settings telemetry |
|
||
| `SessionStartTime` | Float | Session start timestamp |
|
||
| `LastFlushTime` | Float | Last write timestamp |
|
||
|
||
### Functions
|
||
|
||
| Name | Inputs | Outputs | Description |
|
||
|------|--------|---------|-------------|
|
||
| `Initialize` | — | — | Start session, load consent |
|
||
| `RecordEvent` | Event: FAnalyticsEvent | — | Queue analytics event |
|
||
| `RecordSessionStart` | — | — | Log new session |
|
||
| `RecordSessionEnd` | — | — | Log session end |
|
||
| `RecordProgressionEvent` | ChapterID: FName, Action: FString | — | Story progress |
|
||
| `RecordCombatEvent` | EnemyType: FName, Result: FString | — | Combat outcome |
|
||
| `RecordDeathEvent` | Cause: FString, Position: FVector | — | Death analytics |
|
||
| `RecordPerformanceSnapshot` | FPS: Float, FrameTime: Float | — | Performance data |
|
||
| `RecordSettingsChange` | Setting: FString, Value: FString | — | Settings telemetry |
|
||
| `RecordInteraction` | ObjectID: FName, Action: FString | — | Interaction analytics |
|
||
| `FlushEventQueue` | — | — | Write to disk |
|
||
| `ClearEventQueue` | — | — | Discard unsent events |
|
||
| `SetPrivacyLevel` | Level: EAnalyticsPrivacyLevel | — | Update consent |
|
||
| `GenerateSessionID` | — | FString | Unique session GUID |
|
||
| `GetTotalEventsRecorded` | — | Int32 | Event count |
|
||
|
||
### Blueprint Flow
|
||
|
||
```
|
||
[Initialize]
|
||
└─► Load analytics consent from SS_SettingsManager
|
||
└─► If PrivacyLevel == None: bAnalyticsEnabled = false, return
|
||
└─► SessionID = GenerateSessionID()
|
||
└─► SessionStartTime = current game time
|
||
└─► RecordSessionStart()
|
||
└─► Start flush timer (QueueFlushInterval = 60 seconds)
|
||
└─► Bind event listeners:
|
||
BPC_PlayerMetricsTracker.OnEnemyKilled -> RecordCombatEvent
|
||
BPC_PlayerMetricsTracker.OnPlayerDeath -> RecordDeathEvent
|
||
BPC_NarrativeState.OnNarrativePhaseChanged -> RecordProgressionEvent
|
||
BPC_StatsTracker.OnStatUpdated -> Aggregate for session summary
|
||
|
||
[RecordEvent]
|
||
└─► If Not bAnalyticsEnabled: return
|
||
└─► Event.Timestamp = GetGameTimeInSeconds()
|
||
└─► Event.SessionID = SessionID
|
||
└─► Event.bAnonymized = true
|
||
└─► If EventQueue.Length >= MaxQueueSize:
|
||
FlushEventQueue()
|
||
└─► EventQueue.Add(Event)
|
||
|
||
[RecordSessionEnd]
|
||
└─► Create session summary event:
|
||
Total play time
|
||
Chapters completed
|
||
Deaths (from BPC_StatsTracker)
|
||
Total kills
|
||
Settings changed count
|
||
Performance averages
|
||
└─► RecordEvent(SessionSummary)
|
||
└─► FlushEventQueue()
|
||
└─► Broadcast OnSessionComplete(SessionID)
|
||
|
||
[FlushEventQueue]
|
||
└─► If bIsFlushing OR EventQueue is empty: return
|
||
└─► bIsFlushing = true
|
||
└─► Serialize EventQueue to JSON string
|
||
└─► File name: "analytics_{SessionID}_{Timestamp}.json"
|
||
└─► Write to Saved/Analytics/ directory
|
||
└─► ClearEventQueue()
|
||
└─► bIsFlushing = false
|
||
└─► Log: "Analytics flushed: {Count} events"
|
||
|
||
[SetPrivacyLevel]
|
||
└─► PrivacyLevel = Level
|
||
└─► If Level == None:
|
||
bAnalyticsEnabled = false
|
||
ClearEventQueue()
|
||
Delete all analytics files for this session
|
||
└─► Else if Level == Minimal:
|
||
bIncludePerformance = false
|
||
bIncludeSettings = false
|
||
└─► Else if Level == Full:
|
||
bIncludePerformance = true
|
||
bIncludeSettings = true
|
||
└─► Save consent to SS_SettingsManager
|
||
|
||
[GenerateSessionID]
|
||
└─► Generate UUID/GUID string
|
||
└─► Format: "{timestamp}-{random-hex}"
|
||
└─► Return Session ID string
|
||
```
|
||
|
||
### Event Dispatchers
|
||
|
||
| Name | Payload | Description |
|
||
|------|---------|-------------|
|
||
| `OnSessionComplete` | SessionID: FString | Session ended |
|
||
| `OnPrivacyLevelChanged` | Level: EAnalyticsPrivacyLevel | Consent updated |
|
||
|
||
### Communications With
|
||
|
||
| Target | Method | Why |
|
||
|--------|--------|-----|
|
||
| [`SS_SaveManager`](../05-saveload/28_SS_SaveManager.md) | Direct call | Save flush event |
|
||
| [`BPC_StatsTracker`](../11-polish/75_BPC_StatsTracker.md) | Direct call | Aggregate stats |
|
||
| [`BPC_PlayerMetricsTracker`](../02-player/14_BPC_PlayerMetricsTracker.md) | Event | Player actions |
|
||
| [`BPC_NarrativeState`](../07-narrative/36_BPC_NarrativeState.md) | Event | Progression events |
|
||
| [`BPC_PerformanceScaler`](../10-adaptive/68_BPC_PerformanceScaler.md) | Event | Performance snapshots |
|
||
| [`SS_SettingsManager`](../11-polish/71_SS_SettingsManager.md) | Direct call | Consent storage |
|
||
|
||
### Reuse Notes
|
||
- Fully opt-in with GDPR/CCPA-compliant consent levels
|
||
- UUID-based session IDs — no PII collected
|
||
- Events serialized to JSON for easy parsing
|
||
- Queue-based flush system prevents disk spam
|
||
- Separate analytics directory for clean file organization
|
||
- Integrates with existing event dispatchers across all systems
|
||
- Session summaries provide aggregate metrics
|
||
- Privacy level change clears existing data immediately |