Blueprint Subsystems

Author: Tomasz Klin
Version: 1.0.0

Introduction

Blueprint Subsystems lets you create shared systems entirely in Blueprint. Use one to keep quest progress between level changes, manage events in a world or store data for each local player.

A subsystem holds data and logic. Unreal Engine creates and removes it when needed. Other Blueprints access it through a Get Subsystem node. You do not need to place a manager actor in a map.

The plugin supports Engine, Editor, Game Instance, World, Tickable World and Local Player subsystems. It finds your subsystem Blueprints and includes them when packaging the game. Editor subsystems are available only in the editor.

Getting started

  1. Enable Blueprint Subsystems in Edit > Plugins. Restart the editor if prompted.
  2. In the Content Browser, choose Add > Blueprints > Blueprint Subsystem.
  3. Choose a subsystem type from the table below and name the new asset.
  4. Open the Blueprint and add your setup logic to Initialize.
  5. Compile and save the Blueprint.
  6. In another compatible graph, search for Get followed by your Blueprint's class name.

With automatic discovery enabled, the plugin finds saved subsystem Blueprints and registers them with the engine. Restart the editor after changing discovery settings that require a restart.

Choosing a scope

A subsystem's scope decides how many instances exist and how long each one lasts. Choose the scope that matches the data and logic you want to keep.

ScopeInstancesLifetime and common uses
EngineOne per running engine processShared services that continue across worlds and Play In Editor sessions.
EditorOne per editor sessionEditor tools and project checks. Available only in the editor.
Game InstanceOne per game instanceData for a game session, including across level changes. Useful for quest progress or matchmaking.
WorldOne per supported worldData and logic for that world, such as a level event manager.
Tickable WorldOne per supported worldA World subsystem with a Blueprint Tick event.
Local PlayerOne per local playerSeparate data for each local player, such as input or HUD state. Continues across level changes.

Engine

Choose Blueprint Engine Subsystem for a system that needs to continue when worlds or game instances change. It has no world of its own. Use a World subsystem for actors and other objects that belong to one level.

Editor

Choose Blueprint Editor Subsystem for editor tools and project checks. It does not exist in a packaged game, so use it only from editor code and editor Blueprints.

Game Instance

Choose Blueprint Game Instance Subsystem for data that lasts for one game session. It remains available between level changes and can access its owning Game Instance.

Each Play In Editor run gets a new instance, so data from one run does not carry into the next.

World and Tickable World

Choose Blueprint World Subsystem for a system that belongs to one world. The engine creates an instance for each supported world and removes it when that world ends.

Blueprint Tickable World Subsystem also provides a Tick event. Its settings control whether it updates in editor worlds and while the game is paused.

Use Supported World Types in the Blueprint defaults to choose where it runs. For a gameplay system, you will usually exclude Editor and Preview worlds.

Use the regular World type if the system only responds to events and does not need Tick.

Local Player

Choose Blueprint Local Player Subsystem for separate data and logic for each local player. A split-screen game has one instance per local player. A dedicated server has none.

The instance remains available when the player's controller changes or the player changes levels.

Lifecycle

Lifecycle events tell your subsystem when to start and stop its work:

Scope-specific events

Some events are available only for certain subsystem types:

During a level change, Player Controller Changed may first receive no controller and later receive the new controller. Check that the controller is valid before using it.

Initialize dependencies

Use Initialize Dependency inside Initialize if your subsystem needs another subsystem to be ready first. Both must have the same scope. The other subsystem initializes before your Initialize continues.

The order in which classes are found does not guarantee their initialization order. If you only need the other subsystem later, get it when you need it.

Discovery and packaging

Automatic discovery finds subsystem Blueprint classes and registers them with Unreal Engine. It also includes their assets when packaging the game, even when no other asset references them.

Open Project Settings > Plugins > Blueprint Subsystems:

Restart the editor after changing options marked as requiring a restart.

Runtime registration

You can also control registration while the game runs. Use these nodes under Blueprint Subsystems for downloadable content, systems used by a specific game mode, or projects with automatic discovery disabled.

If you unregister a subsystem, make sure any Blueprint that uses it can handle the instance being unavailable.

Recompiling a subsystem

Engine and Editor subsystems can remain active for the entire editor session. Enable Reinitialize On Blueprint Compile to apply their updated graphs after a compile.

The plugin runs Deinitialize on the affected instances and creates new ones, which run Initialize. Data held only in the old instances is lost.

This refresh is skipped during Play In Editor. Disable the option if you need to keep data in the current editor instances while editing.

Recipes

These examples show which subsystem to choose and where to put your logic.

Keep session state across level changes

Create a Blueprint Game Instance Subsystem and store your session data in it. Set it up in Initialize and read it from each world through its Get node.

A World subsystem is recreated when its world changes, so use Game Instance for data that must continue between levels.

Build a level service without a manager actor

  1. Create a Blueprint World Subsystem.
  2. Exclude Editor and Preview from Supported World Types if it is only for gameplay.
  3. Use World Begin Play to find or spawn the level objects it needs.
  4. Use Deinitialize to unbind events and clear references when the world ends.

Hold per-player state in split screen

Create a Blueprint Local Player Subsystem. Each local player gets a separate instance.

Use Player Controller Changed to update controller references. A level change may replace the controller.

Run editor validation for the whole session

Create a Blueprint Editor Subsystem. Bind to editor events in Initialize and unbind them in Deinitialize. Keep references to this class in editor tools, outside runtime gameplay graphs.

Troubleshooting

My subsystem works in the editor but is missing from a build

Check that automatic discovery can find the Blueprint or add it to Additional Subsystem Classes. If Search Paths contains folders, the asset must be in one of them unless listed separately.

Build with the source plugin. Copying only binaries generated by the editor is not enough for other build targets.

Get Subsystem returns no instance

Check that the Get node uses the correct scope and owner. Then check Should Create Subsystem and Supported World Types.

A Local Player subsystem needs a local player; dedicated servers have none. An Editor subsystem is available only in the editor.

Initialize runs before another subsystem is ready

Call Initialize Dependency from Initialize when both subsystems have the same scope.

For a World subsystem that can wait until all world subsystems are ready, put the work in Post Initialize.

Recompiling erased state

Reinitialize On Blueprint Compile replaces the old instance with a new one. Disable the option to keep the current instance, or store data that must survive elsewhere.

A tickable subsystem does not tick

Check Tick Enabled, Is Tick Enabled, Supported World Types and Tick In Editor. To update while the game is paused, also enable Tick When Paused.

Support

For help or bug reports, contact tomasz.klin@gmail.com.

Include your Unreal Engine version, plugin version, subsystem scope and world type. This manual covers plugin version 1.0.0.