Files
UE5-Modular-Game-Framework/docs/blueprints/00-project-setup/GI_StarterGameInstance.md
Lefteris Notas fee12b115f Refactor GameplayTag documentation and implementation
- Updated references from GI_GameTagRegistry to DA_GameTagRegistry in architecture overview and implementation patterns documentation.
- Added new Blueprint specification for GI_StarterGameInstance, detailing its purpose, configuration, and integration pattern.
- Introduced DA_GameTagRegistry Blueprint specification, centralizing GameplayTag management and providing functions for tag validation and logging.
- Created documentation for the Starter GameInstance, outlining its role in the project setup and how other systems can integrate with it.
2026-05-20 14:31:52 +03:00

356 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GI_StarterGameInstance — Blueprint Specification
> **Asset Type:** Game Instance (derives from `UGameInstance`)
> **UE Version:** 5.55.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.