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:
- IoStore (I/O Store) system
- Asset Registry
- Blueprint system
- Core redirects system
- Linker loading system
- Metadata system
- Gameplay Tags system
- 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:
- LocalizedPackages
- AssetRegistry
- CoreRedirects
- GameplayTagRedirects
Developers should be aware of the following when using PackageRedirects:
- It’s crucial for maintaining backwards compatibility when package names or locations change.
- Improper use can lead to asset loading issues or broken references.
- It affects various parts of the engine, so changes should be made carefully.
Best practices for using PackageRedirects include:
- Always update PackageRedirects when renaming or moving packages to maintain compatibility with existing content.
- Use the appropriate configuration files (e.g., Engine.ini) to set up redirects.
- Be consistent with redirect naming conventions across your project.
- Regularly clean up old redirects that are no longer necessary to improve performance.
- Test thoroughly after adding or modifying redirects to ensure all affected systems work correctly.
- 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()];