BaseProfileName

BaseProfileName

#Overview

name: BaseProfileName

The value of this variable can be defined or overridden in .ini config files. 198 .ini config files referencing this setting variable.

It is referenced in 16 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of BaseProfileName is to establish a hierarchical relationship between device profiles in Unreal Engine 5. It is used to define the parent profile of a given device profile, allowing for inheritance of settings and properties.

This setting variable is primarily used in the Device Profile system, which is part of Unreal Engine’s core functionality. It is utilized by the Engine module and the DeviceProfiles subsystem.

The value of BaseProfileName is typically set in the device profile configuration files (e.g., DeviceProfiles.ini) or through the Unreal Engine editor interface when creating or modifying device profiles.

BaseProfileName interacts with several other variables and systems:

  1. It is used to build the parent-child relationship between device profiles (Parent property).
  2. It is used in conjunction with CVars (Console Variables) to inherit and override settings from parent profiles.
  3. It is used in the DeviceProfileManager to manage profile hierarchies and gather device-specific settings.

Developers should be aware of the following when using this variable:

  1. Circular references in the profile hierarchy can cause issues and should be avoided.
  2. The BaseProfileName is case-sensitive.
  3. An empty BaseProfileName indicates that the profile has no parent.

Best practices for using BaseProfileName include:

  1. Carefully plan the device profile hierarchy to avoid unnecessary complexity.
  2. Use meaningful and consistent naming conventions for profiles.
  3. Regularly review and maintain the profile hierarchy to ensure it remains relevant and efficient.
  4. Be cautious when changing BaseProfileName values, as it can have far-reaching effects on inherited settings.
  5. Use the UDeviceProfileManager class methods when manipulating device profiles programmatically to ensure consistency and proper updating of related data structures.

#Setting Variables

#References In INI files

<Workspace>/Engine/Config/BaseDeviceProfiles.ini:178, section: [Windows DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:183, section: [WindowsEditor DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:188, section: [WindowsClient DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:192, section: [WindowsServer DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:196, section: [WindowsCookedEditor DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:288, section: [IOS DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:324, section: [iPhone6S DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:335, section: [iPhone6SPlus DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:346, section: [iPhoneSE DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:355, section: [iPhone7 DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:363, section: [iPhone7Plus DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:371, section: [iPhone8 DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:380, section: [iPhone8Plus DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:389, section: [iPhoneX DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:395, section: [iPhoneXS DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:401, section: [iPhoneXSMax DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:407, section: [iPhoneXR DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:413, section: [iPhone11 DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:419, section: [iPhone11Pro DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:425, section: [iPhone11ProMax DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:431, section: [iPhoneSE2 DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:436, section: [iPhone12Mini DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:441, section: [iPhone12 DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:446, section: [iPhone12Pro DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:451, section: [iPhone12ProMax DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:456, section: [iPhone13Mini DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:461, section: [iPhone13 DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:466, section: [iPhone13Pro DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:471, section: [iPhone13ProMax DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:476, section: [iPhoneSE3 DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:481, section: [iPhone14 DeviceProfile]


... omitting 168 locations ...

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:1258

Scope (from outer to inner):

file
function     FNiagaraPlatformSet::FPlatformIniSettings& FNiagaraPlatformSet::GetPlatformIniSettings

Source code excerpt:

	//Load config files in which we can reasonable expect to find fx.Niagara.QualityLevel and may be set.
	FConfigFile LocalEngineIni;
	FConfigFile* LoadedEngineIni = FConfigCacheIni::FindOrLoadPlatformConfig(LocalEngineIni, TEXT("Engine"), *PlatformName); //Should use BaseProfileName? Are either of these ensured to be correct? I worry this is brittle.

	FConfigFile LocalGameIni;
	FConfigFile* LoadedGameIni = FConfigCacheIni::FindOrLoadPlatformConfig(LocalGameIni, TEXT("Game"), *PlatformName); //Should use BaseProfileName? Are either of these ensured to be correct? I worry this is brittle.
	
	FConfigFile LocalScalabilityIni;
	FConfigFile* LoadedScalabilityIni = FConfigCacheIni::FindOrLoadPlatformConfig(LocalScalabilityIni, TEXT("Scalability"), *PlatformName); //Should use BaseProfileName? Are either of these ensured to be correct? I worry this is brittle.

	auto FindCVarValue = [&](const TCHAR* Section, const TCHAR* CVarName, int32& OutVal)
	{
		bool bFound = true;
		if (!LoadedScalabilityIni->GetInt(Section, CVarName, OutVal))
		{

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/DeviceProfileDetails.cpp:540

Scope (from outer to inner):

file
function     void FDeviceProfileParentPropertyDetails::CreateParentPropertyView

Source code excerpt:

	
	// If we have a parent, display Console Variable information
	if(ActiveDeviceProfile != nullptr && ActiveDeviceProfile->BaseProfileName.Len() > 0)
	{
		// Get a list of the current profiles CVar names to use as a filter when showing parent CVars
		TArray<FString> DeviceProfileCVarNames;
		for (auto& NextActiveProfileCVar : ActiveDeviceProfile->CVars)
		{
			FString CVarName;

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/DeviceProfileDetails.cpp:608

Scope (from outer to inner):

file
function     void FDeviceProfileParentPropertyDetails::HandleDeviceProfileParentSelectionChanged

Source code excerpt:

void FDeviceProfileParentPropertyDetails::HandleDeviceProfileParentSelectionChanged(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
{
	ActiveDeviceProfile->BaseProfileName = *NewSelection.Get() == LOCTEXT("NoParentSelection", "None").ToString() ? TEXT("") : *NewSelection.Get();
	// -> Refresh the UI of the Details view to display the parent selection
	DetailBuilder->ForceRefreshDetails();

}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/DeviceProfiles/DeviceProfile.h:28

Scope (from outer to inner):

file
class        class UDeviceProfile : public UTextureLODSettings

Source code excerpt:

	/** The name of the parent profile of this object */
	UPROPERTY(EditAnywhere, config, Category=DeviceSettings)
	FString BaseProfileName;

	/** Some asset types can reference Device Profiles, is this profile visible to those assets. */
	UPROPERTY(EditAnywhere, config, Category = DeviceSettings)
	uint32 bIsVisibleForAssets : 1;

	/** The parent object of this profile, it is the object matching this DeviceType with the BaseProfileName */
	UPROPERTY()
	TObjectPtr<UDeviceProfile> Parent;

	/** Flag used in the editor to determine whether the profile is visible in the property matrix */
	bool bVisible;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfile.cpp:23

Scope (from outer to inner):

file
function     UDeviceProfile::UDeviceProfile

Source code excerpt:

	: Super(ObjectInitializer)
{
	BaseProfileName = TEXT("");
	DeviceType = TEXT("");
	bIsVisibleForAssets = false;

	bVisible = true;

	FString DeviceProfileFileName = FPaths::EngineConfigDir() + TEXT("Deviceprofiles.ini");

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfile.cpp:48

Scope (from outer to inner):

file
function     void UDeviceProfile::GatherParentCVarInformationRecursively

Source code excerpt:

{
	// Recursively build the parent tree
	if (!BaseProfileName.IsEmpty())
	{
		UDeviceProfile* ParentProfile = GetParentProfile(false);
		check(ParentProfile != nullptr);

		for (auto& CurrentCVar : ParentProfile->CVars)
		{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfile.cpp:84

Scope (from outer to inner):

file
function     UDeviceProfile* UDeviceProfile::GetParentProfile

Source code excerpt:

			return Parent;
		}
		if (!BaseProfileName.IsEmpty())
		{
			ParentProfile = FindObject<UDeviceProfile>(GetTransientPackage(), *BaseProfileName);
		}
		// don't find a parent for GlobalDefaults as it's the implied parent for everything (it would
		// return itself which is bad)
		if (!ParentProfile && bIncludeDefaultObject && GetName() != TEXT("GlobalDefaults"))
		{
			ParentProfile = FindObject<UDeviceProfile>(GetTransientPackage(), TEXT("GlobalDefaults"));

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfile.cpp:179

Scope (from outer to inner):

file
function     void UDeviceProfile::PostEditChangeProperty

Source code excerpt:

					do
					{
						if( this->GetName() == ParentProfile->BaseProfileName )
						{
							NumGenerations = NumGenerations > ProfileGeneration ? NumGenerations : ProfileGeneration;
							DependentProfiles.Add(*DeviceProfileIt,ProfileGeneration);
							break;
						}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:243

Scope (from outer to inner):

file
function     TMap<FName, FString> UDeviceProfileManager::GatherDeviceProfileCVars

Source code excerpt:

	static FString SectionSuffix = *FString::Printf(TEXT(" %s"), *UDeviceProfile::StaticClass()->GetName());

	// For each device profile, starting with the selected and working our way up the BaseProfileName tree,
	FString BaseDeviceProfileName = DeviceProfileName;
	bool bReachedEndOfTree = BaseDeviceProfileName.IsEmpty();
	while (bReachedEndOfTree == false)
	{
		FString CurrentSectionName = BaseDeviceProfileName + SectionSuffix;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:611

Scope (from outer to inner):

file
function     bool UDeviceProfileManager::DoActiveProfilesReference
lambda-function

Source code excerpt:

	auto DoesProfileReference = [&AvailableProfiles, GDeviceProfilesIni = GDeviceProfilesIni](const FString& SearchProfile, const TSet<FString>& InDeviceProfilesToQuery)
	{
		// For each device profile, starting with the selected and working our way up the BaseProfileName tree,
		FString BaseDeviceProfileName = SearchProfile;
		bool bReachedEndOfTree = BaseDeviceProfileName.IsEmpty();
		while (bReachedEndOfTree == false)
		{
			FString CurrentSectionName = FString::Printf(TEXT("%s %s"), *BaseDeviceProfileName, *UDeviceProfile::StaticClass()->GetName());
			bool bProfileExists = AvailableProfiles.Contains(CurrentSectionName);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:627

Scope (from outer to inner):

file
function     bool UDeviceProfileManager::DoActiveProfilesReference
lambda-function

Source code excerpt:

				// Get the next device profile name
				FString NextBaseDeviceProfileName;
				if (GConfig->GetString(*CurrentSectionName, TEXT("BaseProfileName"), NextBaseDeviceProfileName, GDeviceProfilesIni))
				{
					BaseDeviceProfileName = NextBaseDeviceProfileName;
				}
				else
				{
					BaseDeviceProfileName.Empty();

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:693

Scope (from outer to inner):

file
function     static void TestProfileForCircularReferences

Source code excerpt:

			const FString SectionName = FString::Printf(TEXT("%s %s"), *CurrentParent, *UDeviceProfile::StaticClass()->GetName());
			CurrentParent.Reset();
			PlatformConfigFile.GetString(*SectionName, TEXT("BaseProfileName"), CurrentParent);
		}
	}
}

UDeviceProfile* UDeviceProfileManager::CreateProfile(const FString& ProfileName, const FString& ProfileType, const FString& InSpecifyParentName, const TCHAR* ConfigPlatform)
{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:730

Scope (from outer to inner):

file
function     UDeviceProfile* UDeviceProfileManager::CreateProfile

Source code excerpt:

		{
			const FString SectionName = FString::Printf(TEXT("%s %s"), *ProfileName, *UDeviceProfile::StaticClass()->GetName());
			PlatformConfigFile->GetString(*SectionName, TEXT("BaseProfileName"), ParentName);
		}

		UDeviceProfile* ParentObject = nullptr;
		// Recursively build the parent tree
		if (ParentName.Len() > 0 && ParentName != ProfileName)
		{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:764

Scope (from outer to inner):

file
function     UDeviceProfile* UDeviceProfileManager::CreateProfile

Source code excerpt:


		// final fixups
		DeviceProfile->BaseProfileName = DeviceProfile->BaseProfileName.Len() > 0 ? DeviceProfile->BaseProfileName : ParentName;
		DeviceProfile->Parent = ParentObject;
		// the DP manager can be marked as Disregard for GC, so what it points to needs to be in the Root set
		DeviceProfile->AddToRoot();

		// Add the new profile to the accessible device profile list
		Profiles.Add( DeviceProfile );

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:1165

Scope (from outer to inner):

file
function     bool UDeviceProfileManager::AreProfilesTheSame

Source code excerpt:

	}

	if (!Profile1->BaseProfileName.Equals(Profile2->BaseProfileName, ESearchCase::CaseSensitive))
	{
		return false;
	}


	if (Profile1->CVars != Profile2->CVars)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:1371

Scope (from outer to inner):

file
function     void UDeviceProfileManager::GetAllPossibleParentProfiles

Source code excerpt:

			do
			{
				if(CurrentAncestor->BaseProfileName == ChildProfile->GetName())
				{
					bIsValidPossibleParent = false;
					break;
				}
				else
				{