# GI_StarterGameInstance — Blueprint Specification

> **Asset Type:** Game Instance (derives from `UGameInstance`)
> **UE Version:** 5.5–5.7
> **Category:** 00-Project-Setup / Starter
> **Build Phase:** Pre-Phase 0 — Project Initialization
> **Dependencies:** `DA_GameTagRegistry` (01), 11 per-category Data Tables, GameplayTags plugin

---

## 1. Purpose

A minimal, ready-to-use GameInstance Blueprint that serves as the project's **immediate** entry point. Set this as your `Game Instance Class` in Project Settings to get tag validation and framework bootstrapping working on day one. It loads `DA_GameTagRegistry`, validates that all 11 Data Tables are registered, and broadcasts `OnFrameworkReady` when initialization completes.

**This is intentionally simple.** As the project matures, replace it with `GI_GameFramework` (04) which adds full game-phase management, subsystem ownership, platform init, and save-slot orchestration. All systems that bind to `OnFrameworkReady` will continue working with either GameInstance.

---

## 2. Class Settings

| Setting | Value |
|---------|-------|
| **Parent Class** | `GameInstance` |
| **Blueprint Type** | Game Instance |
| **Asset Path** | `/Game/Framework/Core/GI_StarterGameInstance` |
| **Is Abstract** | No |

**UE5 Setup:** `Project Settings → Maps & Modes → Game Instance Class` → `GI_StarterGameInstance`

---

## 3. Enums

None. No custom enums are defined in this system.

---

## 4. Structs

None. No custom structs are defined in this system.

---

## 5. Variables

### Configuration (Instance Editable)

| Name | Type | Default | Category | Description |
|------|------|---------|----------|-------------|
| `TagRegistry` | `DA_GameTagRegistry` (Object Reference) | *Assigned in Class Defaults* | Config | Hard reference to the `DA_GameTagRegistry` Data Asset |
| `bValidateTagsOnInit` | `Boolean` | `true` | Config | If true, calls `DA_GameTagRegistry.GetAllRegisteredTags()` during `Event Init` and logs tag count |
| `bLogTagsOnInit` | `Boolean` | `false` | Debug | If true, calls `DA_GameTagRegistry.LogAllTags()` after validation (Editor-only; heavy logging) |

### Internal (Private)

| Name | Type | Default | Category | Description |
|------|------|---------|----------|-------------|
| `bFrameworkInitialized` | `Boolean` | `false` | State | Set to `true` after `Event Init` completes successfully |

---

## 6. Functions

### Public Functions

#### `GetTagRegistry()` → `DA_GameTagRegistry` *(Blueprint Pure)*

- **Description:** Returns the cached `TagRegistry` reference. Returns `None` if not yet loaded.
- **Parameters:** None
- **Flow:**
  1. Return `TagRegistry` variable

#### `IsFrameworkReady()` → `Boolean` *(Blueprint Pure)*

- **Description:** Returns whether the framework has completed initialization. Systems should check this before querying tag-dependent services.
- **Parameters:** None
- **Flow:**
  1. Return `bFrameworkInitialized`

### Protected / Private Functions

#### `ValidateFrameworkTags()` *(Blueprint Callable, Private)*

- **Description:** Loads the tag registry, counts registered tags, and logs warnings if zero tags are found. Called automatically during `Event Init`.
- **Parameters:** None
- **Flow:**
  1. `IsValid(TagRegistry)`? → False: Print Error "TagRegistry not assigned!" → Return
  2. Call `TagRegistry.GetAllRegisteredTags()` → `AllTags` (Array\<GameplayTag\>)
  3. `Array Length(AllTags) == 0`?
     - True: Print Warning "No Gameplay Tags registered! Check Project Settings → GameplayTags → Gameplay Tag Table List. All 11 Data Tables must be added."
     - False: Print String "DA_GameTagRegistry initialized: {Array Length} tags registered across 11 Data Tables."
  4. If `bLogTagsOnInit`: Call `TagRegistry.LogAllTags()`

---

## 7. Event Dispatchers

| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnFrameworkReady` | — | Public | Fires after `Event Init` completes and tag validation passes. Other systems bind to this to defer initialization until the framework is ready. |
| `OnFrameworkInitFailed` | `ErrorReason: String` | Public | Fires if `TagRegistry` is invalid or zero tags are found during init. Systems should handle gracefully — show error UI, disable gameplay. |

---

## 8. Overridden Events

### Event: `Event Init`

- **Description:** UE5's GameInstance initialization event. Fires once when the game starts, before any level loads. This is where framework bootstrapping happens.
- **Flow:**
  1. Call `Parent: Event Init` (important — don't skip)
  2. Print String: "GI_StarterGameInstance: Init started"
  3. `Branch: bValidateTagsOnInit?`
     - False → Print String "Tag validation skipped (bValidateTagsOnInit = false)"
     - True → Call `ValidateFrameworkTags()`
  4. `Branch: IsValid(TagRegistry)?`
     - False → Print Error "DA_GameTagRegistry reference is invalid!" → Call `OnFrameworkInitFailed("TagRegistry not assigned or invalid")` → Return
     - True → Continue
  5. Set `bFrameworkInitialized = true`
  6. Call `OnFrameworkReady` (broadcast to all bound listeners)
  7. Print String: "GI_StarterGameInstance: Init complete — OnFrameworkReady broadcast"

---

## 9. Blueprint Graph Logic Flow

```mermaid
flowchart TD
    A[Event Init] --> B[Call Parent: Event Init]
    B --> C{ bValidateTagsOnInit? }
    C -->|True| D[Call ValidateFrameworkTags]
    C -->|False| E[Skip validation]
    D --> F{ IsValid TagRegistry? }
    F -->|False| G[Print Error<br>Broadcast OnFrameworkInitFailed]
    F -->|True| H[Set bFrameworkInitialized = true]
    H --> I[Broadcast OnFrameworkReady]
    I --> J[Print 'Init Complete']
```

### ValidateFrameworkTags Flow

```mermaid
flowchart TD
    A[ValidateFrameworkTags] --> B{ IsValid TagRegistry? }
    B -->|False| C[Print Error: TagRegistry not assigned]
    B -->|True| D[Call GetAllRegisteredTags → AllTags]
    D --> E{ Array Length == 0? }
    E -->|True| F[Print Warning: No tags registered]
    E -->|False| G[Print: N tags registered]
    G --> H{ bLogTagsOnInit? }
    H -->|True| I[Call LogAllTags]
    H -->|False| J[Return]
    I --> J
    F --> J
    C --> J
```

---

## 10. Communication Matrix

| Source | Target | Method | Direction | Data |
|--------|--------|--------|-----------|------|
| `GI_StarterGameInstance` | `DA_GameTagRegistry` | Direct function call | Outbound | Calls `GetAllRegisteredTags()`, `LogAllTags()`, `ValidateTag()` |
| `GI_StarterGameInstance` | All bound systems | `OnFrameworkReady` dispatcher | Outbound broadcast | No data — listeners query `IsFrameworkReady()` |
| `GI_StarterGameInstance` | All bound systems | `OnFrameworkInitFailed` dispatcher | Outbound broadcast | `ErrorReason: String` |
| Any system | `GI_StarterGameInstance` | `GetGameInstance()` → Cast | Inbound query | Systems call `IsFrameworkReady()` before initialization |

---

## 11. Validation Checklist

- [ ] `GI_StarterGameInstance` set as `Game Instance Class` in `Project Settings → Maps & Modes`
- [ ] `TagRegistry` variable assigned to `DA_GameTagRegistry` Data Asset in Class Defaults
- [ ] All 11 Data Tables registered in `Project Settings → GameplayTags → Gameplay Tag Table List`
- [ ] On PIE (Play In Editor): output log shows "N tags registered across 11 Data Tables"
- [ ] On PIE with `bLogTagsOnInit = true`: all tag names printed to output log
- [ ] If `TagRegistry` is unassigned: error prints and `OnFrameworkInitFailed` fires (test by clearing the variable)
- [ ] Other systems successfully bind to `OnFrameworkReady` and defer their init
- [ ] Edge case: 0 tags in Data Tables → warning prints, `OnFrameworkInitFailed` does NOT fire (empty tables are a warning, not a failure)

---

## 12. Reuse Notes

- **Replacement path:** When you are ready for the full `GI_GameFramework` (04), simply change the `Game Instance Class` in Project Settings. All systems that bind to `OnFrameworkReady` on either GameInstance will work — `GI_GameFramework` includes the same dispatcher.
- **Project-specific init:** Add custom initialization (achievement platform, analytics, save migration) after the `OnFrameworkReady` broadcast in `Event Init`.
- **Tag registry is a Data Asset, not a subsystem:** You must manually assign the `TagRegistry` reference in Class Defaults. It is NOT auto-discovered.
- **Multi-platform:** On consoles, `Event Init` fires before any level loads — same as PC. No platform-specific code is needed.

---

## 13. Manual Implementation Guide

> **For human implementer:** Follow these steps to build `GI_StarterGameInstance` in UE5 Blueprints. This is the FIRST Blueprint you should create — it enables tag validation for all other systems.

### 13.1 Class Setup

1. Right-click in Content Browser → **Blueprint Class**
2. Search for parent class: `GameInstance`
3. Name: `GI_StarterGameInstance`
4. Save to: `Content/Framework/Core/`
5. Open **Project Settings → Maps & Modes** → Set `Game Instance Class` to `GI_StarterGameInstance`

### 13.2 Variables

Add to Class Defaults:

| Variable | Type | Instance Editable | Default | Category |
|----------|------|------------------|---------|----------|
| `TagRegistry` | `DA_GameTagRegistry` (Object Reference) | ✓ | *Select `DA_GameTagRegistry` asset* | Config |
| `bValidateTagsOnInit` | `Boolean` | ✓ | `true` | Config |
| `bLogTagsOnInit` | `Boolean` | ✓ | `false` | Debug |
| `bFrameworkInitialized` | `Boolean` | ✗ (Private) | `false` | State |

**⚠️ Important:** For `TagRegistry`, use the type `DA_GameTagRegistry` (your specific Data Asset Blueprint class, NOT the generic `PrimaryDataAsset`). Compile `DA_GameTagRegistry` first so it appears in the type dropdown.

### 13.3 Event Dispatchers

Create two Event Dispatchers in the **My Blueprint** panel:

1. `OnFrameworkReady` — no parameters
2. `OnFrameworkInitFailed` — add one input parameter:
   - `ErrorReason` (String)

### 13.4 Override Event Init

1. In the **My Blueprint** panel, hover over **Functions** → click **Override** → select `Event Init`
2. Build the following graph:

```
[Event Init]
  Step 1: Call "Parent: Event Init" (right-click event node → "Add Call to Parent")
  Step 2: Print String: "GI_StarterGameInstance: Init started"
           → Text (Format Text): "GI_StarterGameInstance: Init started"
  Step 3: Branch (Condition: bValidateTagsOnInit)
    True → Call ValidateFrameworkTags (see 13.5)
    False → Print String: "Tag validation skipped (bValidateTagsOnInit = false)"
  Step 4: IsValid(TagRegistry) → Branch
    False:
      → Print String: "DA_GameTagRegistry reference is invalid!"
      → Call OnFrameworkInitFailed (ErrorReason = "TagRegistry not assigned or invalid")
      → Return Node
    True: Continue
  Step 5: Set bFrameworkInitialized = true
  Step 6: Call OnFrameworkReady (no params)
  Step 7: Print String: "GI_StarterGameInstance: Init complete — OnFrameworkReady broadcast"
```

**Nodes to Search:** `Event Init`, `Add Call to Parent`, `Print String`, `Format Text`, `Branch`, `IsValid`, `Set`, `Call OnFrameworkReady`, `Call OnFrameworkInitFailed`

### 13.5 Implement ValidateFrameworkTags

Create a new function: **BlueprintCallable**, Private, named `ValidateFrameworkTags`.

```
[Function: ValidateFrameworkTags] (BlueprintCallable, Private)
  Step 1: IsValid(TagRegistry) → Branch
    False: Print String "TagRegistry not assigned in GI_StarterGameInstance!" → Return
    True: Continue
  Step 2: Call TagRegistry → GetAllRegisteredTags() → store in "AllTags" (Array<GameplayTag>)
  Step 3: Array Length(AllTags) → store in "TagCount" (Integer)
  Step 4: Branch (Condition: TagCount == 0)
    True: Print String (Color: Yellow): "WARNING: No Gameplay Tags registered! Check Project Settings → GameplayTags → Gameplay Tag Table List. All 11 Data Tables must be added."
    False: Print String (Format Text): "DA_GameTagRegistry initialized: {TagCount} tags registered across 11 Data Tables."
  Step 5: Branch (Condition: bLogTagsOnInit)
    True: Call TagRegistry → LogAllTags()
    False: Continue (no action)
  Step 6: Return
```

**Nodes to Search:** `IsValid`, `GetAllRegisteredTags`, `Array Length`, `Branch`, `Print String`, `Format Text`, `LogAllTags`

### 13.6 Implement GetTagRegistry

Create a new function: **BlueprintPure**, Public, named `GetTagRegistry`.

```
[Function: GetTagRegistry] → DA_GameTagRegistry (BlueprintPure)
  Return TagRegistry
```

### 13.7 Implement IsFrameworkReady

Create a new function: **BlueprintPure**, Public, named `IsFrameworkReady`.

```
[Function: IsFrameworkReady] → Boolean (BlueprintPure)
  Return bFrameworkInitialized
```

### 13.8 How Other Systems Bind to OnFrameworkReady

In any other Blueprint that needs framework services (tag validation, subsystems, etc.):

```
[Event BeginPlay]
  Step 1: Get Game Instance → Cast to GI_StarterGameInstance → Store as "GameInstance"
  Step 2: Branch: IsValid(GameInstance)?
    True:
      → Branch: GameInstance → IsFrameworkReady()?
        True: Call "OnFrameworkReadyHandler" immediately (already initialized)
        False: Bind "OnFrameworkReadyHandler" to GameInstance.OnFrameworkReady
    False: Print Warning "GI_StarterGameInstance not found!"
```

**Custom Event: OnFrameworkReadyHandler**
```
[Custom Event: OnFrameworkReadyHandler]
  Step 1: Unbind from GameInstance.OnFrameworkReady (if bound — prevents double-fire)
  Step 2: ... proceed with system-specific initialization ...
```

### 13.9 Quick Node Reference

| Node | Where to Find | Used For |
|------|---------------|----------|
| `Event Init` | Override in My Blueprint → Functions | GameInstance startup |
| `Get Game Instance` | Right-click → "Get Game Instance" | Any Blueprint that needs the GameInstance |
| `Cast to GI_StarterGameInstance` | Right-click → "Cast to GI_StarterGameInstance" | Type-safe access to framework functions |
| `IsValid` | Right-click → "IsValid" | Null-checking object references |
| `Bind Event to OnFrameworkReady` | Right-click on dispatcher → "Bind Event" | Deferred initialization |
| `Unbind Event from OnFrameworkReady` | Right-click on dispatcher → "Unbind Event" | Clean up after handler fires |

---

## 14. Blueprint Build Checklist

- [ ] Create `GI_StarterGameInstance` Blueprint (Parent: `GameInstance`)
- [ ] Set as `Game Instance Class` in `Project Settings → Maps & Modes`
- [ ] Create `DA_GameTagRegistry` Data Asset first (required for `TagRegistry` variable type)
- [ ] Add variable `TagRegistry` (type: `DA_GameTagRegistry`) and assign the Data Asset
- [ ] Add variable `bValidateTagsOnInit` (Boolean, default `true`)
- [ ] Add variable `bLogTagsOnInit` (Boolean, default `false`)
- [ ] Add variable `bFrameworkInitialized` (Boolean, default `false`, Private)
- [ ] Create Event Dispatcher `OnFrameworkReady` (no params)
- [ ] Create Event Dispatcher `OnFrameworkInitFailed` (1 param: `ErrorReason` String)
- [ ] Override `Event Init` — add Call to Parent, validation branch, dispatcher broadcasts
- [ ] Implement `ValidateFrameworkTags()` — validate registry, count tags, optional log
- [ ] Implement `GetTagRegistry()` (BlueprintPure) — return TagRegistry reference
- [ ] Implement `IsFrameworkReady()` (BlueprintPure) — return bFrameworkInitialized
- [ ] Compile and test: PIE → output log shows "DA_GameTagRegistry initialized: N tags"
- [ ] Test error path: clear `TagRegistry` variable → `OnFrameworkInitFailed` fires
- [ ] Test with `bLogTagsOnInit = true` → all tags printed to output log
- [ ] Verify other systems can bind to `OnFrameworkReady` and defer init correctly

---

## 15. Multiplayer Networking

**Replication: None needed.** The GameInstance is a client-only singleton — each client has its own instance. The `DA_GameTagRegistry` Data Asset loads identically from disk on all clients and servers. Event Dispatchers (`OnFrameworkReady`, `OnFrameworkInitFailed`) fire locally on each instance.

**Authority: N/A.** No runtime state changes. Tag data is read-only configuration.

**Multiplayer Note:** In a networked game, `Event Init` fires on both server and each client's GameInstance. Tag validation runs independently on each — which is correct, since Data Tables and GameplayTags must be identical across all instances for networked tag replication to function.
