Project Settings Skill
🔀 Registered settings moved to the engine. Category-based registered-setting access (
list_categories/list_settings/get_setting/set_setting/set_category_settings_from_json) is now Unreal 5.8's nativeConfigSettingsToolset— reach it withcall_tool(rundescribe_toolsetonConfigSettingsToolsetfor its actions/params). VibeUE'sProjectSettingsServicewas trimmed to the delta the engine doesn't cover:discover_settings_classes+ direct INI read/write (get_ini_value/set_ini_value/*_ini_array/list_ini_sections/list_ini_keys) + config save, plusset_settings_property/get_settings_propertyfor one property of a settings class by name. Use those fromexecute_python_codeas shown below.
Critical Rules
⚠️ EditorStyleSettings is NOT a Python Class
EditorStyleSettings is not discoverable via discover_python_class('unreal.EditorStyleSettings') — it returns PYTHON_CLASS_NOT_FOUND. Reach it through the engine ConfigSettingsToolset as a settings category (via call_tool), or write its values directly via raw INI:
python# ❌ WRONG — will fail discover_python_class('unreal.EditorStyleSettings') # NOT FOUND # ✅ CORRECT — engine ConfigSettingsToolset (registered settings) via call_tool, OR the class by name: result = unreal.ProjectSettingsService.set_settings_property( "EditorStyleSettings", "AssetEditorOpenLocation", "MainWindow")
set_ini_value writes the file you name: a bare name resolves to the project Config/ folder
("DefaultGame.ini" → Config/DefaultGame.ini), an absolute path is used as-is, and the path must end
in .ini. A bare "EditorPerProjectUserSettings.ini" therefore writes
Config/EditorPerProjectUserSettings.ini, a file no config hierarchy reads. An absolute path does reach
a user-layer file under Saved/Config/<Platform>Editor/, but the editor keeps those files in memory and
rewrites them from memory when it saves its config (at the latest when it exits), which can silently drop
a direct write. Change user settings (editor preferences such as EditorStyleSettings) with
set_settings_property, which edits the editor's in-memory copy and saves it.
⚠️ Category vs Raw INI
Named registered-setting categories (general, maps, EditorStyleSettings, etc.) are handled by
the engine ConfigSettingsToolset. From VibeUE you instead address settings by their INI
section / key / file:
| Need | Use |
|---|---|
| Project info, maps, any registered category by name | engine ConfigSettingsToolset via call_tool |
| Read/write a known INI section+key | ProjectSettingsService.get_ini_value / set_ini_value |
| Set one property of any loaded config class, live and saved as the Settings window saves it | ProjectSettingsService.set_settings_property(class, property, value) |
| Discover which classes/sections exist | ProjectSettingsService.discover_settings_classes() |
⚠️ Map Paths Must Be Full Asset Paths
python# WRONG - folder path "/Game/Variant_Horror.Variant_Horror" # CORRECT - full map asset path "/Game/Variant_Horror/Lvl_Horror.Lvl_Horror"
Always verify with does_asset_exist() before setting.
⚠️ Always Check Operation Results
The INI write methods return an FProjectSettingResult:
pythonresult = unreal.ProjectSettingsService.set_ini_value( "/Script/EngineSettings.GeneralProjectSettings", "ProjectName", "MyGame", "DefaultGame.ini") if not result.success: print(f"Failed: {result.error_message}")
set_ini_value writes the key into the file on disk (the rest of the file, comments included, is
kept), reloads that config branch, and reads the file back: success is false when the value did not
land, and the file is then put back exactly as it was. A section or key containing a line break, a
section containing ], and a path that does not end in .ini are refused before anything is written.
A settings object read its config at startup, so it sees the new value after a restart
(requires_restart is true); set_settings_property applies the value live as well.
get_ini_value, list_ini_keys and get_ini_array read the file on disk as it is now (one file, not
the merged config hierarchy), so they see set_ini_value, set_settings_property and hand edits at
once. get_ini_value returns the plain Key= line, resolved as GConfig resolves it; +Key= /
.Key= array lines are not its value. get_ini_array returns the Key=, +Key= and .Key= lines in
file order (-Key= removals and !Key=ClearArray are not values). For the merged value a settings
object actually uses, read get_settings_property.
set_settings_property takes any loaded config class (CLASS_Config), not only the ones the
Settings window lists, and saves it the way the Settings window does: a defaultconfig class to its
project Default*.ini, a user-config class to its user file, any other class to its config branch
under Saved/Config. The value applies live (PostEditChangeProperty runs, as for an edit in the
details panel), so an engine or editor class changes behavior immediately. Per-object-config classes
are refused.
set_ini_array works only on a settings class section (/Script/Module.Class), through
set_settings_property: an array in a layered project file needs !Key=ClearArray / +Key=
lines relative to the lower layers, which only a settings object writes correctly. It replaces the
whole array. Each value is one element in Unreal text format: an element of a struct array is a
struct literal and goes in as written; an element of a string array is passed as the plain string and
quoted for you; any other element containing a space, comma, parenthesis or quote is quoted for you.
A section named by a config class's path is read and written in the section that class really uses.
Some classes keep an older name through OverrideConfigSection: ProjectPackagingSettings lives in
/Script/DeveloperToolSettings but its settings stay under [/Script/UnrealEd.ProjectPackagingSettings],
so get_ini_value / get_ini_array / list_ini_keys / set_ini_value given the new path use that section.
python# struct array: elements are struct literals, passed as written result = unreal.ProjectSettingsService.set_ini_array( "/Script/DeveloperToolSettings.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsNonUFS", ['(Path="Movies")', '(Path="Extras/Data")'], "DefaultGame.ini") # string array: plain values result = unreal.ProjectSettingsService.set_ini_array( "/Script/DeveloperToolSettings.ProjectPackagingSettings", "CulturesToStage", ["en", "pt-BR"], "DefaultGame.ini")
(Registered-setting writes via the engine ConfigSettingsToolset return their own result — check it the same way.)
Workflows
Basic Project Info Setup
Project info (name/company/description) is a registered category — set it via the engine
ConfigSettingsToolset (call_tool). Or write the INI keys directly from VibeUE:
pythonimport unreal sec = "/Script/EngineSettings.GeneralProjectSettings" file = "DefaultGame.ini" unreal.ProjectSettingsService.set_ini_value(sec, "ProjectName", "My RPG Game", file) unreal.ProjectSettingsService.set_ini_value(sec, "CompanyName", "Indie Studios", file) unreal.ProjectSettingsService.set_ini_value(sec, "Description", "An epic fantasy adventure", file) unreal.ProjectSettingsService.save_all_config()
Configure Default Maps
pythonimport unreal # Registered "maps" category → engine ConfigSettingsToolset via call_tool, OR raw INI: result = unreal.ProjectSettingsService.set_ini_value( "/Script/EngineSettings.GameMapsSettings", "GameDefaultMap", "/Game/Maps/MainMenu.MainMenu", "DefaultEngine.ini") if result.success: unreal.ProjectSettingsService.save_all_config() print("Default map updated and saved")
Set Editor Startup Map
pythonimport unreal # EditorStartupMap controls which level opens when the editor launches. It is a GameMapsSettings # property (defaultconfig, saved in Config/DefaultEngine.ini). # Registered "maps" category → engine ConfigSettingsToolset (via call_tool), OR the class by name: # Use full asset path format: /Game/Path/To/Level.Level result = unreal.ProjectSettingsService.set_settings_property( "GameMapsSettings", "EditorStartupMap", "/Game/Levels/MyLevel.MyLevel") if result.success: print("Editor startup map updated and saved:", result.modified_settings) else: print("Failed:", result.error_message)
💾 If the level must be saved first (untitled level, or "save as and set as startup"): the editor world comes from
unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem).get_editor_world()(NOTLevelEditorSubsystem, NOT deprecatedEditorLevelLibrary), thenunreal.EditorLoadingAndSavingUtils.save_map(world, "/Game/Maps/MyLevel"). Full workflow: load thelevel-actorsskill → "Save the Current Level".
Discover Settings Classes
pythonimport unreal classes = unreal.ProjectSettingsService.discover_settings_classes() for c in classes: print(f"{c.class_name}: {c.property_count} properties in {c.config_file}")
List Settings in a Category
Listing the settings inside a named category is an engine ConfigSettingsToolset action (via
call_tool). From VibeUE you can enumerate the raw INI keys of a known section instead:
pythonimport unreal sec = "/Script/EngineSettings.GeneralProjectSettings" file = "DefaultGame.ini" for key in unreal.ProjectSettingsService.list_ini_keys(sec, file): print(f"{key} = {unreal.ProjectSettingsService.get_ini_value(sec, key, file)}")
Find a Setting (When You Don't Know the Section)
discover_settings_classes() maps each settings class to its INI section + file, so you can
locate a setting without guessing Python class names, then read its keys via raw INI:
pythonimport unreal keyword = "AssetEditor" # partial match on class/section name for c in unreal.ProjectSettingsService.discover_settings_classes(): if keyword.lower() in c.class_name.lower() or keyword.lower() in c.config_section.lower(): print(f"{c.class_name} -> section {c.config_section} in {c.config_file}") for key in unreal.ProjectSettingsService.list_ini_keys(c.config_section, c.config_file): print(f" {key}")
Use discover_settings_classes() instead of guessing Python class names. Many settings classes
(e.g., EditorStyleSettings) are NOT exposed as Python classes — edit them through the engine
ConfigSettingsToolset or via their INI section.
Direct INI Access
pythonimport unreal # List sections sections = unreal.ProjectSettingsService.list_ini_sections("DefaultEngine.ini") # Get value value = unreal.ProjectSettingsService.get_ini_value("/Script/Engine.Engine", "GameEngine", "DefaultEngine.ini") # Set value result = unreal.ProjectSettingsService.set_ini_value( "/Script/MyGame.CustomSettings", "EnableDebugMode", "True", "DefaultGame.ini" )
Data Structures
Python Naming Convention: C++ types like
FProjectSettingResultare exposed asProjectSettingResultin Python (noFprefix).
SettingsClassInfo (from discover_settings_classes())
class_name,class_pathconfig_section,config_fileproperty_count,is_developer_settings
ProjectSettingResult (from INI write methods)
success,error_messagemodified_settings,failed_settingsrequires_restart
Sample scripts (run via execute_python_code)
scripts/configure_setting.txt— discover settings classes and read/write a project setting.


