diff --git a/CONTEXT.md b/CONTEXT.md index 480e885..d2a0e6b 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -181,7 +181,7 @@ docs/ 15. **Server-Authoritative Replication** — All state mutations gated by `HasAuthority()`. Clients request via `Server_` RPCs; servers validate and replicate via `RepNotify`. See [`multiplayer-networking.md`](docs/architecture/multiplayer-networking.md). ## Build Order (Dependency-Safe) -- **Phase 0:** Foundation + Input (01-core, 15-input — 8 systems) +- **Phase 0:** Foundation + Input (01-core + 15-input — 9 systems — includes BPC_PlatformServiceAbstraction 150) - **Phase 1:** Player Core (02-player, 8 systems) - **Phase 2:** Interaction (03-interaction, 8 systems) - **Phase 3:** Inventory (04-inventory, 11 systems) diff --git a/UE5_Modular_Game_Framework.md b/UE5_Modular_Game_Framework.md index 0a1afae..5702412 100644 --- a/UE5_Modular_Game_Framework.md +++ b/UE5_Modular_Game_Framework.md @@ -4125,5 +4125,5 @@ Build these first. Everything else depends on them. *End of Reusable UE5 Modular Game Framework v2.0* *Framework designed for generic use. All system names are project-agnostic.* *Override in /Game/ folder. Never modify /Framework/ core assets.* -*C++ source: 22 classes in Source/PG_Framework/ | BP specs: 149 numbered files + 2 supplementary in docs/blueprints/* +*C++ source: 22 classes in Source/PG_Framework/ | BP specs: 150 numbered files + 2 supplementary in docs/blueprints/* *Companion docs: docs/checklists/ (build order, status), docs/developer/ (per-category references), docs/architecture/ (state management, audio, networking, animation, sound)* diff --git a/docs/blueprints/01-core/150_BPC_PlatformServiceAbstraction.md b/docs/blueprints/01-core/150_BPC_PlatformServiceAbstraction.md new file mode 100644 index 0000000..f47a3aa --- /dev/null +++ b/docs/blueprints/01-core/150_BPC_PlatformServiceAbstraction.md @@ -0,0 +1,406 @@ +# 150 — Platform Service Abstraction (`BPC_PlatformServiceAbstraction`) + +> **Blueprint-Only Implementation** — UE 5.5–5.7 supports all platform detection and SDK routing from Blueprints via `UGameplayStatics::GetPlatformName()`, conditional compilation checks, and plugin API calls. This component is the **single source of truth** for platform identity, replacing the three fragmented detection systems that currently exist across the framework. + +--- + +## Purpose +Central platform authority attached to the Game Instance. Detects the platform once at startup and provides a unified `EPlatformFamily` enum that ALL subsystems query instead of detecting platform independently. Routes platform-specific SDK calls (achievement submission to Steam/PSN/Xbox Live/Nintendo, cloud saves, overlays, input device profiles). Returns stub/no-op implementations on unsupported platforms so game code never needs `#if PLATFORM_PS5` checks. + +## The Problem Being Solved + +Currently the framework has **three independent platform detection systems**, each calling `GetPlatformName()` separately: + +| System | Enum | Platform Families | +|--------|------|-------------------| +| `BPC_RenderPipelineManager` (149) | `EPlatformFamily` | PS5, PS4, Xbox_Series, Xbox_One, Switch, PC_High, PC_Low, SteamDeck | +| `SS_EnhancedInputManager` (128) | `E_InputPlatform` | PC_KeyboardMouse, Xbox, PS5_DualSense | +| `BPC_HapticsController` (148) | `EControllerPlatform` | PC_Generic, Xbox, PS5_DualSense, PS4_DualShock | + +These are **different enums with different values** and don't talk to each other. If you change platform in one system, nothing cascades. + +**After this component is integrated, all three systems query `BPC_PlatformServiceAbstraction.GetPlatformFamily()` instead of detecting platform themselves. The old enums are deprecated and mapped to `EPlatformFamily`.** + +## Dependencies +- **Requires:** [`GI_GameFramework`](../01-core/04_GI_GameFramework.md) (attached as component), [`DA_GameTagRegistry`](../01-core/01_DA_GameTagRegistry.md) (platform tag validation) +- **Required By:** [`BPC_RenderPipelineManager`](../12-settings/149_BPC_RenderPipelineManager.md) (GFX quality profile selection), [`SS_EnhancedInputManager`](../15-input/128_SS_EnhancedInputManager.md) (input device profile selection), [`BPC_HapticsController`](../12-settings/148_BPC_HapticsController.md) (controller platform detection), [`SS_AchievementSystem`](../11-meta/103_SS_AchievementSystem.md) (SDK routing), [`SS_SettingsSystem`](105_SS_SettingsSystem.md) (platform-aware defaults) +- **Engine/Plugin Requirements:** GameplayTags, `UGameplayStatics`, Platform SDK plugins (Steamworks, PSN, Xbox GDK, Nintendo SDK — all optional) + +## Class Info +| Property | Value | +|----------|-------| +| **Parent Class** | `ActorComponent` | +| **Class Type** | Blueprint Component | +| **Asset Path** | `Content/Framework/Core/BPC_PlatformServiceAbstraction` | +| **Implements Interfaces** | None | +| **Attachment** | Game Instance (`GI_GameFramework`) | + +--- + +## 1. Enums + +### `EPlatformFamily` (UNIFIED — all systems use this) + +| Value | Description | Input Device | Render Pipeline | Achievements SDK | Store | +|-------|-------------|-------------|-----------------|-----------------|-------| +| `Unknown = 0` | Not yet detected | — | — | — | — | +| `PC_Win64 = 1` | Windows PC (any GPU) | KB+M / Xbox / PS5 gamepad | Detected per GPU capability | Steam / EGS | Steam / EGS | +| `PC_Linux = 2` | Linux / SteamOS | Same as PC | Vulkan | Steam | Steam | +| `PS5 = 3` | PlayStation 5 | DualSense | Lumen + Nanite | PSN Trophies | PS Store | +| `PS5_Pro = 4` | PlayStation 5 Pro | DualSense | Lumen + PSSR | PSN Trophies | PS Store | +| `PS4 = 5` | PlayStation 4 / 4 Pro | DualShock 4 | Baked only | PSN Trophies | PS Store | +| `Xbox_Series = 6` | Xbox Series X\|S | Xbox Wireless | Lumen + Nanite | Xbox Live | MS Store | +| `Xbox_One = 7` | Xbox One / One X | Xbox Wireless | Baked only | Xbox Live | MS Store | +| `Switch = 8` | Nintendo Switch | Joy-Con / Pro | Baked + Proxy | Nintendo | eShop | +| `Switch_2 = 9` | Nintendo Switch 2 | Joy-Con 2 / Pro 2 | Baked + CSM + FSR | Nintendo | eShop | +| `SteamDeck = 10` | Steam Deck | Built-in / external | Baked/SSGI + CSM | Steam | Steam | +| `Mac = 11` | macOS | KB+M / gamepad | Metal / Baked | Steam | Steam / App Store | + +### `EPlatformSDK` +| Value | Description | +|-------|-------------| +| `None = 0` | No SDK available (editor, generic build) | +| `Steam = 1` | Steamworks SDK (achievements, cloud, overlay, stats) | +| `PSN = 2` | PlayStation Network SDK (trophies, cloud, overlay, invites) | +| `XboxLive = 3` | Xbox Live / GDK (achievements, cloud, overlay, invites) | +| `Nintendo = 4` | Nintendo SDK (achievements, cloud, overlay) | +| `EGS = 5` | Epic Games Store SDK | + +### `EPlatformOverlayType` +| Value | Description | +|-------|-------------| +| `Achievements = 0` | Show platform achievements/trophies page | +| `Friends = 1` | Open friends list | +| `Invite = 2` | Send game invite | +| `Store = 3` | Open store page (DLC, etc.) | +| `SocialFeed = 4` | Community / social feed | + +--- + +## 2. Structs + +### `SPlatformCapabilities` +| Field | Type | Description | +|-------|------|-------------| +| `Platform` | `EPlatformFamily` | Current platform | +| `SDK` | `EPlatformSDK` | Available platform SDK | +| `bSupportsLumen` | `bool` | Platform GPU supports Lumen GI | +| `bSupportsNanite` | `bool` | Platform GPU supports Nanite | +| `bSupportsHWRT` | `bool` | Platform supports hardware ray tracing | +| `bSupportsCloudSaves` | `bool` | Platform has cloud save API | +| `bSupportsAchievements` | `bool` | Platform has achievement/trophy system | +| `bSupportsOverlay` | `bool` | Platform has in-game overlay | +| `bSupportsRichPresence` | `bool` | Platform supports rich presence / "now playing" | +| `bSupportsUserGeneratedContent` | `bool` | Platform supports UGC/mod sharing | +| `bIsConsole` | `bool` | Is this a console platform (certification required)? | +| `bIsHandheld` | `bool` | Is this a handheld device? | +| `DefaultInputType` | `FName` | Default input device for this platform ("Gamepad", "Keyboard", "Touch") | +| `MaxLocalPlayers` | `int32` | Maximum local split-screen players | +| `StoreID` | `FString` | Platform store ID for DLC checks | + +--- + +## 3. Variables + +### Configuration (Instance Editable) +| Variable | Type | Default | Category | Description | +|----------|------|---------|----------|-------------| +| `bAutoDetectPlatform` | `bool` | `true` | `Config` | Auto-detect on Initialize | +| `OverridePlatform` | `EPlatformFamily` | `Unknown` | `Config` | Force a platform (for testing in editor) | +| `bEnableSDKIntegration` | `bool` | `true` | `Config` | Enable platform SDK calls | + +### Internal (Private) +| Variable | Type | Default | Category | Description | +|----------|------|---------|----------|-------------| +| `CurrentPlatform` | `EPlatformFamily` | `Unknown` | `State` | Detected or overridden platform | +| `CurrentSDK` | `EPlatformSDK` | `None` | `State` | Active platform SDK | +| `PlatformCapabilities` | `SPlatformCapabilities` | — | `State` | Full capabilities snapshot | +| `bIsInitialized` | `bool` | `false` | `State` | Whether Initialize completed | +| `CachedGameInstance` | `GI_GameFramework` | `None` | `Cache` | Owner Game Instance reference | + +--- + +## 4. Functions + +### Public Functions + +#### `Initialize` → `void` +- **Description:** Detect platform, resolve SDK, build capabilities, broadcast ready signal. Called once at Game Instance startup. +- **Flow:** + 1. Get Owner → Cast to `GI_GameFramework` → cache + 2. If `OverridePlatform != Unknown`: use override + 3. Else if `bAutoDetectPlatform`: call `DetectPlatform()` + 4. Resolve which SDK is available: check plugin state, build configuration + 5. Build `SPlatformCapabilities` for detected platform + 6. Register platform in `DA_GameTagRegistry` as `Framework.Platform.{Name}` + 7. Set `bIsInitialized = true` + 8. Broadcast `OnPlatformReady(CurrentPlatform)` + 9. Broadcast `OnPlatformCapabilitiesReady(PlatformCapabilities)` + +#### `DetectPlatform` → `EPlatformFamily` +- **Description:** Detects the current platform using UE5 APIs. +- **Flow:** + 1. `UGameplayStatics::GetPlatformName()` → switch: + - "PS5" → check if Pro model available → `PS5_Pro` or `PS5` + - "PS4" → `PS4` + - "XboxOne" → `Xbox_One` + - "XSX" or "XboxAnaconda" → `Xbox_Series` (check if S model → adjust capabilities) + - "Switch" → check model revision → `Switch_2` or `Switch` + - "Win64" → check if running on Steam Deck (`IsSteamDeck()`) → `SteamDeck` + - "Win64" → `PC_Win64` + - "Linux" → `PC_Linux` + - "Mac" → `Mac` + 2. Store in `CurrentPlatform` + 3. Return `CurrentPlatform` + +#### `GetPlatformFamily` → `EPlatformFamily` +- **Description:** Returns the current platform. **This is the function ALL other systems call.** Read-only, always available after initialization. + +#### `GetSDK` → `EPlatformSDK` +- **Description:** Returns the available platform SDK. Used by achievement and save systems for routing. + +#### `GetPlatformCapabilities` → `SPlatformCapabilities` +- **Description:** Returns the full capabilities struct. Read-only. + +#### `SubmitAchievementToPlatform` → `bool` +- **Description:** Route an achievement unlock to the correct platform SDK. +- **Parameters:** + | Param | Type | Description | + |-------|------|-------------| + | `AchievementID` | `FString` | Platform-specific achievement ID | +- **Flow:** + 1. Switch on `CurrentSDK`: + - `Steam` → call Steamworks `ISteamUserStats::SetAchievement(AchievementID)` + `StoreStats()` + - `PSN` → call PSN Trophy API `UnlockTrophy(AchievementID)` + - `XboxLive` → call Xbox Live `AchievementsService::UpdateAchievement(AchievementID, 100)` + - `Nintendo` → call Nintendo achievement API + - `None` → log "Achievement submitted (editor mode)" → return true (no-op stub) + 2. Return true if successful, false on SDK error + +#### `SyncCloudSave` → `bool` +- **Description:** Upload or sync save data to platform cloud. +- **Parameters:** + | Param | Type | Description | + |-------|------|-------------| + | `SlotIndex` | `int32` | Which save slot | + | `SaveData` | `TArray` | Serialized save data | +- **Flow:** Route to Steam Cloud / PSN Cloud / Xbox Cloud / Nintendo Cloud based on `CurrentSDK`. + +#### `ShowPlatformOverlay` → `void` +- **Description:** Open a platform-specific overlay. +- **Parameters:** + | Param | Type | Description | + |-------|------|-------------| + | `OverlayType` | `EPlatformOverlayType` | Which overlay to show | +- **Flow:** + 1. Switch on `CurrentSDK`: + - `Steam` → `ISteamFriends::ActivateGameOverlay(URL)` + - `PSN` → System software overlay API + - Others → nop (not supported) + +#### `GetDefaultInputProfile` → `FName` +- **Description:** Returns the default input profile for this platform. Used by `SS_EnhancedInputManager` to select the correct `DA_InputMappingProfile`. +- **Returns:** "PC_KeyboardMouse", "Xbox", "PS5_DualSense", "PS4_DualShock", "Switch_JoyCon" + +#### `IsConsole` → `bool`, `IsHandheld` → `bool`, `IsPS5` → `bool`, `IsXbox` → `bool`, `IsSwitch` → `bool`, `IsPC` → `bool`, `IsSteamDeck` → `bool` +- **Description:** Convenience boolean checks for common platform queries. All return from `PlatformCapabilities` struct. + +#### `GetConsoleCertificationRequirements` → `TArray` +- **Description:** Returns a list of TRC (Technical Requirement Checklist) items for the current console platform. Empty on PC. +- **Flow:** + 1. Switch on `CurrentPlatform`: + - `PS5` → return Sony TRC items (60 FPS perf mode, HDR support, controller speaker, activity cards, etc.) + - `PS4` → return Sony PS4 TRC items + - `Xbox_Series` → return Microsoft XR items (Quick Resume, Smart Delivery, VRR, etc.) + - `Xbox_One` → return Microsoft XR items + - `Switch` → return Nintendo guidelines (dynamic resolution, Handheld/Docked parity, etc.) + - `PC_*` → return empty (no console cert needed) + +#### `GetStoreID` → `FString` +- **Description:** Returns the platform store app ID for DLC entitlement checks. + +--- + +## 5. Event Dispatchers + +| Dispatcher | Parameters | Bind Access | Description | +|------------|-----------|-------------|-------------| +| `OnPlatformReady` | `EPlatformFamily Platform` | `Public` | Fired after platform detection completes — all other systems bind to this for deferred init | +| `OnPlatformCapabilitiesReady` | `SPlatformCapabilities Capabilities` | `Public` | Fired alongside OnPlatformReady with full capability info | +| `OnPlatformSDKReady` | `EPlatformSDK SDK` | `Public` | Fired when platform SDK is ready for API calls | +| `OnPlatformOverlayOpened` | `EPlatformOverlayType Type` | `Public` | Fired when platform overlay opens (game should pause) | +| `OnPlatformOverlayClosed` | — | `Public` | Fired when platform overlay closes (game resumes) | +| `OnCloudSaveCompleted` | `bool bSuccess`, `int32 SlotIndex` | `Public` | Fired when cloud save upload completes | +| `OnAchievementSubmitted` | `FString AchievementID`, `bool bSuccess` | `Public` | Fired after platform API achievement call | + +--- + +## 6. Overridden Events + +### Event: On Component Created (attached to GI_GameFramework via BeginPlay) +- **Description:** Auto-initializes at game start. +- **Flow:** + 1. Call `Initialize()` + 2. All dependent subsystems that bound to `OnPlatformReady` receive the event and complete their initialization + +--- + +## 7. Blueprint Graph Logic Flow + +```mermaid +flowchart TD + A[GI_GameFramework: BeginPlay] --> B[BPC_PlatformServiceAbstraction: Initialize] + B --> C{OverridePlatform?} + C -->|Yes| D[Use Override] + C -->|No| E[DetectPlatform] + E --> F[Switch on GetPlatformName] + F --> G[Set CurrentPlatform] + D --> G + + G --> H[Resolve available SDK] + H --> I[Build SPlatformCapabilities] + I --> J[Register Platform Tag in DA_GameTagRegistry] + J --> K[Broadcast OnPlatformReady] + + K --> L[ALL BOUND SYSTEMS RECEIVE] + L --> M[RenderPipelineManager: load DA_RPP for platform] + L --> N[EnhancedInputManager: load DA_InputMapping for platform] + L --> O[HapticsController: set EControllerPlatform from platform] + L --> P[AchievementSystem: route SDK via GetSDK] + L --> Q[SettingsSystem: load platform defaults] +``` + +--- + +## 8. Communication Matrix + +| Who Talks | How | What Is Sent | +|-----------|-----|-------------| +| `GI_GameFramework` | `Owner` | Hosts this component | +| `BPC_PlatformServiceAbstraction` | `Dispatcher` → ALL systems | `OnPlatformReady(Platform)` — every system's deferred init trigger | +| `BPC_RenderPipelineManager` (149) | `Function Call` | `GetPlatformFamily()` → selects correct `DA_RenderPipelineProfile` | +| `SS_EnhancedInputManager` (128) | `Function Call` | `GetDefaultInputProfile()` → selects correct `DA_InputMappingProfile` | +| `BPC_HapticsController` (148) | `Function Call` | `GetPlatformFamily()` → maps to `EControllerPlatform` | +| `SS_AchievementSystem` (103) | `Function Call` | `SubmitAchievementToPlatform(ID)` → routes to Steam/PSN/Xbox/Nintendo | +| `SS_SaveManager` (35) | `Function Call` | `SyncCloudSave(Slot, Data)` → routes to platform cloud API | +| `SS_SettingsSystem` (105) | `Function Call` | `GetPlatformFamily()` → sets platform-appropriate defaults | +| `SS_UIManager` (44) | `Dispatcher` | `OnPlatformOverlayOpened/Closed` → pause/resume game | +| `DA_GameTagRegistry` (01) | `Function Call` | Register `Framework.Platform.{Name}` tag | + +--- + +## 9. Platform Enum Mapping (Deprecation of old enums) + +The old scattered platform enums are mapped to `EPlatformFamily` as follows: + +| Deprecated Enum | Old Value | EPlatformFamily | +|----------------|-----------|-----------------| +| `E_InputPlatform::PC_KeyboardMouse` | 0 | `PC_Win64` (or `PC_Linux`, `Mac`) | +| `E_InputPlatform::Xbox` | 1 | `Xbox_Series` or `Xbox_One` (detected) | +| `E_InputPlatform::PS5_DualSense` | 2 | `PS5` or `PS5_Pro` | +| `EControllerPlatform::PC_Generic` | 1 | `PC_Win64` | +| `EControllerPlatform::Xbox` | 2 | `Xbox_Series` or `Xbox_One` | +| `EControllerPlatform::PS5_DualSense` | 3 | `PS5` | +| `EControllerPlatform::PS4_DualShock` | 4 | `PS4` | + +All systems that previously used their own platform enum now call: +``` +BPC_PlatformServiceAbstraction → GetPlatformFamily() → map to local enum internally +``` + +--- + +## 10. Validation / Testing Checklist + +- [ ] `DetectPlatform` correctly identifies all 12 platform families +- [ ] `OverridePlatform = PS4` → all systems use PS4 profiles (baked lighting, DualShock, PSN SDK) +- [ ] `OverridePlatform = Switch` → all systems use Switch profiles (baked, NIS, Joy-Con, Nintendo SDK) +- [ ] `OverridePlatform = PS5_Pro` → RenderPipelineManager enables PSSR upscaler +- [ ] `GetDefaultInputProfile` returns correct input profile for each platform +- [ ] `SubmitAchievementToPlatform` on Steam build successfully calls Steam API +- [ ] `SubmitAchievementToPlatform` in Editor returns true (no-op stub, no crash) +- [ ] `SyncCloudSave` routes to correct platform cloud API +- [ ] `ShowPlatformOverlay(Achievements)` opens correct platform overlay +- [ ] `OnPlatformReady` fires before any dependent system queries `GetPlatformFamily()` +- [ ] Changing `OverridePlatform` at runtime (dev cheat) cascades to all bound systems +- [ ] Edge case: No SDK available (editor, generic build) → all SDK calls return no-op stubs +- [ ] Edge case: Platform SDK initialization fails → `CurrentSDK = None`, systems fallback gracefully +- [ ] Edge case: Steam Deck detection in Desktop Mode → reported as `PC_Linux`, not `SteamDeck` +- [ ] Edge case: Xbox Series S (Lockhart) vs Series X (Anaconda) → different capabilities for GPU + +--- + +## 11. Manual Implementation Guide + +### 11.1 Class Setup +1. Create Blueprint Class: parent `ActorComponent`, name `BPC_PlatformServiceAbstraction` +2. Path: `Content/Framework/Core/` +3. Attach to `GI_GameFramework` (or BP child of it) + +### 11.2 Key UE5 Nodes +| Node | Where to Find | Used For | +|------|---------------|----------| +| `Get Platform Name` | Right-click → "Get Platform Name" | Primary detection API | +| `Switch on String` | Right-click → "Switch" | Platform name branching | +| `Is Steam Deck` | Custom node / check for "SteamDeck" in device name | Steam Deck detection | +| `Is In Editor` | Right-click → "Is In Editor" | SDK substitution in editor | +| `Switch on EPlatformFamily` | Right-click → "Switch" | Platform-specific logic | + +### 11.3 Node-by-Node: DetectPlatform + +``` +[Function: DetectPlatform] + Step 1: Get Platform Name → Store as PlatformStr + Step 2: Switch on String (PlatformStr): + "PS5" → + Step 2a: Get device model info → if "Pro" → PS5_Pro, else PS5 + "PS4" → PS4 + "XboxOne" → Xbox_One + "XSX" → Xbox_Series (check if "Lockhart" variant for Series S) + "XboxAnaconda" → Xbox_Series + "Switch" → Switch (check model revision for Switch_2) + "Win64" → + Step 2b: Check if running on Steam Deck → if yes → SteamDeck + Step 2c: Else → PC_Win64 + "Linux" → PC_Linux + "Mac" → Mac + Default → PC_Win64 (fallback) + Step 3: Store result in CurrentPlatform + Step 4: Return CurrentPlatform +``` + +### 11.4 Networking +- **Platform is per-client.** Each client may be on a different platform (PC host + PS5 client). +- `BPC_PlatformServiceAbstraction` runs on ALL instances (server + each client). +- Platform SDK calls are local-to-client. +- For listen server: host's platform SDK is used for host's achievements; clients use their own. + +### 11.5 Multiplayer Note +- In a multiplayer session, each player's platform is detected independently +- Cross-platform play: a PC host may have Steam SDK active while a PS5 client has PSN SDK +- The Game Instance's PlatformServiceAbstraction only represents the LOCAL player's platform +- For dedicated servers: `CurrentPlatform = PC_Linux` or `PC_Win64`, `CurrentSDK = None` (no achievements on dedicated server) + +--- + +## 12. Blueprint Build Checklist + +- [ ] Create Blueprint class: `BPC_PlatformServiceAbstraction` (parent: `ActorComponent`) +- [ ] Add enums: `EPlatformFamily` (12 values), `EPlatformSDK` (6 values), `EPlatformOverlayType` (5 values) +- [ ] Add struct: `SPlatformCapabilities` +- [ ] Add all variables from Section 3 +- [ ] Build `Initialize` → `DetectPlatform` → `BuildCapabilities` → broadcast chain +- [ ] Implement `DetectPlatform` with Switch on GetPlatformName +- [ ] Implement `SubmitAchievementToPlatform` with Switch on CurrentSDK +- [ ] Implement `SyncCloudSave`, `ShowPlatformOverlay` +- [ ] Implement all boolean convenience functions (`IsConsole`, `IsPS5`, etc.) +- [ ] Create all 7 event dispatchers +- [ ] Wire OnPlatformReady as deferred init trigger for all dependent subsystems +- [ ] Test: OverridePlatform = PS5 → OnPlatformReady fires with PS5 +- [ ] Test: Editor mode → SDK calls return no-op stubs +- [ ] Test: Steam build → SubmitAchievement calls Steam API +- [ ] Test: Platform hot-swap (dev cheat) cascades to all bound systems + +--- + +*Blueprint Spec: Platform Service Abstraction. Conforms to TEMPLATE.md v2.0 — part of the UE5 Modular Game Framework, CORE layer.* diff --git a/docs/blueprints/11-meta/103_SS_AchievementSystem.md b/docs/blueprints/11-meta/103_SS_AchievementSystem.md index d3457b2..41aae39 100644 --- a/docs/blueprints/11-meta/103_SS_AchievementSystem.md +++ b/docs/blueprints/11-meta/103_SS_AchievementSystem.md @@ -12,8 +12,8 @@ - **Requires:** [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) — Player stats source - **Requires:** [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) — Story progression - **Required By:** [`WBP_NotificationToast`](../06-ui/WBP_NotificationToast.md) — UI notification -- **Required By:** [`BPC_PlatformServiceAbstraction`](../12-settings/BPC_PlatformServiceAbstraction.md) — Platform API submission -- **Engine/Plugin Requirements:** GameplayTags +- **Required By:** [`BPC_PlatformServiceAbstraction`](../01-core/150_BPC_PlatformServiceAbstraction.md) — Platform API routing (Steam/PSN/Xbox/Nintendo) +- **Engine/Plugin Requirements:** GameplayTags, Platform SDK plugins (Steamworks, PSN, Xbox GDK, Nintendo SDK — all optional) ### Purpose Platform-agnostic achievement and trophy tracking system. Manages achievement definitions, progress tracking, unlock logic, and platform API submission. Supports hidden achievements, progress-based achievements, and cross-save achievement state persistence. @@ -118,7 +118,7 @@ Platform-agnostic achievement and trophy tracking system. Manages achievement de | [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) | Direct read | Stats for achievements | | [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) | Direct read | Story achievements | | [`WBP_NotificationToast`](../06-ui/WBP_NotificationToast.md) | Create widget | Toast display | -| [`BPC_PlatformServiceAbstraction`](../12-settings/BPC_PlatformServiceAbstraction.md) | Direct call | Platform submission | +| [`BPC_PlatformServiceAbstraction`](../01-core/150_BPC_PlatformServiceAbstraction.md) | Direct call | Platform SDK routing (Steam/PSN/Xbox/Nintendo) | --- diff --git a/docs/blueprints/12-settings/148_BPC_HapticsController.md b/docs/blueprints/12-settings/148_BPC_HapticsController.md index b1cb1aa..d339d49 100644 --- a/docs/blueprints/12-settings/148_BPC_HapticsController.md +++ b/docs/blueprints/12-settings/148_BPC_HapticsController.md @@ -8,7 +8,7 @@ Abstraction layer for all controller haptic feedback and force feedback effects. Gameplay systems trigger haptics by GameplayTag (e.g., `Haptic.Damage.Heavy`) rather than calling raw UE5 haptic APIs. This component handles platform detection (Xbox rumble vs PS5 DualSense adaptive triggers vs generic PC gamepad), respects accessibility settings (`BPC_AccessibilitySettings.bHapticsEnabled`), and manages effect priority/conflict resolution. ## Dependencies -- **Requires:** [`DA_HapticProfile`](docs/blueprints/14-data-assets/121_DA_HapticProfile.md) (effect definitions), [`BPC_AccessibilitySettings`](docs/blueprints/12-settings/104_BPC_AccessibilitySettings.md) (master toggle), [`BPC_StateManager`](docs/blueprints/16-state/130_BPC_StateManager.md) (heart rate for heartbeat haptic) +- **Requires:** [`DA_HapticProfile`](docs/blueprints/14-data-assets/121_DA_HapticProfile.md) (effect definitions), [`BPC_AccessibilitySettings`](docs/blueprints/12-settings/104_BPC_AccessibilitySettings.md) (master toggle), [`BPC_StateManager`](docs/blueprints/16-state/130_BPC_StateManager.md) (heart rate for heartbeat haptic), [`BPC_PlatformServiceAbstraction`](docs/blueprints/01-core/150_BPC_PlatformServiceAbstraction.md) (platform detection — replaces own platform enum) - **Required By:** `BPC_HealthSystem` (damage haptics), `BPC_FirearmSystem` (weapon fire kick), `BPC_MeleeSystem` (melee impact), `BPC_PhysicsDragSystem` (grab/release), `BPC_ScareEventSystem` (tension rumble), `BP_ItemPickup` (pickup pulse), `BPC_MovementStateSystem` (footstep rumble via GASP notifies) - **Engine/Plugin Requirements:** Enhanced Input Plugin (controller detection), PlayStation 5 Controller Plugin (DualSense adaptive triggers — optional, graceful fallback) @@ -56,7 +56,7 @@ Abstraction layer for all controller haptic feedback and force feedback effects. | `Right = 1` | Right (high-frequency) motor only | | `Both = 2` | Both motors simultaneously | -### `EControllerPlatform` +### `EControllerPlatform` *(deprecated — use EPlatformFamily from BPC_PlatformServiceAbstraction. This enum is mapped internally from the unified platform enum.)* | Value | Description | |-------|-------------| | `Unknown = 0` | Platform not yet detected | diff --git a/docs/blueprints/12-settings/149_BPC_RenderPipelineManager.md b/docs/blueprints/12-settings/149_BPC_RenderPipelineManager.md index f50173b..4555c31 100644 --- a/docs/blueprints/12-settings/149_BPC_RenderPipelineManager.md +++ b/docs/blueprints/12-settings/149_BPC_RenderPipelineManager.md @@ -8,7 +8,7 @@ Central authority for render pipeline configuration. Reads `DA_RenderPipelineProfile` Data Assets to determine the appropriate rendering method (Lumen vs Baked Lightmass), shadow system (VSM vs CSM), upscaler (DLSS/FSR/TSR/PSSR), and mesh strategy (Nanite vs LOD) for the current platform and quality preset. Applies settings via UE5 console variables, coordinates with `BPC_PerformanceScaler` for runtime quality tier adjustments, and broadcasts pipeline changes so dependent systems (Planar Capture, Audio, UI) can adapt. ## Dependencies -- **Requires:** [`DA_RenderPipelineProfile`](../14-data-assets/DA_RenderPipelineProfile.md) (render configs), [`SS_SettingsSystem`](105_SS_SettingsSystem.md) (saved quality preferences), [`GI_GameFramework`](../01-core/04_GI_GameFramework.md) (game phase for pre-load apply) +- **Requires:** [`DA_RenderPipelineProfile`](../14-data-assets/DA_RenderPipelineProfile.md) (render configs), [`BPC_PlatformServiceAbstraction`](../01-core/150_BPC_PlatformServiceAbstraction.md) (central platform detection), [`SS_SettingsSystem`](105_SS_SettingsSystem.md) (saved quality preferences), [`GI_GameFramework`](../01-core/04_GI_GameFramework.md) (game phase for pre-load apply) - **Required By:** [`BPC_PerformanceScaler`](../10-adaptive/91_BPC_PerformanceScaler.md) (delegates CVar application), [`SS_PlanarCaptureManager`](../17-capture/138_SS_PlanarCaptureManager.md) (capture quality cap on pipeline change), [`WBP_SettingsMenu`](../06-ui/57_WBP_SettingsMenu.md) (Video tab quality controls) - **Engine/Plugin Requirements:** DLSS Plugin (optional), FSR Plugin (optional), XeSS Plugin (optional), GameplayTags, Enhanced Input @@ -25,7 +25,8 @@ Central authority for render pipeline configuration. Reads `DA_RenderPipelinePro ## 1. Enums -*See [`DA_RenderPipelineProfile`](../14-data-assets/DA_RenderPipelineProfile.md) for: `ERenderPipelineMethod`, `EShadowMethod`, `EReflectionMethod`, `EUpscalerMethod`, `EMeshStrategy`, `EPlatformFamily`.* +*See [`DA_RenderPipelineProfile`](../14-data-assets/DA_RenderPipelineProfile.md) for: `ERenderPipelineMethod`, `EShadowMethod`, `EReflectionMethod`, `EUpscalerMethod`, `EMeshStrategy`.* +*See [`BPC_PlatformServiceAbstraction`](../01-core/150_BPC_PlatformServiceAbstraction.md) for: `EPlatformFamily` (unified — all systems use this).* ### `ERenderPipelineChangeType` | Value | Description | @@ -41,7 +42,7 @@ Central authority for render pipeline configuration. Reads `DA_RenderPipelinePro ### `SActivePipelineState` | Field | Type | Description | |-------|------|-------------| -| `Platform` | `EPlatformFamily` | Detected platform | +| `Platform` | `EPlatformFamily` | Detected platform (from BPC_PlatformServiceAbstraction) | | `ActivePreset` | `FName` | Currently applied quality preset name | | `PendingPreset` | `FName` | Queued preset awaiting reload | | `ActivePipelineProfile` | `DA_RenderPipelineProfile` | Currently loaded profile Data Asset | @@ -81,7 +82,8 @@ Central authority for render pipeline configuration. Reads `DA_RenderPipelinePro - **Description:** Detects platform, loads the appropriate `DA_RenderPipelineProfile`, reads saved quality from `SS_SettingsSystem`, and applies initial pipeline settings. - **Flow:** 1. Get Owner → Cast to PlayerController → cache - 2. If `bAutoDetectPlatform`: call `DetectPlatform()` → set `DetectedPlatform` + 2. Bind to `GI_GameFramework.GetSubsystem(BPC_PlatformServiceAbstraction).OnPlatformReady` + 3. In handler: read `PlatformService.GetPlatformFamily()` → set `DetectedPlatform` 3. Lookup `DA_RenderPipelineProfile` from `PlatformProfileMap` by `DetectedPlatform` 4. If not found: log error, fallback to `PC_High` profile 5. Read `SS_SettingsSystem.GetSettingFloat("QualityPreset")` → resolve preset name @@ -173,7 +175,7 @@ Central authority for render pipeline configuration. Reads `DA_RenderPipelinePro 3. Call `ApplyRenderConfig(PendingPreset, Config)` 4. Broadcast `OnRenderPipelineChanged(PendingPreset, RequiresLevelReload)` -#### `DetectPlatform` → `EPlatformFamily` +#### `DetectPlatform` → `EPlatformFamily` *(deprecated — use BPC_PlatformServiceAbstraction.GetPlatformFamily() instead)* - **Description:** Auto-detect the current platform and GPU capability. - **Flow:** 1. Check `UGameplayStatics::GetPlatformName()`: diff --git a/docs/blueprints/15-input/128_SS_EnhancedInputManager.md b/docs/blueprints/15-input/128_SS_EnhancedInputManager.md index 3bd0ff1..17f4956 100644 --- a/docs/blueprints/15-input/128_SS_EnhancedInputManager.md +++ b/docs/blueprints/15-input/128_SS_EnhancedInputManager.md @@ -8,7 +8,7 @@ Centralized Game Instance Subsystem that manages all UE5 Enhanced Input operations: Input Mapping Context push/pop with priority stack, platform-specific binding profiles, key rebinding, input mode coordination with [`SS_UIManager`](docs/blueprints/06-ui/44_SS_UIManager.md), and read-only input state queries for gameplay systems. ## Dependencies -- **Requires:** [`DA_InputMappingProfile`](docs/blueprints/14-data-assets/129_DA_InputMappingProfile.md) (platform profiles), [`GI_GameFramework`](docs/blueprints/01-core/04_GI_GameFramework.md) (subsystem access) +- **Requires:** [`DA_InputMappingProfile`](docs/blueprints/14-data-assets/129_DA_InputMappingProfile.md) (platform profiles), [`GI_GameFramework`](docs/blueprints/01-core/04_GI_GameFramework.md) (subsystem access), [`BPC_PlatformServiceAbstraction`](docs/blueprints/01-core/150_BPC_PlatformServiceAbstraction.md) (central platform detection — replaces own platform enum) - **Required By:** All gameplay systems that read input (`BPC_InteractionDetector`, `BPC_FirearmSystem`, `BPC_MovementStateSystem`, `BPC_CutsceneBridge`, `BPC_HidingSystem`, `BPC_ActiveItemSystem`, etc.) - **Engine/Plugin Requirements:** Enhanced Input Plugin (UE5 built-in), `UEnhancedInputLocalPlayerSubsystem` @@ -33,12 +33,12 @@ Centralized Game Instance Subsystem that manages all UE5 Enhanced Input operatio | `Inspection = 3` | 3D item inspection (IMC_Inspection, Priority 20) | | `UI = 4` | Full-screen menus/pause (IMC_UI, Priority 100) | -### `E_InputPlatform` +### `E_InputPlatform` *(deprecated — use EPlatformFamily from BPC_PlatformServiceAbstraction. This enum is kept for DA_InputMappingProfile compatibility but all runtime selection uses the unified enum)* | Value | Description | |-------|-------------| -| `PC_KeyboardMouse = 0` | Keyboard + Mouse | -| `Xbox = 1` | Xbox Series X\|S / Xbox One | -| `PS5_DualSense = 2` | PlayStation 5 DualSense | +| `PC_KeyboardMouse = 0` | Keyboard + Mouse (maps to `PC_Win64`, `PC_Linux`, `Mac`) | +| `Xbox = 1` | Xbox Series X\|S / Xbox One (maps to `Xbox_Series` or `Xbox_One`) | +| `PS5_DualSense = 2` | PlayStation 5 DualSense (maps to `PS5` or `PS5_Pro`) | --- @@ -290,6 +290,7 @@ flowchart TD | `BPC_HidingSystem` | `Function Call` | `SS_EnhancedInputManager::PushContext(Hiding) / PopContext(Hiding)` | | `BPC_ActiveItemSystem` | `Function Call` | `SS_EnhancedInputManager::IsActionPressed("IA_QuickSlot1")` | | `BPC_HapticsController` (148) | `Function Call` | `SS_EnhancedInputManager::GetControllerPlatform()` — for platform detection | +| `BPC_PlatformServiceAbstraction` (150) | `Function Call / Bind OnPlatformReady` | `GetDefaultInputProfile()` — selects correct DA_InputMappingProfile for detected platform | | `WBP_PauseMenu` | `Function Call` | `SS_EnhancedInputManager::PushContext(UI) / PopContext(UI)` | | `WBP_InventoryMenu` | `Function Call` | `SS_EnhancedInputManager::PushContext(WristwatchUI)` | | `BP_PuzzleDeviceActor` | `Function Call` | `SS_EnhancedInputManager::PushContext(Inspection)` | diff --git a/docs/blueprints/AUDIT_REPORT.md b/docs/blueprints/AUDIT_REPORT.md index bf4e39a..03b92eb 100644 --- a/docs/blueprints/AUDIT_REPORT.md +++ b/docs/blueprints/AUDIT_REPORT.md @@ -117,7 +117,7 @@ These systems appear in the Plan but may need explicit spec files or are covered - `BPC_HapticsController` — ✅ Created (system 148); `docs/blueprints/12-settings/148_BPC_HapticsController.md` - `BPC_RenderPipelineManager` — ✅ Created (system 149); `docs/blueprints/12-settings/149_BPC_RenderPipelineManager.md` - `DA_RenderPipelineProfile` — ✅ Created (supplementary); `docs/blueprints/14-data-assets/DA_RenderPipelineProfile.md` -- `BPC_PlatformServiceAbstraction` — Not yet created; Master Section 12.3 +- `BPC_PlatformServiceAbstraction` — ✅ Created (system 150); `docs/blueprints/01-core/150_BPC_PlatformServiceAbstraction.md` --- diff --git a/docs/blueprints/INDEX.md b/docs/blueprints/INDEX.md index f5e2b95..17514b5 100644 --- a/docs/blueprints/INDEX.md +++ b/docs/blueprints/INDEX.md @@ -1,6 +1,6 @@ # Master Blueprint Index — UE5 Modular Game Framework -**Version:** 3.6 | **Generated:** 2026-05-22 | **Total Files:** 149 numbered + 1 starter + 2 supplementary (152 total specs) | **C++:** 27 source files (15 full + 10 stubs + 2 utility) +**Version:** 3.7 | **Generated:** 2026-05-22 | **Total Files:** 150 numbered + 1 starter + 2 supplementary (153 total specs) | **C++:** 27 source files (15 full + 10 stubs + 2 utility) This document is the canonical index of every Blueprint specification file in the framework. Each entry links to its full spec document and includes: file name, asset type, parent class, purpose summary, and key dependencies. @@ -25,7 +25,7 @@ docs/blueprints/ │ ├── 00-project-setup/ ← Project Setup & Starter Assets (1 file) │ └── GI_StarterGameInstance.md ← Minimal GameInstance; tag validation entry point -├── 01-core/ ← Foundation (7 files + 11 Data Table CSVs + 1 Macro Library) +├── 01-core/ ← Foundation (8 files + 11 Data Table CSVs + 1 Macro Library) │ ├── data-tables/ ← Per-category Gameplay Tag Data Tables (NEW — replaces DT_ProjectTags.csv) │ │ ├── DT_Tags_Player.csv (34 tags) │ │ ├── DT_Tags_Interaction.csv (36 tags) @@ -72,6 +72,7 @@ docs/blueprints/ | 05 | [`05_GM_CoreGameMode`](01-core/05_GM_CoreGameMode.md) | `GM_` Game Mode | `GameModeBase` | Core game mode; spawns player, sets default classes, pause control | 01-core | | 06 | [`06_GS_CoreGameState`](01-core/06_GS_CoreGameState.md) | `GS_` Game State | `GameStateBase` | Shared game state; tracks global flags, phase, timer | 01-core | | 07 | [`07_DA_ItemData`](01-core/07_DA_ItemData.md) | `DA_` Data Asset | `PrimaryDataAsset` | Base item data asset; inherited by all item types | 01-core | +| 150 | [`150_BPC_PlatformServiceAbstraction`](01-core/150_BPC_PlatformServiceAbstraction.md) | `BPC_` Component | `ActorComponent` | Central platform authority; unified platform detection, SDK routing, achievement/cloud/overlay | 01-core | | — | — | — | — | — | — | | 08 | [`08_BPC_HealthSystem`](02-player/08_BPC_HealthSystem.md) | `BPC_` Component | `ActorComponent` | Player health, damage resistance, death trigger, healing | 02-player | | 09 | [`09_BPC_StaminaSystem`](02-player/09_BPC_StaminaSystem.md) | `BPC_` Component | `ActorComponent` | Stamina pool, sprint/action drain, exhaustion states, regen | 02-player | @@ -237,7 +238,7 @@ docs/blueprints/ | Prefix | Type | Count | |--------|------|-------| -| `BPC_` | Blueprint Component | 82 | +| `BPC_` | Blueprint Component | 83 | | `BP_` | Blueprint Actor | 11 | | `WBP_` | Widget Blueprint | 14 | | `DA_` | Data Asset | 20 | @@ -250,7 +251,7 @@ docs/blueprints/ | `AI_` | AI Controller | 1 | | `BB_` | Blackboard | 1 | | `E_` | Enum | 5 | -| **Total** | | **161** | +| **Total** | | **162** | --- @@ -268,7 +269,8 @@ Below are the most cross-referenced systems — these are the ones the State Man | `BPC_StateManager` (130) | EVERY system (central query point) | | `SS_AudioManager` (132) | ALL systems that play audio, BP_RoomAudioZone, WBP_SettingsMenu, BPC_StateManager (heart rate → audio) | | `BPC_HapticsController` (148) | HealthSystem, FirearmSystem, MeleeSystem, ScareEventSystem, PhysicsDrag, MovementState, ReloadSystem, DeathHandling, Staminasystem, StateManager → heartbeat, AccessibilitySettings | -| `BPC_RenderPipelineManager` (149) | PerformanceScaler (delegates CVars), SettingsSystem (quality persistence), PlanarCaptureManager (budget adjustment), SettingsMenu (upscaler query), AtmosphereController | +| `BPC_RenderPipelineManager` (149) | PerformanceScaler (delegates CVars), SettingsSystem (quality persistence), PlanarCaptureManager (budget adjustment), SettingsMenu (upscaler query), PlatformServiceAbstraction (platform detection) | +| `BPC_PlatformServiceAbstraction` (150) | ALL systems (central platform query), RenderPipelineManager, EnhancedInputManager, HapticsController, AchievementSystem, SaveManager, SettingsSystem, UIManager | | `ABP_GASP` (external) | StateManager (overlay + action intensity), MovementState, Hiding, Stamina, Embodiment | --- @@ -331,7 +333,7 @@ Below are the most cross-referenced systems — these are the ones the State Man --- -*Master Blueprint Index v3.6 — The single reference document for every file in the framework. Now 149 files + 2 supplementary with State Management, MetaSounds Audio, Multiplayer Networking, Planar Capture System, Haptics Controller, and Render Pipeline Manager support.* +*Master Blueprint Index v3.7 — The single reference document for every file in the framework. Now 150 files + 2 supplementary with unified platform authority (PlatformServiceAbstraction), State Management, MetaSounds Audio, Multiplayer Networking, Planar Capture System, Haptics Controller, and Render Pipeline Manager support.* --- diff --git a/docs/checklists/cpp-blueprint-status.md b/docs/checklists/cpp-blueprint-status.md index f2cb95e..fe3c889 100644 --- a/docs/checklists/cpp-blueprint-status.md +++ b/docs/checklists/cpp-blueprint-status.md @@ -183,6 +183,7 @@ Abbreviations: | 102-114 | All 13 systems | 🔵 | ✅ | BP children + widget BPs | | 148 | `BPC_HapticsController` | 🔵 (Blueprint-only) | ✅ | ⬜ BP child attach to PlayerController | | 149 | `BPC_RenderPipelineManager` | 🔵 (Blueprint-only) | ✅ | ⬜ BP child attach to PlayerController | +| 150 | `BPC_PlatformServiceAbstraction` | 🔵 (Blueprint-only) | ✅ | ⬜ BP child attach to GI_GameFramework | ### Data Assets (14-data-assets — 16 systems) diff --git a/docs/checklists/remaining-blueprint-build-order.md b/docs/checklists/remaining-blueprint-build-order.md index 8abd4ea..98c620f 100644 --- a/docs/checklists/remaining-blueprint-build-order.md +++ b/docs/checklists/remaining-blueprint-build-order.md @@ -726,6 +726,7 @@ All 16 are Data Asset definitions. No code — create Data Asset instances per c | 105 | `SS_SettingsSystem` | BP child of GameInstanceSubsystem | Settings persistence: save/load config to disk, apply on boot | | 148 | `BPC_HapticsController` | BP child of ActorComponent | Haptics: GameplayTag-driven force feedback, DualSense triggers, heartbeat pulse | | 149 | `BPC_RenderPipelineManager` | BP child of ActorComponent | Render pipeline: quality presets, GI/shadows/upscaling per platform, PlanarCapture aware | +| 150 | `BPC_PlatformServiceAbstraction` | BP child of ActorComponent | Central platform authority: detection, SDK routing (Steam/PSN/Xbox/Nintendo), input/GFX/achievement coordination | --- diff --git a/docs/developer/INDEX.md b/docs/developer/INDEX.md index bee883c..05b29b3 100644 --- a/docs/developer/INDEX.md +++ b/docs/developer/INDEX.md @@ -1,6 +1,6 @@ # Developer Reference — UE5 Modular Game Framework -**Version:** 1.8 | **Generated:** 2026-05-22 | **Files:** 21 (1 index + 3 overview + 1 migration + 1 integration + 1 prototype + 1 starter + 10 category docs + 1 combined + 1 capture + 1 render) | **C++:** 15 full + 10 stubs = 25 systems +**Version:** 1.9 | **Generated:** 2026-05-22 | **Files:** 21 | **Systems:** 150 numbered + 2 supplementary This directory contains developer-facing reference documentation for every system in the framework. Unlike the blueprint spec files (which define *what* to build), these documents explain *how each system works internally* — the data flow, state machines, integration points, and design rationale. Use these when you need to understand a system's behavior to implement, debug, or extend it. @@ -52,6 +52,7 @@ docs/developer/ | 05 | `GM_CoreGameMode` | Foundation | Spawns player, manages game rules | | 06 | `GS_CoreGameState` | Foundation | Shared game state, phase tracker | | 07 | `DA_ItemData` | Foundation | Base item data asset | +| 150 | `BPC_PlatformServiceAbstraction` | Foundation | Central platform authority — detection, SDK routing, input/GFX/achievement coordination (NEW) | | 08 | `BPC_HealthSystem` | Player | Health, damage, death trigger | | 09 | `BPC_StaminaSystem` | Player | Stamina pool, sprint drain, exhaustion | | 10 | `BPC_StressSystem` | Player | Psychological stress tiers, hallucinations |