Game Features Plugin — Usage Reference Notes

Game Features Plugin — Usage Reference Notes

Core Concepts

Loading States

  • Installed: Means “content is on disk / downloaded and the system allows you to mount it.” At this point the Pak may not be mounted yet, so the UE asset system may not be able to locate its Content by path.
  • Mount: The act of bringing a Pak/directory into the virtual file system so that resource paths like /PluginName/... become visible. Only after mounting do most asset references (especially hard-reference chains and the actual Load of soft references) have a real chance of succeeding.

Loading Order Flowchart

1
2
3
4
5
flowchart LR
I[Installed\nContent on disk / installable] --> R[Registered\nGameFeatureData discovered and registered]
R --> M[Mount\nPak/directory mounted\nAsset paths visible]
M --> L[Loaded\nAssets/classes resolvable and loadable]
L --> A[Active\nActions executed\nGameplay logic in effect]

The 4 CurrentState Values of a Game Features Plugin

These four states are essentially the key milestones of the Game Feature Plugin state machine. They describe the journey of a GFP from “discoverable” to “usable / in effect,” and they directly determine whether cross-GFP asset references will fail at runtime due to an unmounted or unloaded dependency.

  1. Installed

    • Meaning: The plugin “exists and can be managed (installed/uninstalled)” as far as the system is concerned. If this is optional downloadable content (DLC / Chunk / optional Pak), this state usually means the installation step has completed. Think of it as knowing a disc exists, but not having read it yet.
    • What you can rely on: Content is not yet guaranteed to be mounted, so loading asset paths at this stage is generally unreliable.
  2. Registered

    • Meaning: The plugin has been recognized and fully registered. The corresponding GameFeatureData can be found, and the system knows “what Actions/rules this GFP has.” The disc is in the drive and can be read, but you don’t know what’s on it yet.
    • What you can rely on: Assets are still not guaranteed to be loadable in most projects (mounting typically happens in a later step or immediately after), but you can perform declarative preparation — for example, building a list of which Actions will be executed.
  3. Loaded

    • Meaning: Plugin content has reached the point where “assets and classes can be loaded” — which typically includes the Pak being mounted and asset-bundle paths being resolvable. You’ve entered the game, but none of the gameplay features are active yet.
    • What you can rely on: Soft and hard reference targets now have a much higher chance of being successfully resolved and loaded. For cross-GFP Content references that require assets from plugin B, B must be at least at Loaded.
  4. Active

    • Meaning: The Actions declared in GameFeatureData have actually executed and taken effect in the game world (e.g., adding components, registering abilities/inputs, injecting data, enabling systems, etc.). The gameplay features are live.
    • What you can rely on: In addition to “assets being loadable,” you can also rely on “gameplay logic being registered/enabled.” If a cross-GFP dependency requires not just assets but also B’s systems to provide runtime services (e.g., registries, Subsystems, component injections), B generally needs to be Active.

Three Types of “References”

  1. Hard Asset Reference

    • Example: A Material Instance MI directly specifies a Parent Material located in another GFP; a Blueprint default value directly points to an external asset, etc.
    • Characteristic: Forms a fixed loading dependency chain. If the target asset is unavailable, loading will fail.
  2. Soft Asset Reference

    • Example: TSoftObjectPtr / path reference; Primary Asset Id; a DataAsset that records a path but doesn’t load it immediately.
    • Characteristic: The target asset only needs to be available at resolve/load time; better suited for “load on demand.”
  3. Code / Module Dependency (C++ Module Dependency)

    • Example: B module listed as a dependency in A‘s *.Build.cs or *.uplugin.
    • Characteristic: A compile-time / link-time dependency; generally means “inseparable.”

This post focuses on Content-layer (asset-level) cross-GFP references.

GameFeatureAsset

A GameFeatureAsset (usually a GameFeatureData) is the entry-point asset for a Game Features plugin. It declares the Actions to execute at the Registered / Loaded / Active phases, the components / abilities / data to inject, and optional dependency and unload logic. At runtime it drives the plugin state machine.

  • Every Game Features plugin needs at least one GameFeatureAsset as its entry point (typically placed in the Content/ directory).

GameFeaturesActions

image-20260224154743535

These are the gameplay behaviors that execute when the plugin is activated.

GameFeaturesAssetManager

image-20260224155043010

These are the assets that Unreal will load when the plugin is enabled.

Rules deal with priority. For example, a partial download can be enough to start playing.


Usage

Plugins required to get started: Game Features and Modular Gameplay.


  • Intra-GFP self-reference: GFP A references assets from GFP A/Content.
  • GFP referencing Engine Content (e.g., Engine Content) is acceptable in many projects (depending on team standards).
  • GFP referencing a “shared content plugin / base content pack” (either a non-GFP plugin or a GFP that is an explicit base dependency), as long as it is mounted at game startup.
  • GFP A referencing GFP B’s Content without an explicit guarantee that B is installed / mounted / activated before A.
    • Often looks fine in the editor, but can fail at runtime during on-demand loading.
    • Undermines the pluggability of GFPs (A can no longer be independently enabled/disabled).

Restricted by Game Features Runtime Logic (May Fail Outright)

  • When A activates it needs to resolve/load B’s assets, but B is not mounted (Pak not mounted, plugin not installed).
    • Common symptoms: soft reference load fails, hard reference can’t find the package at load time, or unexpected dependency-load-order issues are triggered.

Note: These “restrictions” are typically not compile-time errors — they are non-deterministic failures caused by runtime loading chains / mount order.


Dependency Relationship Diagram (Mermaid)

Legend:

  • Solid line: Recommended / Allowed
  • Dashed line: Allowed but not recommended (unless you explicitly control load order or declare dependencies)
  • Red: Restricted by runtime logic, may fail (when B is referenced while not yet mounted / activated)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
flowchart LR
subgraph A[GFP A]
AContent[A/Content Assets]
ACode[A/Source Code]
end

subgraph B[GFP B]
BContent[B/Content Assets]
BCode[B/Source Code]
end

subgraph S[Shared / Base]
SharedContent[Shared Content Plugin / Base Pack Content]
end

Engine[Engine Content]

%% Recommended / Allowed
AContent -->|Allowed (recommended)| AContent
AContent -->|Allowed (common)| Engine
AContent -->|Allowed (recommended)| SharedContent

%% Allowed but not recommended
AContent -.->|Allowed but not recommended: cross-GFP asset reference| BContent

%% Runtime restriction (conditional)
AContent -->|Restricted: may fail if B is not mounted / activated| BContent

%% Code dependency (informational, not the focus of this post)
ACode -.->|Not recommended: A module depending on B module creates tight coupling| BCode

Debug

Debug Strategies

  • Use the Reference Viewer to check whether A’s key assets hard-reference anything in B.

    You can click the little eye icon and choose “Show Asset Path” to see the path for each referencing and referenced asset.

  • Verify at runtime:

    • Before A activates, has B already completed Install + Mount + Activate?
    • If B is not activated, can A still run independently?
  • If load order cannot be guaranteed: move the shared assets up into a shared plugin / base pack.

One Game Feature References Another Game Feature’s Content, But No Reference Is Visible in the UI

On the surface, these two unconnected nodes look completely harmless.

image-20260224142949027

image-20260224143018127

image-20260224143259155

But in reality: they were copy-pasted directly from ABP_Main_Youan_DNA_C.

The editor UI doesn’t show any information about where these nodes were copied from. The variable called LiveLinkSubject doesn’t exist in the current Blueprint, so that node’s data never updated. And because the node isn’t wired up to anything, the compiler doesn’t catch it as an error. This silently caused a reference to Game Features YouAn’s content to sneak in.

The moral of the story: don’t leave dead Blueprint nodes lying around.

The most common cross-GFP reference pattern with materials / material instances is:

  • MI_A (in GFP A) uses M_B (in GFP B) as its Parent Material, or references a Material Function / Texture from B.

This creates a hard reference chain, which means:

  • When certain assets in A are loaded, B’s assets must also be available;
  • If B hasn’t been mounted first in the on-demand activation flow, loading A may fail outright.

Recommended approaches (in priority order):

  1. Move the shared material base / material functions / shared textures to a shared content location

    • Example: Plugins/SharedAssets/Content/... (an ordinary content plugin)
    • Or establish a dedicated “explicitly base-dependency GFP” (which then becomes a prerequisite for all dependents).
  2. Keep the cross-GFP reference but explicitly declare / guarantee load order

    • Implement it in your Game Features management logic: install/activate B before activating A.
    • Applicable when: A and B are always bundled together as a unit and can’t be independently toggled.
  3. Switch to soft references + resolve at activation time

    • Prevent A from forming a hard reference chain at edit time; at activation resolve and load via path / Primary Asset.

Resources