A Data Registry is an efficient global storage space for USTRUCT
-tagged data structures. Data Registries support synchronous and asynchronous data access, and user-defined caching behaviors. They are intended to work with general read-only data.
Data Registries are part of a plugin. The Data Registries Quickstart can guide you through the process and familiarize you with some of the basic concepts.For specific session-based data such as progress in a story, or a character's current state, use the engine's Save Game system.
You can configure your Data Registry to load or generate data from a variety of different sources, and can populate it with Asset scanning and manual registration. Data Registries are similar to Composite Data Tables, but can store curve data in addition to standard table rows, and use an indirection layer rather than manually compositing multiple tables together.
Data Sources
Data Registries gather data items from two types of sources, Data Registry Sources and Meta Data Registry Sources. These sources are not the actual data items, instead the Data Registry uses them to find or generate data items. The order in which data sources appear within a Data Registry matters, if a specific data item is not found in one source, then the Data Registry will look in the sources that appear after it in the list.
This creates the potential for override and fallback behavior, and enables context-specific sources to override generic ones. The Data Registry plugin includes built-in Data Registry Sources and Meta Data Registry Sources that wrap Data Tables and Curve Tables.
Data Registries gather data items from two types of sources, Data Registry Sources and Meta Data Registry Sources. These sources are not the actual data items, instead the Data Registry uses them to find or generate data items. The order in which data sources appear within a Data Registry matters, if a specific data item is not found in one source, then the Data Registry will look in the sources that appear after it in the list.
This creates the potential for override and fallback behavior, and enables context-specific sources to override generic ones.
The Data Registry plugin includes built-in Data Registry Sources and Meta Data Registry Sources that wrap Data Tables (UDataTable
) and Curve Tables (UCurveTable
).
Data Registry Sources
The Data Registry directly owns a set of Data Registry Source objects that you create and configure in an array within the Data Registry Asset. These objects represent interfaces to specific data sources where the Data Registry can find information, such as an individual data table or a web database. C++ developers can create Data Registry Source child classes to handle other types of data or implement different indirection rules to map identifiers to data items. If your project has one or more Data Registry Source child classes, they will appear in the list when adding new data sources to a Data Registry Asset.
The Data Registry directly owns a set of Data Registry Source objects that you can create and configure in an array within the Data Registry Asset.
These objects represent interfaces to specific data sources where the Data Registry can find information, such as an individual data table or a web database.
You can create child classes of UDataRegistrySource
if you want to handle other types of data, or implement different indirection rules to map identifiers to data items.
Any child class you create will appear in the dropdown list when you add new data sources to a Data Registry Asset.
Meta Data Registry Sources
Meta Data Registry Sources create and own other data sources at runtime. Instead of explicitly list all data sources, Meta Data Registry Sources use generic rules, such as scanning a set of user-named paths, to locate Assets that contain data items. They can listen for manual registration of specific Assets. Meta Data Registry Sources are dynamically generated data sources (including the data items within those sources), because of this they discover load into the Data Registry at runtime.
Similar to Data Registry Sources, C++ developers can create Meta Data Registry child classes to handle other data types, create different scanning rules. If your project contains one or more Meta Data Registry Source child classes, they will appear in the dropdown list when you add new data sources to a Data Registry Asset.
Meta Data Registry Sources create and own other data sources at runtime. Rather than explicitly list all data sources, Meta Data Registry Sources use generic rules, such as scanning a set of user-named paths, to locate Assets that contain data items. They can also listen for manual registration of specific Assets.
Because Meta Data Registry Sources are dynamically generated, data sources (and the data items within those sources) that they discover load into the Data Registry at runtime.
Similar to Data Registry Sources, you can create your own child classes to handle other data types, create different scanning rules, and so on. To do this, override the UMetaDataRegistrySource
class.
Any child classes you create will appear in the dropdown list as options when you add new Data Sources to a Data Registry Asset.
Identifiers
The Data Registry plugin uses its own identifier types to identify or look up Data Registries and the individual data items they contain. While these identifiers are string-based names, the FDataRegistryType
(for Data Registry Assets) and FDataRegistryId
(for individual items within a Data Registry) structures act as wrappers and provide useful in-editor functionality.
FDataRegistryType
identifies a Data Registry Asset, while FDataRegistryId
identifies a Data Registry and a specific data item within it. You can use these identifier types when you need to find Data Registry Assets or retrieve individual data items from them.
Each Data Registry Asset must have a unique name in the Registry Type field. If two Data Registry Assets have the same name in this field, the system will only recognize and populate one of them. Similarly, if multiple data items share the same identifying value (name or Gameplay Tag), the registry will read all items, but retrieval operations will only access the first one that the Data Registry Asset loaded; see the section on data sources for information about the order in which data items load.
Developers using C++ can change this behavior by creating a child Data Registry class and overriding the ResolveDataRegistryId
function.
Data Registry Asset Identifiers
While setting up a Data Registry Asset, developers must set the Registry Type field to a unique name value. This is the identifier for the Data Registry. After setting this value, all Registry Type fields across the editor will immediately add the new Data Registry name to their dropdown list.
This prevents user error resulting from spelling mistakes when referencing the Data Registry in other Assets, and makes the selection process quicker and easier.
While setting up a Data Registry Asset, developers must set the Registry Type field to a unique name value. This is the identifier for the Data Registry.
After setting this value, FDataRegistryType
fields across the editor will immediately add the new Data Registry name to their dropdown list.
This prevents user error resulting from spelling mistakes when referencing the Data Registry in other Assets, and makes the selection process quicker and easier.

Above, setting the Data Registry Asset's identifier. Below, selecting the identifier, or a specific row within that Data Registry, on an Actor that needs to reference the Data Registry Asset.

Data Item Identifiers
Identifying an individual data item, such as a row within a Data Table, requires specifying the Data Registry Asset and the data item itself. The Data Registry ID contains both identifiers. Its Data Registry Type field will appear as a dropdown list, from which you can select any known Data Registry by its identifying name. After selecting a Data Registry's name from that dropdown list, the Data Registry ID field will change to accommodate the Data Registry.
If the Data Registry's ID Format uses a Gameplay Tag, the user interface will display a filtered list containing that Gameplay Tag and all of its children. If the Data Registry's ID Format did not use a Gameplay Tag, the user interface will display a dropdown list of all known rows that the Data Registry Asset contains.
Identifying an individual data item, such as a row within a data table, requires specifying the Data Registry Asset and the data item itself. The FDataRegistryId
type contains both identifiers. Its Data Registry Type field will appear as a dropdown list, from which you can select any known Data Registry by its identifying name.
After selecting a Data Registry's name from that dropdown list, the Data Registry ID field will change to accommodate the Data Registry.
If the Data Registry's ID Format uses a Gameplay Tag, the user interface will display a filtered list containing that Gameplay Tag and all of its children. If the Data Registry's ID Format did not use a Gameplay Tag, the user interface will display a dropdown list of all known rows that the Data Registry Asset contains.
If you edit a Data Registry Asset, your changes may not take effect immediately in other Assets that reference it using data item identifiers. If this happens, the data item identifiers could contain obsolete rows in its dropdown lists. Click the Compile button in the Asset that references the Data Registry (not the Data Registry Asset itself) to update the interface with current data item information.

On the left, item selection for a Data Registry Asset with an ID Format that uses a Gameplay Tag. On the right, item selection for a Data Registry Asset that uses a simple name.
Because FDataRegistryId
has an FDataRegistryType
member (called RegistryType
), you can find the Data Registry Asset that contains the row without needing a separate FDataRegistryType
identifier.
Identifier Resolution
The system looks up data items by searching for the Item Name of the Data Registry ID you supply. You can alter this behavior by creating a child Data Registry class in C++. Toggle to the C++ version of this page for more details.
Dynamic Identifier Resolution
By default, the system looks up data items by searching for the value of the ItemName
field of the FDataRegistryId
you supply. If this is not the ideal behavior for your project, you can create your own UDataRegistry
subclass and override the MapIdToResolvedName
function to include additional FDataRegistryResolverScope
structs in the local scope. By overriding the ResolveIdToName
function within your FDataRegistryResolverScope
subclasses, you can remap the incoming row names, even using dynamic or player-specific information. After resolving an ID, the system produces an FDataRegistryLookup
which is guaranteed to be unique (within the system) and is used as the caching unique ID.
Quick Function Reference
The following functions are helpful for getting started with Data Registries. This is not a complete reference, but these functions are the basics you will need to access your data after having set up Data Registries in your project.
- Acquire Data Registry Item searches for a given item and loads it into the cache on success. This function is very important for data items coming from MetaDataRegistrySources, as the other Data Registry functions can only access cached data items. Call this function if you want to access a data item that you believe exists (or might exist) but is not currently in the cache.
When you call this function, it will resume execution immediately through the pin on the right side. The return value indicates whether or not the loading operation has started, not the result of that operation; failure means that the operation could not begin, and the callback function you have connected will not be called. Once the callback function runs, the search and load operations have finished, and you can use the other functions described in this section to attempt to retrieve your data from the cache, presuming it loaded successfully. If your data is not in the cache immediately at that point, it was not found.
If you successfully retrieve a data item once, but fail to retrieve it later on, it may have been removed from the cache. Call Acquire Data Registry Item again and retrieve it immediately upon entering the callback function. You may also consider making your own copy of the data, or adjusting the data item's cache behavior, based on the specific needs of your project.

- Find Data Registry Item checks for an item in the Data Registry's cache, and branches based on whether or not the item was found. If it was found, you can access it through the right-side Out Item pin. This function returns immediately, so data items that exist but are not in the cache will not be found.

- Get Data Registry Item is similar to Find Data Registry Item, but returns a success/failure value instead of branching, and automatically populates the variable connected to the left-side Out Item pin on success. This function returns immediately, so data items that exist but are not in the cache will not be found.

- Evaluate Data Registry Curve looks for a cached curve. Like Find Data Registry Item, it is synchronous, so it will return immediately, but will fail to find a curve if that curve is not in the cache at the time of the function call. This function branches execution based on whether it succeeds or fails, and returns the default value that you provide on failure. You can use this feature in cases where you need an output value regardless of whether or not the curve data is available.

Function | Description |
---|---|
UDataRegistrySubsystem::Get |
Returns a pointer to the UDataRegistrySubsystem instance. The only static function in the list, this function acts as the entry point to the subsystem. |
UDataRegistrySubsystem::GetRegistryForType |
Takes a name or FDataRegistryType (either standalone or from FDataRegistryId::RegistryType ) and returns a UDataRegistry pointer to the matching Data Registry, if it exists. |
UDataRegistrySubsystem::RegisterSpecificAsset |
Searches for a Data Registry by FDataRegistryType , and adds a specific Asset to it. If you do not provide a valid FDataRegistryType , the subsystem will attempt to add the Asset to all Data Registries in the subsystem. Returns true if at least one Data Registry accepted the Asset. |
UDataRegistry::GetCachedItem |
Searches the Data Registry for the data item that corresponds to the FDataRegistryId you provide. If the item is not in the cache at the time of the function call, the function will return null. Otherwise, the function returns a const pointer to whichever struct type the Data Registry stores. |
UDataRegistry::GetAllCachedItems |
Populates a map with a pointer to the engine's UScriptStruct data (as a const uint8* ) for each cached item in the Data Registry, using the item's FDataRegistryId as the key. Also provides the UScriptStruct itself through a separate output parameter. This is often useful for iterating over the cache as a debugging tool, such as using the UScriptStruct::ExportText function to log the contents of each cached item. |
UDataRegistry::EvaluateCachedCurve |
Finds the curve that corresponds to the FDataRegistryId you provide, and evaluates it for a given input value. This function will fail if the requested curve is not in the cache at the time of the call. The function's return value is of type FDataRegistryCacheGetResult , which provides information about the cached status of the curve you requested, and most importantly whether or not the curve was found. The curve's output value, of type float , comes through an output parameter. |
UDataRegistry::AcquireItem |
Similar to GetCachedItem , but finds the data item even if it is not cached at the time of the call. This function is asynchronous; it will run your callback function, of type FDataRegistryItemAcquiredCallback , when the search is complete. The function's return value is a bool that indicates success at scheduling the callback; a false return value means that there has been an error and your callback function will not run. A return value of true means that your callback function will run, but does not guarantee that the data item exists. |
Caching struct pointers that you retrieve from a Data Registry can be unsafe. While some data items are always available, others load dynamically and the Data Registry can unload them without warning. If you are potentially dealing with data that can be unloaded, the recommended practice is to use the data immediately after retrieving it, or cache your own copy rather than keeping the pointer from the Data Registry.
Integration with Game Features
The Data Registry plugin can add both Data Registries and individual Data Registry Sources from Game Feature plugins. For details on how this process works, see the Game Features and Modular Gameplay page.