Config files in the Project Settings
The Project Settings save every change to Config/Default<Type>.ini (DefaultEngine.ini, DefaultGame.ini, …). Many projects need some values only on one platform or only for one target, for example the online credentials of a dedicated server. Unreal reads more files for that; later files override earlier ones:
| File | Read by |
|---|---|
Config/Default<Type>.ini | every target on every platform |
Config/Custom/<Custom>/Default<Type>.ini | targets with CustomConfig = "<Custom>" in their Target.cs |
Config/<Platform>/<Platform><Type>.ini | every target on that platform |
Config/<Platform>/Custom/<Custom>/<Platform><Type>.ini | targets with that custom config on that platform |
The editor reads the files of its own platform and of the custom config of the editor target. Pulse Foundation adds two things to the Project Settings, so these files can be edited there instead of by hand.
Save changes to
Every page of the Project Settings that saves to Default<Type>.ini gets the category Config Files with the bar Save changes to; the page of a Pulse plugin has it once at the top, one bar per config type of its blocks (One page per plugin). Its list has two parts:
- Files this editor reads: Default, the custom config, the platform, and the platform with the custom config.
- Other platforms and custom configs: the files of the page’s config type that exist for other platforms and custom configs, for example
Config/Custom/EOSServer/DefaultEngine.iniof a dedicated server.
Until the editor closes, changes on the pages of that config type go to the picked file instead of Default<Type>.ini; a new editor session starts with Default again.
Only the changed setting is written, never the whole section, so a file does not get copies of values that come from other files. Arrays are written as a whole (!Key=ClearArray and one +Key= line per element), so the file decides the full list. The file is checked out in source control, or added when it is new.
If a file the editor reads later sets the same value, the change does not show in this editor; a notification names that file.
With a file the editor does not read, the changed value is saved there, and the setting then gets the value back that the editor takes from its own files: the page always shows what this editor uses. A notification names the file; the layers button of the setting shows the value in every file.
Undo and redo write the value after the undo into the picked file, like the engine writes it into Default<Type>.ini. With a file the editor does not read, undo changes only the editor; the file keeps what was saved in it.
A few engine settings save settings that depend on them into Default<Type>.ini themselves, for example the renderer settings when ray tracing is switched; the bar does not redirect those.
The ini fixes of the Pulse setup steps (Steps::MakeIniStep, Steps::MakeNetDriverStep) write to the picked file when the editor reads it, else to Default<Type>.ini: the step checks the value the editor loads.
Values per file
Every setting of such a page gets a layers button at the end of its row. Its tooltip names the file the editor takes the value from and the files of other platforms and custom configs that set it; the icon is blue when a file other than Default<Type>.ini sets it. A click opens a window with the value in every file:
- Files this editor reads, in reading order; the one the editor uses is marked (used).
- Other platforms and custom configs that set the value, plus files added with Add a file, for example the custom config of a dedicated server target, which the editor never reads.
Per file: type a single value and press Enter (the value is checked before it is written), Set to Current writes the value the editor shows, Remove deletes the setting from the file, so the files before it decide again. Lists and structs show as text and are written with Set to Current. Values of credentials (property names with Secret, Password, Token, ClientId, …) only show as (set) and cannot be typed in.
After a change to a file the editor reads, the setting shows the value the editor now takes from its files. When no file of the editor sets it any more, Unreal does not load the key again: the editor keeps the value it shows until it restarts, then the engine or plugin default applies. Changes to files of other platforms or custom configs do not change this editor.
New files and custom configs
New Config File next to the bar (also at the end of its list, and as New Config File… in Add a file of the values window) creates a config file of the page’s config type:
- Platform: All platforms or one platform, for example
Linux. - Custom config: None, a custom config of the project, or New Custom Config… with a name of its own, for example
SteamorDemo(letters, digits and underscores). - File shows the path, for example
Config/Linux/Custom/Steam/LinuxGame.ini, and whether it exists. - Read by names the targets of the project that read the file. A target reads the files of a custom config once its
Target.cssaysCustomConfig = "Steam";; until then the dialog says that no target uses it yet. - Create makes the file (empty, folders included) and adds it in source control; a file that exists stays as it is. With **Save changes of
settings to this file** (on when the dialog comes from the bar) the bar points to it right away.
The console does the same: Pulse.ConfigFiles.Create Game Linux/Custom/Steam.
Files of the editor are also created with the first value written to them: the bar lists the platform files of the editor even before they exist and marks them (new file), and Add a file in the values window lists the files of every other platform and custom config the same way.
The custom configs in the lists come from the folders Config/Custom/<Name> and Config/<Platform>/Custom/<Name>, the custom config of the editor target and the ones added in this session. New Custom Config… above the table of the Pulse window adds a column for a custom config no target uses yet; its files are created with the first value written.
Console commands
| Command | What it does |
|---|---|
Pulse.ConfigFiles.SaveTo <Type> [File] | Picks the file of Save changes to for a config type: Default, Windows, Custom/EOS, Windows/Custom/EOS, also files the editor does not read (Linux, Custom/EOSServer); without a file it lists the files the editor reads. |
Pulse.ConfigFiles.Create <Type> <File> | Creates a config file like New Config File and picks it for Save changes to, e.g. Pulse.ConfigFiles.Create Game Linux/Custom/Steam. |
Pulse.ConfigFiles.NewCustom <Name> | Adds a custom config to the lists of this session; its files are created with the first value written. |
Pulse.ConfigFiles.Show <SettingsClass> <Property> | Opens the values of a setting in every file. |
Every target at a glance
The tab Settings of the Pulse window (Tools > Pulse > Pulse) has the button Config Files next to every page of a plugin. It opens a table: one row per setting of the page, one column per build target of the project (Source/*.Target.cs: editor, game, client, server with their custom configs). A cell shows the value the target gets on the chosen platform and the file it comes from (Default, Custom EOSServer, Windows, … or engine or plugin when no project file sets it). A click on a cell opens the values in every file (see above).
A credential set in a file that a game or client target reads gets a !: players get that file. Server credentials belong into the custom config of the server target.
The page Foundation of the Pulse window has the same table for any page of the Project Settings (engine pages too): Config files of any Project Settings page > Choose a page.
Turning it off
Editor Preferences > Pulse > Foundation > Config Files > Choose Config Files (UPulseConfigFileSettings::bShowConfigFiles, per user) removes the bar and the buttons; the Project Settings then save as they do without Pulse.
In C++
Settings/PulseSettingsLayers.h (module PulseFoundationEditor, namespace Pulse::Editor::Settings):
| Function | What it does |
|---|---|
GetLayers(ConfigName) | All project files of a config type in reading order; bActive for the ones the editor reads. |
GetActiveLayers, GetLayersForTarget(Layers, Platform, CustomConfig) | The files of the editor or of one target. |
GetPlatforms, GetCustomConfigs | The platforms and custom configs the lists offer. |
MakeLayer(ConfigName, Platform, CustomConfig), ParseLayerId | The file of one platform and custom config, also of a new custom config; ids like Linux/Custom/Steam. |
CreateLayerFile | Creates the (empty) file of a layer and adds it in source control. |
GetTargetsReadingLayer(Layer, Targets) | The targets that read a file. |
ReadLayerValues, FindDecidingLayer | What each file sets for a key, and which file wins. |
MakePropertyLines | Section, key and lines the config system writes for a property (console variable keys included). |
WriteProperty, RemoveProperty, WriteLines | Write or remove a setting in one file (source control, reload of the config type when the editor reads the file). |
GetTargetLayer, SetTargetLayer, OnTargetLayerChanged | The file Save changes to points to. |
GetActiveTargetLayer | That file when the editor reads it, else Default<Type>.ini (for changes the editor has to load). |
GetProjectTargets, ParseTargetRules | The build targets of the project with type and custom config. |
AddCustomConfig, IsValidCustomConfigName | A custom config for this session, files on the first write. |
FPulseSettingsLayer::GetId, FindLayerById, FPulseSettingsLayer::Exists | Short ids for commands (Windows/Custom/EOS), whether the file exists. |
FindIniKeyLines, SetIniKeyLines, ParseIniKey, DescribeLines | Ini text helpers without file access. |