PackageRedirects

PackageRedirects

#Overview

name: PackageRedirects

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

It is referenced in 18 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of PackageRedirects is to handle package redirections in Unreal Engine 5. It is primarily used for managing changes in package names or locations, allowing the engine to redirect references from old package names to new ones.

PackageRedirects is utilized by various Unreal Engine subsystems and modules, including:

  1. IoStore (I/O Store) system
  2. Asset Registry
  3. Blueprint system
  4. Core redirects system
  5. Linker loading system
  6. Metadata system
  7. Gameplay Tags system
  8. Package file system

The value of this variable is typically set in configuration files, particularly in the Engine.ini file under the [/Script/Engine.Engine] section. It can also be modified programmatically in some cases.

PackageRedirects often interacts with other variables and systems related to asset management, such as:

Developers should be aware of the following when using PackageRedirects:

  1. It’s crucial for maintaining backwards compatibility when package names or locations change.
  2. Improper use can lead to asset loading issues or broken references.
  3. It affects various parts of the engine, so changes should be made carefully.

Best practices for using PackageRedirects include:

  1. Always update PackageRedirects when renaming or moving packages to maintain compatibility with existing content.
  2. Use the appropriate configuration files (e.g., Engine.ini) to set up redirects.
  3. Be consistent with redirect naming conventions across your project.
  4. Regularly clean up old redirects that are no longer necessary to improve performance.
  5. Test thoroughly after adding or modifying redirects to ensure all affected systems work correctly.
  6. Document any significant changes to package redirects for team members and future reference.

#Setting Variables

#References In INI files

<Workspace>/Engine/Config/BaseEngine.ini:352, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:353, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:587, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:654, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:674, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:675, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:743, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:844, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:845, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:853, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:854, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:855, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:857, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:858, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:859, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:860, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:862, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:864, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:865, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:866, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:868, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:869, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:870, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:871, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:872, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:968, section: [CoreRedirects]
<Workspace>/Engine/Config/BaseEngine.ini:1016, section: [CoreRedirects]
<Workspace>/Engine/Plugins/Compositing/OpenCVLensDistortion/Config/BaseOpenCVLensDistortion.ini:7, section: [CoreRedirects]
<Workspace>/Engine/Plugins/Enterprise/DatasmithContent/Config/BaseDatasmithContent.ini:2, section: [CoreRedirects]
<Workspace>/Engine/Plugins/Enterprise/DatasmithContent/Config/BaseDatasmithContent.ini:3, section: [CoreRedirects]
<Workspace>/Engine/Plugins/Enterprise/DatasmithContent/Config/BaseDatasmithContent.ini:4, section: [CoreRedirects]


... omitting 75 locations ...

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Developer/IoStoreUtilities/Private/IoStoreUtilities.cpp:5114

Scope (from outer to inner):

file
function     void CreateContainerHeader

Source code excerpt:

				else
				{
					Header.PackageRedirects.Add({ FPackageId::FromName(Package->SourcePackageName), Package->GlobalPackageId, MappedSourcePackageName });
				}
			}

			// ImportedPackages
			const TArray<FPackageId>& ImportedPackageIds = Entry.ImportedPackageIds;
			SerializePackageEntryCArrayHeader(StoreEntriesWriter, ImportedPackageIds.Num());

#Loc: <Workspace>/Engine/Source/Developer/IoStoreUtilities/Private/IoStoreUtilities.cpp:6754

Scope (from outer to inner):

file
namespace    DescribeUtils

Source code excerpt:

		FGuid EncryptionKeyGuid;
		TArray<FPackageDesc*> LocalizedPackages;
		TArray<FPackageRedirect> PackageRedirects;
		bool bCompressed;
		bool bSigned;
		bool bEncrypted;
		bool bIndexed;
	};

#Loc: <Workspace>/Engine/Source/Developer/IoStoreUtilities/Private/IoStoreUtilities.cpp:7037

Scope (from outer to inner):

file
namespace    DescribeUtils
function     TOptional<FContainerPackageInfo> TryGetContainerPackageInfo
lambda-function

Source code excerpt:


				Job.RawLocalizedPackages = ContainerHeader.LocalizedPackages;
				Job.RawPackageRedirects = ContainerHeader.PackageRedirects;

				TArrayView<FFilePackageStoreEntry> StoreEntries(reinterpret_cast<FFilePackageStoreEntry*>(ContainerHeader.StoreEntries.GetData()), ContainerHeader.PackageIds.Num());

				int32 PackageIndex = 0;
				Job.Packages.Reserve(StoreEntries.Num());
				for (FFilePackageStoreEntry& ContainerEntry : StoreEntries)

#Loc: <Workspace>/Engine/Source/Developer/IoStoreUtilities/Private/IoStoreUtilities.cpp:7095

Scope (from outer to inner):

file
namespace    DescribeUtils
function     TOptional<FContainerPackageInfo> TryGetContainerPackageInfo

Source code excerpt:

			for (const auto& RedirectPair : LoadContainerHeaderJob.RawPackageRedirects)
			{
				FPackageRedirect& PackageRedirect = LoadContainerHeaderJob.ContainerDesc->PackageRedirects.AddDefaulted_GetRef();
				PackageRedirect.Source = PackageByIdMap.FindRef(RedirectPair.SourcePackageId);
				PackageRedirect.Target = PackageByIdMap.FindRef(RedirectPair.TargetPackageId);
			}
			for (const auto& LocalizedPackage : LoadContainerHeaderJob.RawLocalizedPackages)
			{
				LoadContainerHeaderJob.ContainerDesc->LocalizedPackages.Add(PackageByIdMap.FindRef(LocalizedPackage.SourcePackageId));

#Loc: <Workspace>/Engine/Source/Developer/IoStoreUtilities/Private/IoStoreUtilities.cpp:7515

Scope (from outer to inner):

file
function     int32 Describe

Source code excerpt:

			}

			if (ContainerDesc->PackageRedirects.Num())
			{
				bool bNeedsHeader = true;
				for (const FPackageRedirect& Redirect : ContainerDesc->PackageRedirects)
				{
					if (RelevantPackages.Num() > 0 && !RelevantPackages.Contains(Redirect.Source->PackageId) && !RelevantPackages.Contains(Redirect.Target->PackageId))
					{
						continue;
					}
					if (bNeedsHeader)

#Loc: <Workspace>/Engine/Source/Editor/BlueprintGraph/Private/K2Node_BaseAsyncTask.cpp:673

Scope (from outer to inner):

file
function     UK2Node::ERedirectType UK2Node_BaseAsyncTask::DoPinsMatchForReconstruction

Source code excerpt:

		{
			bAsyncTaskPinRedirectMapInitialized = true;
			const FConfigSection* PackageRedirects = GConfig->GetSection(TEXT("/Script/Engine.Engine"), false, GEngineIni);
			for (FConfigSection::TConstIterator It(*PackageRedirects); It; ++It)
			{
				if (It.Key() == TEXT("K2AsyncTaskPinRedirects"))
				{
					FString ProxyClassString;
					FString OldPinString;
					FString NewPinString;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Commandlets/DerivedDataCacheCommandlet.cpp:860

Scope (from outer to inner):

file
function     int32 UDerivedDataCacheCommandlet::Main

Source code excerpt:

						FCoreRedirectObjectName CoreRedirectName;
						CoreRedirectName.PackageName = SoftRefName;
						// Packages that are specifically identified by PackageRedirects as removed need to be skipped.
						if (FCoreRedirects::IsKnownMissing(ECoreRedirectFlags::Type_Package, CoreRedirectName))
						{
							continue;
						}

						if (FPackageName::DoesPackageExist(SoftRefName.ToString(), &SoftRefFilename))

#Loc: <Workspace>/Engine/Source/Runtime/AssetRegistry/Private/AssetRegistry.cpp:1117

Scope (from outer to inner):

file
namespace    UE::AssetRegistry
function     bool FAssetRegistryImpl::ResolveRedirect

Source code excerpt:

	const FString& PackageName = *PackageNamePtr;

	for (const FAssetRegistryPackageRedirect& PackageRedirect : PackageRedirects)
	{
		if (PackageName.Compare(PackageRedirect.SourcePackageName) == 0)
		{
			OutPackageName = InPackageName.Replace(*PackageRedirect.SourcePackageName, *PackageRedirect.DestPackageName);
			return true;
		}

#Loc: <Workspace>/Engine/Source/Runtime/AssetRegistry/Private/AssetRegistry.cpp:1176

Scope (from outer to inner):

file
namespace    UE::AssetRegistry
function     void FAssetRegistryImpl::InitRedirectors
lambda-function

Source code excerpt:

				FString OriginalPackageNameString = NewPackageNameString.Replace(*RootPackageName, TEXT("/Game/"));

				PackageRedirects.Add(FAssetRegistryPackageRedirect(OriginalPackageNameString, NewPackageNameString));
				return true;
			}, true, false);

		bOutRedirectorsNeedSubscribe = true;
	}
}

#Loc: <Workspace>/Engine/Source/Runtime/AssetRegistry/Private/AssetRegistryImpl.h:469

Scope (from outer to inner):

file
namespace    UE::AssetRegistry
class        class FAssetRegistryImpl

Source code excerpt:

		FString DestPackageName;
	};
	TArray<FAssetRegistryPackageRedirect> PackageRedirects;

#if WITH_EDITOR
	/** List of objects that need to be processed because they were loaded or saved */
	TRingBuffer<TWeakObjectPtr<const UObject>> LoadedAssetsToProcess;

	/** The set of object paths that have had their disk cache updated from the in memory version */

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/IO/IoContainerHeader.cpp:54

Scope (from outer to inner):

file
function     FArchive& operator<<

Source code excerpt:

	}
	Ar << ContainerHeader.LocalizedPackages;
	Ar << ContainerHeader.PackageRedirects;

	return Ar;
}

#Loc: <Workspace>/Engine/Source/Runtime/Core/Public/IO/IoContainerHeader.h:88

Scope: file

Source code excerpt:

	TArray<FDisplayNameEntryId> RedirectsNameMap;
	TArray<FIoContainerHeaderLocalizedPackage> LocalizedPackages;
	TArray<FIoContainerHeaderPackageRedirect> PackageRedirects;

	CORE_API friend FArchive& operator<<(FArchive& Ar, FIoContainerHeader& ContainerHeader);
};

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/UObject/CoreRedirects.cpp:578

Scope (from outer to inner):

file
function     void FCoreRedirects::Initialize

Source code excerpt:

	ConfigKeyMap.Add(TEXT("FunctionRedirects"), ECoreRedirectFlags::Type_Function);
	ConfigKeyMap.Add(TEXT("PropertyRedirects"), ECoreRedirectFlags::Type_Property);
	ConfigKeyMap.Add(TEXT("PackageRedirects"), ECoreRedirectFlags::Type_Package);

	RegisterNativeRedirects();

	// Prepopulate RedirectTypeMap entries that some threads write to after the engine goes multi-threaded.
	// Most RedirectTypeMap entries are written to only from InitUObject's call to ReadRedirectsFromIni, and at that point the Engine is single-threaded.
	// Known missing packages and plugin loads can add entries to existing lists but will not add brand new types.

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/UObject/LinkerLoad.cpp:238

Scope (from outer to inner):

file
function     void FLinkerLoad::CreateActiveRedirectsMap

Source code excerpt:

	if (GConfig)
	{
		const FConfigSection* PackageRedirects = GConfig->GetSection( TEXT("/Script/Engine.Engine"), false, GEngineIniName );
		if (PackageRedirects)
		{
			TArray<FCoreRedirect> NewRedirects;
			FDeferredMessageLog RedirectErrors(NAME_LoadErrors);

			static FName ActiveClassRedirectsKey(TEXT("ActiveClassRedirects"));
			for( FConfigSection::TConstIterator It(*PackageRedirects); It; ++It )
			{
				if (It.Key() == ActiveClassRedirectsKey)
				{
					FName OldClassName = NAME_None;
					FName NewClassName = NAME_None;
					FName ObjectName = NAME_None;

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/UObject/MetaData.cpp:473

Scope (from outer to inner):

file
function     void UMetaData::InitializeRedirectMap

Source code excerpt:

			const FName MetadataRedirectsName(TEXT("MetadataRedirects"));

			const FConfigSection* PackageRedirects = GConfig->GetSection(TEXT("CoreUObject.Metadata"), false, GEngineIni);
			if (PackageRedirects)
			{
				for (FConfigSection::TConstIterator It(*PackageRedirects); It; ++It)
				{
					if (It.Key() == MetadataRedirectsName)
					{
						FName OldKey = NAME_None;
						FName NewKey = NAME_None;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/MemberReference.cpp:202

Scope (from outer to inner):

file
function     void FMemberReference::InitFieldRedirectMap

Source code excerpt:

			TArray<FCoreRedirect> NewRedirects;

			const FConfigSection* PackageRedirects = GConfig->GetSection( TEXT("/Script/Engine.Engine"), false, GEngineIni );
			for (FConfigSection::TConstIterator It(*PackageRedirects); It; ++It)
			{
				if (It.Key() == TEXT("K2FieldRedirects"))
				{
					FString OldFieldPathString;
					FString NewFieldPathString;

#Loc: <Workspace>/Engine/Source/Runtime/GameplayTags/Private/GameplayTagRedirectors.cpp:18

Scope (from outer to inner):

file
function     FGameplayTagRedirectors::FGameplayTagRedirectors

Source code excerpt:

	// Check the deprecated location
	bool bFoundDeprecated = false;
	const FConfigSection* PackageRedirects = GConfig->GetSection(TEXT("/Script/Engine.Engine"), false, GEngineIni);

	if (PackageRedirects)
	{
		for (FConfigSection::TConstIterator It(*PackageRedirects); It; ++It)
		{
			if (It.Key() == TEXT("+GameplayTagRedirects"))
			{
				FName OldTagName = NAME_None;
				FName NewTagName;

#Loc: <Workspace>/Engine/Source/Runtime/PakFile/Private/FilePackageStore.cpp:676

Scope (from outer to inner):

file
function     void FFilePackageStoreBackend::Update

Source code excerpt:

			}

			for (const FIoContainerHeaderPackageRedirect& Redirect : ContainerHeader->PackageRedirects)
			{
				TTuple<FName, FPackageId>& RedirectEntry = RedirectsPackageMap.FindOrAdd(Redirect.SourcePackageId);
				FName& SourcePackageName = RedirectEntry.Key;
				if (SourcePackageName.IsNone())
				{
					FDisplayNameEntryId NameEntry = ContainerHeader->RedirectsNameMap[Redirect.SourcePackageName.GetIndex()];