Star Topology — Plugin Dependencies

graph TD CORE["PGXCoreRuntime
L1 — Single Core"] CORE --> Profile["Profile v2.0"] CORE --> Log["Log v3.0"] CORE --> Save["Save v1.0"] CORE --> GameFlow["GameFlow v1.0"] CORE --> PSO["PSO v2.0"] CORE --> LevelFlow["LevelFlow v1.0"] CORE --> Loading["Loading v1.0"] CORE --> MGOS["MGOS v1.0"] CORE --> Audio["Audio v1.1"] CORE --> Registry["Registry v2.0"] CORE --> Construction["Construction v1.3"] CORE --> Message["Message v1.0"] CORE --> EventHandler["EventHandler v1.0"] Loading -.->|"exception"| GameFlow Loading -.->|"exception"| PSO PSO -.->|"exception"| GameFlow style CORE fill:#7f00ff,stroke:#7f00ff,color:#fff style Profile fill:#111128,stroke:#ffc107,color:#ffc107 style Log fill:#111128,stroke:#4caf50,color:#4caf50 style Save fill:#111128,stroke:#4caf50,color:#4caf50 style GameFlow fill:#111128,stroke:#ff9800,color:#ff9800 style PSO fill:#111128,stroke:#00bcd4,color:#00bcd4 style LevelFlow fill:#111128,stroke:#2196f3,color:#2196f3 style Loading fill:#111128,stroke:#e91e63,color:#e91e63 style MGOS fill:#111128,stroke:#7f00ff,color:#7f00ff style Audio fill:#111128,stroke:#ff9800,color:#ff9800 style Registry fill:#111128,stroke:#00ccff,color:#00ccff style Construction fill:#111128,stroke:#008080,color:#008080 style Message fill:#111128,stroke:#4caf50,color:#4caf50 style EventHandler fill:#111128,stroke:#ff9800,color:#ff9800

Why Star Topology?

In a star topology, every L2 plugin depends exclusively on the L1 core (PGXCoreRuntime). This means:

Zero inter-plugin coupling — removing any L2 plugin never breaks another. Predictable compilation — changing one system only recompiles that system and the core. Clean testing — each subsystem can be tested in isolation.

The three documented exceptions (Loading→GameFlow, Loading→PSO, PSO→GameFlow) exist because loading screen orchestration genuinely requires awareness of game flow state and PSO precaching. These are validated, load-order critical dependencies — not convenience shortcuts.

Initialization Sequence

sequenceDiagram participant Engine participant Profile participant GameFlow participant Log participant Save participant PSO participant Widget participant Audio participant Registry participant Message participant EventHandler Engine->>Profile: Initialize() — Platform detection Engine->>GameFlow: Initialize() — State machine Engine->>Log: Initialize() — Log backends Engine->>Save: Initialize() — Slot discovery Engine->>PSO: Initialize() — Pipeline contexts Engine->>Widget: Initialize() — UI bootstrap Engine->>Audio: Initialize() — Dual backends Engine->>Registry: Initialize() — DataTable compile Engine->>Message: Initialize() — Pub/sub bus Engine->>EventHandler: Initialize() — Resolution bus Note over Profile,EventHandler: Deterministic order — Profile always first, EventHandler always last

Deterministic Initialization

PGX enforces a strict initialization order through subsystem dependencies. Profile initializes first (platform budgets must be available before any system reads configuration). EventHandler initializes last (it needs all systems registered to route events correctly).

This eliminates race conditions and ensures that when a subsystem's Initialize() runs, all its dependencies are already live.

Data Flow — Configuration to Runtime

flowchart LR DA["Config DataAsset
Editor-time"] -->|AssetRegistry
auto-discovery| Sub["Subsystem
Initialize()"] Sub -->|"Read budgets"| Profile["Profile Budgets"] Sub -->|"Enforce limits"| Runtime["Runtime State"] Runtime -->|"Delegates"| Listeners["Listeners"] Runtime -->|"Broadcast"| MsgBus["Message Bus"] Runtime -->|"Fire"| EvtBus["EventHandler Bus"] BP["Blueprint
BP Library nodes"] -->|"Static UFUNCTION"| Sub CPP["C++
Direct subsystem access"] --> Sub style DA fill:#111128,stroke:#00bcd4,color:#00bcd4 style Sub fill:#111128,stroke:#7f00ff,color:#7f00ff style Profile fill:#111128,stroke:#ffc107,color:#ffc107 style Runtime fill:#111128,stroke:#4caf50,color:#4caf50 style MsgBus fill:#111128,stroke:#4caf50,color:#4caf50 style EvtBus fill:#111128,stroke:#ff9800,color:#ff9800 style BP fill:#111128,stroke:#2196f3,color:#2196f3 style CPP fill:#111128,stroke:#e91e63,color:#e91e63 style Listeners fill:#111128,stroke:#00ccff,color:#00ccff

Config DataAssets as Universal Entry Point

Every PGX system discovers its configuration at startup through AssetRegistry scanning. The developer creates a DataAsset in the Content Browser, fills in properties, and the system picks it up automatically.

Profile v2.0 adds platform-aware budgets: 11 subsystems read their limits from UPGXPlatformConfig and enforce them at runtime. This means the same project can target mobile, console, and PC with different quality levels — all from DataAssets, zero code changes.

Three-Bus Communication Model

flowchart TB subgraph MSG ["Message Bus — Pub/Sub"] direction LR Sender["Any System"] -->|"Broadcast(Tag, Payload)"| MsgSub["UPGXMessageSubsystem"] MsgSub -->|"Deliver"| L1["Listener A"] MsgSub -->|"Deliver"| L2["Listener B"] MsgSub -->|"Deliver"| L3["Listener C"] end subgraph EVT ["EventHandler Bus — Resolution"] direction LR Caller["Any System"] -->|"FirePGXEvent(Tag, Ctx)"| EvtSub["UPGXEventHandlerSubsystem"] EvtSub -->|"Priority sort"| H1["Handler 1 (P:100)"] EvtSub -->|"If unhandled"| H2["Handler 2 (P:50)"] EvtSub -->|"If unhandled"| H3["Handler 3 (P:10)"] end subgraph DEL ["Native Delegates — Direct"] direction LR System["Subsystem"] -->|"OnStateChanged"| Bound1["Bound Object A"] System -->|"OnStateChanged"| Bound2["Bound Object B"] end style MSG fill:#0a0a1a,stroke:#4caf50,color:#4caf50 style EVT fill:#0a0a1a,stroke:#ff9800,color:#ff9800 style DEL fill:#0a0a1a,stroke:#2196f3,color:#2196f3

When to Use Each Bus

Message Bus (green) — Fire-and-forget notifications. "Something happened, anyone who cares can react." No return value, no priority, no conflict resolution. Use for: damage events, pickup notifications, UI updates.

EventHandler Bus (orange) — "Something wants to happen, who decides?" Priority-based resolution with conflict policies. Handlers compete to handle the event. Use for: ability activation, interaction resolution, AI behavior selection.

Native Delegates (blue) — Direct C++ multicast for performance-critical paths within a single system. No cross-plugin routing. Use for: state change callbacks within a subsystem's own scope.

Three-Layer Architecture

graph TB subgraph L1 ["Layer 1 — Core"] CoreRT["PGXCoreRuntime
Base classes, types, interfaces"] CoreEd["PGXCoreEditor
Factories, registry, toolbar"] end subgraph L2 ["Layer 2 — Systems (13 Production + 14 Stub)"] Sys1["Profile · Log · Save"] Sys2["GameFlow · PSO · LevelFlow · Loading"] Sys3["MGOS · Audio · Registry"] Sys4["Construction · Message · EventHandler"] end subgraph Tools ["Tool Plugins (5)"] T1["PGXDocs · PGXEditorTools · PGXVersionControl"] T2["PGXSimHarness · PGXScaffold"] end L1 --> L2 L1 --> Tools style L1 fill:#111128,stroke:#7f00ff,color:#7f00ff style L2 fill:#111128,stroke:#00bcd4,color:#00bcd4 style Tools fill:#111128,stroke:#ff9800,color:#ff9800

Clean Layer Separation

Layer 1 contains base classes, shared types, interfaces, and all editor infrastructure (factories, Content Browser extension, toolbar, Hub dashboard). It's the foundation everything else builds on.

Layer 2 contains the 13 production subsystems and 14 stub plugins ready for future implementation. Each L2 plugin has a Runtime module (gameplay logic) and optionally an Editor module (inspector panels, custom widgets).

Tool Plugins are editor-only utilities: documentation viewer, simulation harness, project scaffolding, and more. They never ship in packaged builds.

← Back to Overview Explore Systems →