ue-game-features
Use this skill when working with Game Feature plugins, modular gameplay, GameFeatureAction, GameFeatureData, GameFrameworkComponentManager, init state system, experience system, modular components, UPawnComponent, UControllerComponent, UGameStateComponent, UPlayerStateComponent, or Lyra-style modula
By quodsoler · 784 installs
npx skills add quodsoler/unreal-engine-skills --skill ue-game-features
Source repository · Upstream listing
UE Game Features and Modular Gameplay
Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".
Game Features (Beta in 5.8) packages gameplay as self contained plugins under Plugins/GameFeatures/ . UGameFeaturesSubsystem (a UEngineSubsystem ) drives each plugin through a state machine; a UGameFeatureData primary data asset inside the plugin holds an instanced list of UGameFeatureAction objects that run at registration, load, activation and deactivation. Modular Gameplay (Beta in 5.8) supplies UGameFrameworkComponentManager (a UGameInstanceSubsystem ) that injects components into opted in actors, plus the UGameFrameworkComponent bases and the init state system that orders initialization across independently loaded features. Build.cs modules: GameFeatures and ModularGameplay . The GameFeatures module already depends publicly on ModularGameplay and DataRegistry , so code that only consumes actions needs GameFeatures alone.
Context
Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing.
Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.
Request is about… Go to
Creating a feature plugin, .uplugin keys, folder layout, UGameFeatureData [Plugin Layout and Descriptor]( plugin layout and descriptor)
Activating or unloading a feature at runtime, plugin URLs, plugin states [Plugin States and the Subsystem]( plugin states and the subsystem)
Writing an action that runs when a feature turns on or off [Writing a UGameFeatureAction]( writing a ugamefeatureaction)
Picking a ready made action instead of writing one [Engine Provided Actions]( engine provided actions)
Adding components to actors from a feature, extension events [Component Injection]( component injection)
Ordering initialization between components that load separately [Init State System]( init state system)
Choosing a base class for a Pawn/Controller/PlayerState/GameState component [Modular Component Bases]( modular component bases)
Filtering which plugins load, client/server data, state observers [Project Policies and Observers]( project policies and observers)
Lyra style experience composition (sample code, not engine API) [references/experience system.md](references/experience system.md)
Full templates: custom action, receiver setup, policies subclass [references/game feature patterns.md](references/game feature patterns.md)
Plugin Layout and Descriptor
A Game Feature plugin is an ordinary plugin that lives under <Project /Plugins/GameFeatures/ or under <AdditionalPluginDirectory /GameFeatures/ . That location is what makes it a Game Feature plugin — UGameFeaturesSubsystemSettings::IsValidGameFeaturePlugin matches the descriptor path against those folders. There is no plugin level "Type" key in the .uplugin schema.
Key Meaning
ExplicitlyLoaded The plugin manager does not mount the plugin at startup; the feature's state machine mounts and unmounts it. Always true for a feature plugin.
CanContainContent Plugin ships a Content/ directory (needed for the UGameFeatureData asset).
BuiltInInitialFeatureState How far a built in plugin advances at startup: "Installed" , "Registered" , "Loaded" or "Active" . Unknown values log an error and fall back to Active .
EnabledByDefault Plugin is enabled without a .uproject entry.
Modules[].Type ModuleHostType name: Runtime , RuntimeNoCommandlet , Editor , Developer , Program , …
Modules[].LoadingPhase ModuleLoadingPhase name: Default , PreDefault , PostConfigInit , PostEngineInit , …
A content only feature plugin omits Modules entirely. Adding a module means adding a Build.cs ; see ue module build system .
UGameFeatureData
UGameFeatureData : UPrimaryDataAsset is the asset the subsystem loads for the plugin. Its two authored properties are protected; read them through accessors:
Actions is an Instanced array of UGameFeatureAction subclasses created inline in the asset. PrimaryAssetTypesToScan tells the Asset Manager which primary asset types inside the plugin to scan when the feature registers; see ue data assets tables .
Subclass UGameFeatureData only to change GetPrimaryAssetTypesToScan or, in the editor, GetDisallowedActions .
Plugin States and the Subsystem
Destination states are fully ordered; transition and error states sit between them. EGameFeaturePluginState is a plain enum generated from the GAME FEATURE PLUGIN STATE LIST macro.
Destination state Meaning
Terminal Final state before the state machine is removed.
UnknownStatus Only the URL is known.
StatusKnown Availability confirmed (on disk or in a bundle).
Uninstalled Local data for the plugin has been removed.
Installed Files are in local storage, not registered.
Registered Assets discovered and registered; actions received OnGameFeatureRegistering .
Loaded Plugin code and content are in memory, not yet affecting the game.
Active Actions applied; the feature affects the game.
Transition states that show up in logs and in GetPluginState results include CheckingStatus , Downloading , Mounting , Registering , Loading , ActivatingDependencies , Activating , Deactivating , Unloading , Unregistering , Unmounting , Releasing , Uninstalling , plus the matching Error states.
Two other enums: EGameFeatureTargetState ( Installed , Registered , Loaded , Active ) is what you pass to ChangeGameFeatureTargetState ; EBuiltInAutoState ( Invalid , Installed , Registered , Loaded , Active ) is what BuiltInInitialFeatureState parses into.
Driving a plugin from code
GetPluginURLByName(FStringView PluginName, FString& OutPluginURL) is the safe way to build a URL for a built in plugin. The static builders UGameFeaturesSubsystem::GetPluginURL FileProtocol(PluginDescriptorPath) and GetPluginURL InstallBundleProtocol(PluginName, BundleName) produce file: and installbundle: URLs ( EGameFeaturePluginProtocol::File , ::InstallBundle ).
Call Effect
LoadGameFeaturePlugin(URL, CompleteDelegate) Advance to Loaded .
LoadAndActivateGameFeaturePlugin(URL, CompleteDelegate) Advance to Active .
RegisterGameFeaturePlugin(URL, CompleteDelegate) Advance to Registered .
ChangeGameFeatureTargetState(URL, EGameFeatureTargetState::Registered, CompleteDelegate) Move to any destination state.
DeactivateGameFeaturePlugin(URL) Back down to Loaded .
UnloadGameFeaturePlugin(URL, / bKeepRegistered= / false) Back down to Registered or Installed .
TerminateGameFeaturePlugin(URL) Tear the state machine down.
CancelGameFeatureStateChange(URL) Abort an in flight transition.
Every completion delegate above is an alias of FGameFeaturePluginChangeStateComplete , i.e. DECLARE DELEGATE OneParam(..., const UE::GameFeatures::FResult&) . Overloads taking TConstArrayView<FString PluginURLs report through FMultipleGameFeaturePluginsLoaded , a TDelegate<void(const TMap<FString, UE::GameFeatures::FResult &) .
Queries: GetPluginState(URL) , IsGameFeaturePluginActive(URL, bCheckForActivating) , IsGameFeaturePluginActiveByName(PluginName, bCheckForActivating) , IsGameFeaturePluginRegistered(URL, bCheckForRegistering) , IsGameFeaturePluginLoaded(URL) , IsGameFeaturePluginInErrorState(URL) , GetActivePluginNames() .
Console commands for testing ( GameFeaturesSubsystem.cpp:583 661 , take a plugin name or URL): ListGameFeaturePlugins [ activeonly] [ csv] , LoadGameFeaturePlugin , DeactivateGameFeaturePlugin , UnloadGameFeaturePlugin , ReleaseGameFeaturePlugin , CancelGameFeaturePlugin , TerminateGameFeaturePlugin . The LoadGameFeaturePlugin console command calls LoadAndActivateGameFeaturePlugin and is ECVF Cheat , unlike the C++ function of the same name, which only reaches Loaded .
Writing a UGameFeatureAction
UGameFeatureAction is UCLASS(MinimalAPI, DefaultToInstanced, EditInlineNew, Abstract) deriving from UObject . DefaultToInstanced and EditInlineNew are what let instances be created inline in the Actions array. The overridable virtuals, verbatim:
Override the context version of OnGameFeatureActivating ; the base implementation of that one calls the no arg version, so overriding both runs your code twice. IsDataValid is a UObject override, not a UGameFeatureAction member, and is editor only.
An action instance is shared by every world the feature applies to, so never keep per world state in a bare member. Filter worlds with the context and key state by FObjectKey :
FGameFeatureActivatingContext and FGameFeatureDeactivatingContext both derive from FGameFeatureStateChangeContext , which supplies ShouldApplyToWorldContext(const FWorldContext&) , ShouldApplyUsingOtherContext(const FGameFeatureStateChangeContext&) and SetRequiredWorldContextHandle(FName) .
Deactivation that needs async work must hold the state machine open. FGameFeatureDeactivatingContext::PauseDeactivationUntilComplete(FString InPauserTag) returns an FSimpleDelegate you must execute on the game thread, on every path:
Full templates, including world tracking and the RAII handle patterns, are in [references/game feature patterns.md](references/game feature patterns.md).
Engine Provided Actions
Action Purpose
UGameFeatureAction AddComponents Adds actor↔component spawn requests to UGameFrameworkComponentManager .
UGameFeatureAction AddCheats Adds cheat manager extensions for each player.
UGameFeatureAction AddActorFactory Registers an actor factory when the plugin registers.
UGameFeatureAction AddChunkOverride Cooks the plugin's assets into a specified chunk id.
UGameFeatureAction AddWPContent Adds World Partition content as a content bundle.
UGameFeatureAction AddWorldPartitionContent Adds World Partition content for the plugin.
UGameFeatureAction DataRegistry Loads and initializes a list of Data Registries.
UGameFeatureAction DataRegistrySource Adds source assets to existing Data Registries.
UGameFeatureAction AudioActionBase Abstract base for actions that affect the audio engine.
UIrisFilterGameFeatureAction Creates an Iris network filter.
UGameFeatureAction AddComponents is the one most features need. It holds TArray<FGameFeatureComponentEntry ComponentList , and each FGameFeatureComponentEntry carries TSoftClassPtr<AActor ActorClass ( meta=(AllowAbstract="True") ), TSoftClassPtr<UActorComponent ComponentClass , the bitfields uint8 bClientComponent:1 and uint8 bServerComponent:1 , and uint8 AdditionFlags ( meta=(Bitmask, BitmaskEnum="/Script/ModularGameplay.EGameFrameworkAddComponentFlags") ).
Set both bClientComponent and bServerComponent for components needed everywhere, server only for authoritative gameplay logic, client only for cosmetics. The action keeps a TSharedPtr<FComponentRequestHandle per game instance and drops them on deactivation, which removes the injected components.
Component Injection
UGameFrameworkComponentManager is a UGameInstanceSubsystem . Get it from an actor:
GetForActor(const AActor Actor, bool bOnlyGameWorlds = true) returns null outside game worlds. GetGameInstance() GetSubsystem<UGameFrameworkComponentManager () also works where a game instance is in hand.
Receivers
An actor receives injected components only after it registers itself:
The static helpers resolve the manager for the actor and forward to AddReceiver(AActor Receiver, bool bAddOnlyInGameWorlds = true) and RemoveReceiver(AActor Receiver) , whic