IN THIS ARTICLE
Settings Registry Developer Guide
The Settings Registry is a central repository of global settings for all Open 3D Engine (O3DE) applications. Settings can be defined, queried, and changed using
JSON Pointer syntax . The settings registry can read any valid JSON files that have the .setreg extension.
The Settings Registry combines multiple JSON values into one document by merging values using either the
JSON Patch format or the
JSON Merge Patch format. This allows overriding values within the Settings Registry by loading either a .setreg file which is merged using the JSON Merge Patch strategy, or a .setregpatch file which is merged using the JSON Patch strategy.
The Settings Registry can be thought of as a wrapper around a JSON DOM that can query and set values in that DOM using JSON Pointers. Values can also be queried by visiting a path in the JSON document that can be used to construct objects from the JSON DOM without the need for reflection.
JSON Patch and JSON Merge Patch
There are two formats for modifying the Settings Registry, JSON Patch and JSON Merge Patch .
JSON Patch is a format that describes a set of operations to perform to a JSON value at a particular JSON path.
JSON Merge Patch is a format that allows the specification of a JSON document that is used primarily for modifying JSON objects by merging objects using a simple algorithm. Unlike JSON Patch, it does not specify a set of operations encoded in a JSON document. It acts as a patch of changes to apply to a JSON value at a particular path. JSON Merge Patch does not explicitly allow setting a key value to “null’, nor does it allow removing or adding values to a JSON array. The entire array must be replaced.
.setreg example
A .setreg file uses the JSON Merge Patch algorithm when merged into the Settings Registry. The format is JSON.
~/.o3de/Registry/sample.setreg
{
"Amazon": {
"AzCore": {
"Bootstrap": {
"project_path": "D:/o3de/AtomSampleViewer"
}
}
}
}
.setregpatch example
The .setregpatch file uses the JSON Patch algorithm when merged into the Settings Registry. The format is JSON, where elements of the JSON array describe a set of patch operations to a JSON document.
~/.o3de/Registry/sample.setregpatch
[
{ "op": "replace", "path": "/Amazon/AzCore/Bootstrap/project_path", "value": "D:/o3de/AtomSampleViewer" },
{ "op": "add", "path": "/Amazon/AzCore/Bootstrap/engine_path", "value": "D:/o3de/o3de" },
{ "op": "add", "path": "/Amazon/AzCore/Bootstrap/bin_directories/-", "value": "D:/o3de/AtomSampleViewer/AppendToEndOfJsonArray" },
{ "op": "copy", "from": "/Amazon/AzCore/Bootstrap/bin_directories/0", "path": "Amazon/AzCore/Bootstrap/default_bin_directory" },
{ "op": "move", "from": "/Amazon/AzCore/Bootstrap/windows_assets", "path": "/Amazon/AzCore/Bootstrap/assets" },
{ "op": "remove", "path": "/Amazon/AzCore/Bootstrap/bin_directories/1" }
]
Get started with the Settings Registry
Every O3DE application uses the AZ::ComponentApplication class that creates a global Settings Registry for the application. The easiest way to use the Settings Registry is through its Get and Set API (AZ::SettingsRegistry::Get and AZ::SettingsRegistry::Set). The Get and Set functions support query and modification of bool, integer, double, and string types.
Use the Get function
auto settingsRegistry = AZ::SettingsRegistry::Get();
AZ::SettingsRegistryInterface::FixedValueString projectName;
if (settingsRegistry && settingsRegistry->Get(projectName, "/Amazon/AzCore/Bootstrap/project_path"))
{
// Do stuff with current Project Path
}
Use the Set function
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry && settingsRegistry->Set("/Amazon/AzCore/Bootstrap/project_path", "AutomatedTesting"))
{
// Successfully set the Project Path, do other stuff
}
Create a Settings Registry
Creating an AZ::ComponentApplication, or a class derived from it creates a global Settings Registry. When an instance of the AZ::ComponentApplication is created, an AZ::SettingsRegistryImpl instance is registered with an AZ::Interface. It is accessible by the name AZ::SettingsRegistry. For clarity, the default construction of an AZ::ComponentApplication is all that is required to create a global Settings Registry. The AZ::ComponentApplication::Create() function does not need to be called to register a singleton AZ::SettingsRegistryInterface.
To create an empty Settings Registry that can be used locally by a Gem or a library, create an instance of the AZ::SettingsRegistryImpl class.
Populate a Settings Registry
Settings are merged into the Settings registry in the following order:
- First, the global user
~/.o3de/Registrydirectory is scanned and its contents are merged into the Settings Registry. The global userRegistrydirectory is also merged a second time after all the Settings Registry paths are merged (Engine, Gems, and Project) to ensure the user settings override all other settings except for command line settings. - Next, any
--regset/--regremoveoptions specified on the command line are read and merged into the Settings Registry. - The
ComponentApplicationthen requests that the Settings Registry populates runtime file paths based on the bootstrap settings. The runtime file paths are all located under the JSON path of “/O3DE/Runtime/FilePaths”.
The following utility functions help with retrieving important paths and the project name:
AZ::Utils::GetEnginePath()- Queries the absolute path to the engine root.AZ::Utils::GetProjectPath()- Queries the absolute path to the project root.AZ::Utils::GetProjectName()- Queries the name of the project as specified in the<ProjectRoot>/project.jsonfile.AZ::Utils::GetExecutableDirectory()- Queries the absolute path to the directory containing the executable.AZ::Utils::GetO3deManifestDirectory()- Queries the absolute path .o3de directory inside the user home:~/.o3de.AZ::Utils::GetGemPath(gemName)- Queries the absolute path .to the gem whose gem.json “gem_name” entry matches.
Search locations
The ComponentApplication global Settings Registry attempts to load Settings Registry files in the following order:
- First, the
~/.o3de/Registrydirectory is scanned for global user settings. It is located in the user’s home directory. By default, this isC:\Users\<user>\.o3de\Registryon Windows,/home/<user>/.o3de/Registryon Linux, and/Users/<user>/.o3de/Registryon Mac. - Command line options are merged. The command line allows setting a value within the Settings Registry through the following methods:
- The
--regsetswitch by specifying the value as<path>=<value>. - The
--regset-fileswitch allows merging of either a.setregfile (--regset-file=<file>) orstdin(--regset-file=-) into the Settings Registry. - The
--regremoveswitch allows removal of a key in the registry.Note:The registry can be dumped tostdoutusing a JSON pointer path supplied with the--regdumpswitch. The entire Settings Registry can be dumped tostdoutusing the--regdumpallswitch.
- The
- The
<EngineRoot>/Registrydirectory is searched for settings. - Each Gem’s
<GemRoot>/Registrydirectory is searched for settings. - The registry directory,
<ProjectRoot>/Registry, within the project path, is searched for settings. - The global user setting registry located at
~/.o3de/Registryis merged again to ensure the global user settings override any engine, Gem, or project settings. - The project-specific user directory,
<ProjectRoot>/user/Registry, is merged. This directory should not be in source control as it is meant to be user-specific. - Finally, the command line is merged again by checking for
--regset,--regset-file, and--regremoveoptions to override any other settings.
Launcher search locations
The project’s GameLauncher and ServerLauncher applications have an additional search location within the project’s root cache directory, <ProjectRoot>/Cache/<platform>, for an aggregated bootstrap.*.setreg file that Asset Processor generates.
Settings Registry builder
Asset Processor contains a builder for aggregating all the settings stored in files and the command line into a bootstrap.game.<config>.setreg file. The settings are loaded in the following order and merged into a single local Settings Registry which is then serialized out to the bootstrap.game.\*.setreg files.
<engine-root>/Registry<gem-root>/Registryfor each Gem loaded within the Asset Processor<project-root>/Registry- (Non-Release Only)
<user-home>/.o3de/Registry - (Non-Release Only)
<project-root>/user/Registry - (Non-Release Only)
--regset/--regremovecommand line parameters supplied to Asset Processor
For example, on Android, the following files are output to the project’s asset cache Android directory:
bootstrap.game.debug.setregbootstrap.game.profile.setregbootstrap.game.release.setreg
When applications load in non-monolithic mode, the <ExeDirectory>/Registry is searched for a cmake_dependencies.*.setreg that contains the list of Gems to load. For non-host platforms such as Android or iOS, where the files are deployed according to a specific layout, the <ProjectCachePlatformRoot>/Registry is also searched. This is explained in more detail below in the
Loading Gems.
Note:If the GameLauncher or ServerLauncher application is launched before the Asset Processor Settings Registry Builder updates thebootstrap.game.<config>.setregfile, then up-to-date settings might not be available until the next run of the Launcher application.
Gems outside of <EngineRoot>/Gems
The list of Gem root directory paths is populated by CMake when it generates the build files for a platform. Because CMake knows the CMakeLists.txt location for each Gem, it can generate a .setreg file with a list of Gems for each CMake target that sets a “Gem Variant” to load. This done by using the ly_set_gem_variant_to_load command. This list includes the filename of the Gem and the relative path to the Gem directory based on the source directory supplied to CMake during configuration.
The benefit is that if a Gem is added outside of the <EngineRoot> location using the
cmake add_subdirectory command, then the Settings Registry can load any .setreg files within the <GemRoot>/Registry directory.
This can be used to include a specific Gem outside of the O3DE <EngineRoot> directory, as in the following example:
add_subdirectory(<AbsolutePathToMoleculeGem> <AbsolutePathToMoleculeGem>) # This doesn't have to be in the O3DE engine root
add_subdirectory(../<RelativePathToElectronGem> ../<RelativePathToElectronGem>)
Settings Registry key hierarchy
Because the Settings Registry is built from one or more JSON documents, it’s possible that a path to a JSON value from two separate .setreg files has keys rooted at the same path. Therefore, it’s always recommended to prefix any keys within the Settings Registry, particularly keys under “/O3DE” if it is an engine-specific setting. Additionally, appending the project, Gem, or library name to the key is also recommended to reduce the chances of collisions between keys (for example, “/O3DE/AzCore/Key1”, “/O3DE/Gems/EMotionFX/Key1”).
Instead of a settings hierarchy like the following example:
{
"useExistingAllocator": false,
"grabAllMemory": false
}
A better approach is to root the settings at a hierarchy such as “/O3DE/AzCore”, as in the following example:
{
"O3DE": {
"AzCore": {
"useExistingAllocator": false,
"grabAllMemory": false
}
}
}
This approach can help avoid collisions with JSON keys from other libraries or organizations.
Settings Registry API
Several APIs are provided for the Settings Registry to query, modify, and merge settings keys and values. Those APIs are detailed in the Settings Registry Developer API.
| Topic | Description |
|---|---|
| Settings Registry Developer API | Learn how interact with the Settings Registry using the C++ API. |
Setting Registry specializations
Specializations are set of tags that filter which .setreg and .setregpatch files will merge from a particular directory. The tags are part of a filename that *.setreg files can contain. Not all tags within the tag set are required to be matched as part of the filename, but any parts of the filename which do not match a tag in the specializations object will result in a failed match. The following is an example specification of a .setreg file:
<filename stem>.<tag1>.<tag2>...<tagN>.setreg
A Settings Registry file with the name of bootstrap.game.windows.profile.setreg, has the filename bootstrap, and the tags game, windows, and profile. To merge the file using the AZ::SettingsRegistry::MergeSettingsFolder function, a specializations object with game, windows, and profile tags is required. The specializations object can have additional tags other than those listed. As long as it contains the game, windows, and profile tags, the bootstrap.game.windows.profile.setreg file will be merged.
The specializations object can be thought of as an allowlist of .<tag> values that can be part of the Settings Registry file name.
The following example merges a .setreg file from the <ExecutableDirectory>/Registry directory by using specialization tags:
SettingsRegistryInterface::Specializations specializations{
"automatedtesting",
"automatedtesting_gamelauncher",
"randomtag"
};
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
registry->MergeSettingsFolder(AZ::Utils::GetExecutableDirectory() / "Registry", specializations, AZ_TRAIT_OS_PLATFORM_CODENAME);
The following table details which types of files will be merged using the preceding example specializations:
Files in <ExeDirectory>/Registry | Merged by MergeSettingsFolder |
|---|---|
cmake_dependencies.automatedtesting.automatedtesting_gamelauncher.setreg | Yes - contains both the automatedtesting and automatedtesting_gamelauncher tags |
cmake_dependencies.automatedtesting.setreg | Yes - contains the automatedtesting tag |
cmake_dependencies.automatedtesting_gamelauncher.setreg | Yes - contains the automatedtesting_gamelauncher tag |
cmake_dependencies.automatedtesting.automatedtesting_gamelauncher.setregpatch | Yes - contains both the automatedtesting and automatedtesting_gamelauncher tags, and .setregpatch files can also be merged |
cmake_dependencies.automatedtesting.automatedtesting_gamelauncher | No - missing a .setreg or .setregpatch extension |
automatedtesting.cmake_dependencies.setreg | No - cmake_dependencies is not part of the tag set |
cmake_dependencies.setreg | Yes - contains no specialization tags |
automatedtesting.setreg | Yes - “automatedtesting” is the stem of the filename, not a tag. |
Merge settings files
An alternative to using the specialization system is to merge each file with the AZ::SettingsRegistryInterface::MergeSettingsFile function as follows:
. Use AZ::IO::SystemFile::FindFiles to search for .setreg and .setregpatch files. To gather the files for the specific platform, make a second call to AZ::IO::SystemFile::FindFiles by appending the directory of "Platform" / AZ_TRAIT_OS_PLATFORM_CODENAME to the directory being searched, for example, <ExeDirectory>/Registry/Platform/Windows.
- Pass each file to
AZ::SettingsRegistryInterface::MergeSettingsFile.
Merge Platform Abstraction Layer (PAL) directories
AZ::SettingsRegistry::MergeSettingsFolder allows users to supply an optional platform name to indicate an OS platform directory to search for .setreg and .setregpatch files. This allows the merging of platform-specific settings by supplying the platform parameter. This parameter should be set to an empty string if platform-specific settings are not required. To merge platform-specific settings for the current OS, use the
AZ_TRAIT_OS_PLATFORM_CODENAME define, which expands to the current platform.
Adding specializations from the command line
The Settings Registry supports storing specific specializations to use within the registry itself. The /Amazon/AzCore/Settings/Specialization/<TagName> key can be set to true to add the --regset command line option.
The following example launches O3DE Editor with a custom specialization:
Editor.exe --project-path=<Path-To-Project> --regset="/Amazon/AzCore/Settings/Specialization/custom=true"
Note:Specializations in the Settings Registry are case-insensitive.
Specialization system in depth
The specialization tagging system can be used to filter .setreg and .setregpatch files by specialization tags. The Settings Registry MergeSettingsFolder function accepts a specializations parameter which is checked against all tags found within a filename located in the merged directory. If a filename contains a tag that is not supplied as part of the specialization parameter, it will be removed from the list of Settings Registry files to merge.
Consider the following example of merging hardware settings:
For example, given the set of specializations tags mobile and core_count_16, and a directory with the following Settings Registry files:
hardware_settings.core_count_16.mobile.setreghardware_settings.mobile.setreghardware_settings.pc.setreghardware_settings.core_count_16.pc.setreghardware_settings.core_count_4.mobile.setreghardware_settings.core_count_16.setregPlatform/Android/hardware_settings.mobile.setrega_hardware_settings.core_count_16.mobile.setreg
The specialization tags are checked against each of the specializations that are part of the file name in the
SettingsRegistryImpl::ExtractFileDescription function. The part of the filename that is a specialization in a *.setreg or *.setregpatch file is the section after the first period and before the file extension.
As an example, <filename stem>.<tag1>.<tag2>.<tag3>.setreg is a Settings Registry file with three tags.
Each tag of a .setreg file must match a tag supplied to the specialization structure that gets passed into to the
SettingsRegistryInterface::MergeSettingsFolder function.
In this case, the hardware settings are merged from the following files because the specializations parameter contains core_count_16 and mobile.
hardware_settings.core_count_16.mobile.setreghardware_settings.mobile.setreghardware_settings.core_count_16.setregPlatform/Android/hardware_settings.mobile.setrega_hardware_settings.core_count_16.mobile.setreg
Merge order
The SettingsRegistryImpl::IsLessThan function is used to sort the list of Settings Registry files based on the following rules:
- The
<filename stem>.<tag1>.<tag2>...<tagN>.setregfiles are sorted based on the lexicographical order of the<filename>portion of the file. - Next, files with the same
<filename>are sorted by number of tags in ascending order. - Next, for files with the same
<filename>and the same number of tags, the files are sorted according to the order of the tags in the specialization structure. In the preceding example, since thecore_count_16tag is added beforemobile, thecore_count_16tag sorts before themobiletag. - Finally, for files with the same
<filename>, number and order of tags, if one of the files is located within the platform abstraction layer directory, for example,Registry/Platform/Android/hardware_settings.mobile.setreg, the platform-specific file is sorted after the non-platform-specific file.
The following table explains the order that the example files are merged:
| Settings Registry file load order | Reason |
|---|---|
a_hardware_settings.core_count_16.mobile.setreg | The filename a_hardware_settings sorts before hardware_settings. |
hardware_settings.core_count_16.setreg | The filename hardware_settings matches and contains the same number of tags as the next entry, but this entry tag of core_count_16 was added before mobile. |
hardware_settings.mobile.setreg | The mobile tag was added to the specialization array after the core_count_16 tag. |
Platform/Android/hardware_settings.mobile.setreg | The Android platform-specific version of hardware_settings.mobile.setreg loads after the non-platform version. |
hardware_settings.core_count_16.mobile.setreg | The filename hardware_settings matches the previous four entries, but this entry contains two specialization tags instead of one as in the previous entries. |
Command line support
There are several command line options you can use to query, create, modify, and merge .setreg files to the Settings Registry.
The command line options are detailed in
Command Line Arguments.
| Topic | Description |
|---|---|
| Command Line Arguments | Learn how to modify the Settings Registry through the command line. |
Convert .ini files to JSON
To help convert Windows-style .ini settings for use in the Settings Registry, SerializeContextTools exposes a convert-ini option that can accept one or more .ini style files and convert them to .setreg files that can then be loaded in the Settings Registry. The following example demonstrates the conversion of the AssetProcessorPlatformConfig.ini and user.cfg to a .setreg file.
convert-ini
<CMakeBinaryDir>/bin/profile/SerializeContextTools.exe convert-ini --files AssetProcessorPlatformConfig.ini;user.cfg --ext setreg --json-prefix="/O3DE/Settings"
MSVC debugging
The Settings Registry maintains its settings in a rapidjson::Document that is a member variable in AZ::SettingsRegistryImpl.
The rapidjson 3rdParty library provides a Native Visualizer (.natvis) file for the MSVC debugger, making it easy to recurse through rapidjson::Value and rapidjson::Document instances. This .natvis file is part of AzCore and can be visualized in Visual Studio. Expanding AZ::SettingsRegistryImpl::m_settings provides a view of the values within the Settings Registry. This allows for drilling down to a particular JSON entry within the Settings Registry to determine if an entry and its value exist.