# 04 — Game Instance Kernel (`GI_GameFramework`)

> **⚡ C++ Status: Full Implementation** — `Source/PG_Framework/Public/Core/GI_GameFramework.h` provides the complete application kernel: game phase state machine, session flags, save slot management, service resolution, platform initialization, and all event dispatchers. **Create a BP child** (Blueprint Class → All Classes → `GI_GameFramework`) for configuration only — set `TagRegistry` in Class Defaults. Do NOT rebuild the state machine or service registry in BP. See `docs/developer/cpp-integration-guide.md` for exact setup steps.
>
> ---

## Purpose
The single persistent object that lives for the entire application session. It owns global subsystems, manages save slot ownership, and provides the canonical entry point for service resolution.

## Dependencies
- **Requires:** GameplayTags plugin enabled, all `SS_` Subsystems
- **Required By:** `GM_CoreGameMode`, `WBP_HUDController`, `WBP_MenuFlowController`, any system that resolves a subsystem
- **Engine/Plugin Requirements:** GameplayTags, DeveloperSettings

## Class Info
| Property | Value |
|----------|-------|
| **Parent Class** | `GameInstance` |
| **Class Type** | Blueprint (BlueprintType) |
| **Asset Path** | `Content/Framework/Core/GI_GameFramework` |
| **Implements Interfaces** | None |

---

## 1. Enums

### `E_GamePhase`
| Value | Display Name | Description |
|-------|-------------|-------------|
| `MainMenu` = 0 | Main Menu | Game at main menu, no session active |
| `Loading` = 1 | Loading | Transition between levels or phases |
| `InGame` = 2 | In Game | Normal gameplay active |
| `Paused` = 3 | Paused | Game logic paused via pause menu or system |
| `Cutscene` = 4 | Cutscene | Sequencer-driven cutscene playing |
| `DeathLoop` = 5 | Death Loop | Player died and death loop is active |
| `AltDeathSpace` = 6 | Alt Death Space | Alternate death/purgatory space active |
| `Credits` = 7 | Credits | End credits playing |
| `PostGame` = 8 | Post Game | After credits, meta/post-game state |

### `E_PlatformType`
| Value | Display Name | Description |
|-------|-------------|-------------|
| `Steam` = 0 | Steam | Steam platform services |
| `PlayStation` = 1 | PlayStation | PlayStation platform services |
| `Xbox` = 2 | Xbox | Xbox platform services |
| `Switch` = 3 | Nintendo Switch | Nintendo platform services |
| `Generic` = 4 | Generic | Fallback for unknown/unlisted platforms |

---

## 2. Structs

*No structs defined in this class. All data is stored as direct variables or via subsystems.*

---

## 3. Variables

### Configuration (Instance Editable, Expose On Spawn)

| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `ActiveSaveSlotIndex` | `Integer` | `0` | `Save` | Which save slot is currently loaded (0\u2013N) |
| `PlatformType` | `E_PlatformType` | `Generic` | `Platform` | Identifies the current platform for service abstraction |
| `bFirstLaunch` | `Boolean` | `true` | `Save` | True on first-ever boot; triggers intro flow |

### Internal (Private / Protected, No Expose)

| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `SessionFlags` | `Map<GameplayTag, Boolean>` | `Empty Map` | `Session` | Transient flags that do not persist to disk |
| `CurrentGamePhase` | `E_GamePhase` | `MainMenu` | `State` | Tracks the top-level game phase for routing |

---

## 4. Functions

### Public Functions

#### `GetSubsystem` → `Object Reference`
- **Description:** Returns the requested subsystem by GameplayTag lookup. This is the canonical service resolver for all systems.
- **Parameters:**
  | Param | Type | Description |
  |-------|------|-------------|
  | `Tag` | `GameplayTag` | The tag identifying which subsystem to return |
- **Blueprint Authority:** Any
- **Flow:**
  1. Look up subsystem class reference mapped to the input tag
  2. Call `GetSubsystem()` with resolved class
  3. Return the subsystem reference (null if not found)
  4. If null, log a warning via `FL_GameUtilities.LogDebug`

#### `SetSessionFlag` → `Void`
- **Description:** Sets a transient session flag that does not persist to disk.
- **Parameters:**
  | Param | Type | Description |
  |-------|------|-------------|
  | `Tag` | `GameplayTag` | Flag identifier |
  | `Value` | `Boolean` | Flag value |
- **Flow:** `SessionFlags.Add(Tag, Value)`

#### `GetSessionFlag` → `Boolean`
- **Description:** Reads a transient session flag value.
- **Parameters:**
  | Param | Type | Description |
  |-------|------|-------------|
  | `Tag` | `GameplayTag` | Flag identifier |
- **Flow:** Return `SessionFlags.Find(Tag, false)`

#### `SetActiveSlot` → `Void`
- **Description:** Designates the active save slot index. Does not trigger a save or load.
- **Parameters:**
  | Param | Type | Description |
  |-------|------|-------------|
  | `SlotIndex` | `Integer` | Slot index to set active |

#### `SetGamePhase` → `Void`
- **Description:** Updates `CurrentGamePhase` and broadcasts the `OnGamePhaseChanged` dispatcher. This is the single point of authority for phase transitions.
- **Parameters:**
  | Param | Type | Description |
  |-------|------|-------------|
  | `Phase` | `E_GamePhase` | New phase value |
- **Flow:**
  1. `CurrentGamePhase = Phase`
  2. Broadcast `OnGamePhaseChanged`

#### `InitPlatformServices` → `Void`
- **Description:** Called during `Init()`; routes to platform-specific service wrappers based on `PlatformType`.
- **Flow:**
  1. Switch on `PlatformType`
  2. Call platform init stubs (empty in editor)
  3. Broadcast `OnPlatformReady`

---

## 5. Event Dispatchers

| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnGamePhaseChanged` | `NewPhase: E_GamePhase` | `Public` | Fired on any phase transition |
| `OnPlatformReady` | `PlatformType: E_PlatformType` | `Public` | Fired when platform services confirm ready |

---

## 6. Overridden Events / Custom Events

### Event: `Init()`
- **Description:** Override of `GameInstance.Init()`. Called automatically when the game instance is created.
- **Flow:**
  1. Call parent `Init()`
  2. Call `InitPlatformServices()`
  3. All `SS_` Subsystems are automatically initialized by UE (they are GameInstanceSubsystems)
  4. Load persistent settings via `SS_SettingsSystem.PopulateDefaults()`
  5. Check existing save data via `SS_SaveSystem.GetSlotManifest()`
  6. Call `SetGamePhase(MainMenu)`
  7. Broadcast `OnPlatformReady`

### Event: `Shutdown()`
- **Description:** Override of `GameInstance.Shutdown()`. Called when the game instance is destroyed.
- **Flow:**
  1. Save persistent settings via `SS_SettingsSystem`
  2. Call parent `Shutdown()`

---

## 7. Blueprint Graph Logic Flow

```mermaid
flowchart TD
    A[GameInstance Init] --> B[Call InitPlatformServices]
    B --> C{Platform identified?}
    C -->|Yes| D[Platform init stubs]
    C -->|No| E[Set PlatformType = Generic]
    D --> F[SS_SettingsSystem.PopulateDefaults]
    E --> F
    F --> G[SS_SaveSystem.GetSlotManifest]
    G --> H[SetGamePhase MainMenu]
    H --> I[Broadcast OnGamePhaseChanged]
    I --> J[Broadcast OnPlatformReady]

    K[Any system calls SetGamePhase] --> L[Update CurrentGamePhase]
    L --> M[Broadcast OnGamePhaseChanged]
    M --> N[Receivers: GM_CoreGameMode, WBP_HUDController, etc.]
```

---

## 8. Communication Matrix

| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| `GI_GameFramework` | `Direct Reference (owns)` | Manages lifecycle of all `SS_` Subsystems |
| `GI_GameFramework` | `Dispatcher: OnGamePhaseChanged` | `NewPhase: E_GamePhase` to `GM_CoreGameMode`, `WBP_HUDController` |
| `GI_GameFramework` | `Dispatcher: OnPlatformReady` | `PlatformType: E_PlatformType` to all listeners |
| Any Blueprint | `Direct GetSubsystem()` | Subsystem reference by GameplayTag lookup |
| `GM_CoreGameMode` | `Direct Reference` | Reads `CurrentGamePhase`, calls `SetGamePhase` |

---

## 9. Validation / Testing Checklist

- [ ] `Init()` fires without errors and all SS_ Subsystems are created
- [ ] `SetGamePhase()` updates `CurrentGamePhase` and fires `OnGamePhaseChanged`
- [ ] `GetSubsystem()` returns correct subsystem for each registered tag
- [ ] `GetSubsystem()` returns null and logs warning for unknown tags
- [ ] `SetSessionFlag()` and `GetSessionFlag()` round-trip correctly
- [ ] `SetActiveSlot()` updates slot index without side effects
- [ ] `InitPlatformServices()` routes to correct platform stub
- [ ] `bFirstLaunch` stays true until explicitly cleared by onboarding flow
- [ ] Edge case: calling `SetGamePhase()` with same value does not fire dispatcher (if desired)
- [ ] Edge case: `GetSubsystem()` during `PreInit()` returns null (graceful)

---

## 10. Reuse Notes

- Replace `E_PlatformType` routing with new platform entries for additional platforms.
- Add new subsystems to the init list; they are auto-initialized by UE's GameInstanceSubsystem system.
- The `SessionFlags` map lets you add per-project transient state without modifying this class.
- For multi-world / split-screen, treat this as a single-instance singleton per application session.
- `PlatformType` can be overridden via command-line switch `-Platform=Steam` in packaging scripts.

---

## 11. Multiplayer Networking

### Replicated Variables

| Variable | Type | Condition | Description |
|----------|------|-----------|-------------|
| `CurrentGamePhase` | `E_GamePhase` | `Replicated Using OnRep_GamePhase` | Replicated phase; OnRep fires dispatcher for all clients |
| `ActiveSaveSlotIndex` | `Integer` | `Replicated` | Synced save slot |
| `PlatformType` | `E_PlatformType` | `Replicated` | Platform info for cross-play filtering |

### Authority Notes

| Function | Authority | Notes |
|----------|-----------|-------|
| `SetGamePhase` | `Server` | Clients cannot change game phase. OnRep broadcasts to all. |
| `SetSessionFlag` | `Server` | Session flags are server-authoritative. |
| `GetSubsystem` | `Any` | Read-only — safe for clients. Returns subsystems that exist per-side. |
| `InitPlatformServices` | `Any` | Runs on each instance; platform type synced. |

### Server RPCs

| RPC | Direction | Description |
|-----|-----------|-------------|
| `Server_SetGamePhase` | Client→Server | Client requests phase change (e.g. player pauses). Server validates and sets. |

### Client Prediction

- GamePhase transitions are server-authoritative with no client prediction.
- Clients bind to `OnGamePhaseChanged` dispatcher (fired by `OnRep_GamePhase`) — same as single-player.
- `SessionFlags` are not predicted; clients read after server sets them.

### OnRep Handlers

```
OnRep_GamePhase(NewPhase)
  → Broadcast OnGamePhaseChanged(NewPhase)
  → All systems react exactly as in single-player
```