MaxDiffsToLog

MaxDiffsToLog

#Overview

name: MaxDiffsToLog

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

It is referenced in 40 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of MaxDiffsToLog is to limit the number of differences logged between two versions of a package during the Unreal Engine cooking process. It is primarily used in the rendering and asset processing systems to control the verbosity of difference reporting.

MaxDiffsToLog is used by the Unreal Engine’s cooker subsystem, particularly in the DiffPackageWriter module. This variable is part of the diff writing and comparison functionality used when cooking packages.

The value of MaxDiffsToLog is typically set in the constructor of FDiffPackageWriter. It’s initialized with a default value of 5, but can be overridden by:

  1. A value specified in the GEditorIni configuration file under the [CookSettings] section.
  2. A command-line parameter “MaxDiffstoLog=”.

MaxDiffsToLog interacts with various counters and flags in the diff writing process, such as InOutDiffsLogged, NumDiffsForLogStatLocal, and FirstUnreportedDiffIndex.

Developers should be aware that:

  1. Setting MaxDiffsToLog to a negative value will log all differences without limit.
  2. If more differences are found than MaxDiffsToLog allows, a warning message will be logged indicating how many differences were not reported.
  3. This variable affects performance and log file size during the cooking process.

Best practices when using this variable include:

  1. Set it to a reasonable value that balances between getting enough information and avoiding excessive logging.
  2. Consider increasing its value temporarily when investigating specific diff issues.
  3. Be aware of its impact on cooking time and log file size, especially for large projects.
  4. Use in conjunction with other diff-related settings like bIgnoreHeaderDiffs for fine-tuned control over the diff process.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditor.ini:370, section: [CookSettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffPackageWriter.cpp:32

Scope (from outer to inner):

file
function     FDiffPackageWriter::FDiffPackageWriter

Source code excerpt:

	AccumulatorGlobals.Reset(new UE::DiffWriter::FAccumulatorGlobals(Inner.Get()));

	GConfig->GetInt(TEXT("CookSettings"), TEXT("MaxDiffsToLog"), MaxDiffsToLog, GEditorIni);
	// Command line override for MaxDiffsToLog
	FParse::Value(FCommandLine::Get(), TEXT("MaxDiffstoLog="), MaxDiffsToLog);

	bSaveForDiff = FParse::Param(FCommandLine::Get(), TEXT("SaveForDiff"));
	bDiffOptional = FParse::Param(FCommandLine::Get(), TEXT("DiffOptional"));

	GConfig->GetBool(TEXT("CookSettings"), TEXT("IgnoreHeaderDiffs"), bIgnoreHeaderDiffs, GEditorIni);
	// Command line override for IgnoreHeaderDiffs

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffPackageWriter.cpp:227

Scope (from outer to inner):

file
function     UE::DiffWriter::FAccumulator& FDiffPackageWriter::ConstructAccumulator

Source code excerpt:

	{
		check(!bHasStartedSecondSave); // Accumulator should already exist from CreateLinkerArchive in the first save
		Accumulator = new UE::DiffWriter::FAccumulator(*AccumulatorGlobals, Asset, *PackageName.ToString(), MaxDiffsToLog,
			bIgnoreHeaderDiffs, GetDiffWriterMessageCallback(), Inner->GetCookCapabilities().HeaderFormat);
	}
	return *Accumulator;
}

TUniquePtr<FLargeMemoryWriter> FDiffPackageWriter::CreateLinkerArchive(FName PackageName,

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffPackageWriter.h:139

Scope (from outer to inner):

file
class        class FDiffPackageWriter : public ICookedPackageWriter

Source code excerpt:

	FString DumpObjListParams;
	FString PackageFilter;
	int32 MaxDiffsToLog = 5;
	bool bSaveForDiff = false;
	bool bDiffOptional = false;
	bool bIgnoreHeaderDiffs = false;
	bool bIsDifferent = false;
	bool bNewPackage = false;
	bool bDiffCallstack = false;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:37

Scope (from outer to inner):

file
namespace    UE::DiffWriter

Source code excerpt:

void DumpPackageHeaderDiffs(
	FAccumulatorGlobals& Globals, const FPackageData& SourcePackage, const FPackageData& DestPackage,
	const FString& AssetFilename, const int32 MaxDiffsToLog, const EPackageHeaderFormat PackageHeaderFormat,
	const FMessageCallback& MessageCallback);
/** Returns a new linker for loading the specified package. */
FLinkerLoad* CreateLinkerForPackage(
	FUObjectSerializeContext* LoadContext,
	const FString& InPackageName,
	const FString& InFilename,

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:521

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     FAccumulator::FAccumulator

Source code excerpt:

	, PackageName(InPackageName)
	, Asset(InAsset)
	, MaxDiffsToLog(InMaxDiffsToLog)
	, PackageHeaderFormat(InPackageHeaderFormat)
	, bIgnoreHeaderDiffs(bInIgnoreHeaderDiffs)
{
	GBreakAtOffsetSettings.Initialize();
}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:607

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void FAccumulator::OnSecondSaveComplete

Source code excerpt:

		FPackageData SecondSaveHeader{ LinkerArchive->GetData(), InHeaderSize };
		int32 NumHeaderDiffMessages = 0;
		DumpPackageHeaderDiffs(Globals, FirstSaveHeader, SecondSaveHeader, Filename, MaxDiffsToLog,
			PackageHeaderFormat,
			[&NumHeaderDiffMessages, this](ELogVerbosity::Type Verbosity, FStringView Message)
			{
				MessageCallback(Verbosity, Message);
				++NumHeaderDiffMessages;
			});

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:843

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void FAccumulator::CompareWithPreviousForSection

Source code excerpt:


		// Skip logging of the difference if we are over the limit
		if (bCallstackSuppressLogging || (MaxDiffsToLog >= 0 && InOutDiffsLogged >= MaxDiffsToLog))
		{
			if (FirstUnreportedDiffIndex == -1)
			{
				FirstUnreportedDiffIndex = LocalOffset;
			}
			continue;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:988

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void FAccumulator::CompareWithPreviousForSection

Source code excerpt:

	}

	if (MaxDiffsToLog >= 0 && NumDiffsForLogStatLocal > NumDiffsLoggedLocal)
	{
		MessageCallback(ELogVerbosity::Warning, FString::Printf(
			TEXT("%s: %lld difference(s) not logged (first at offset: %lld)."),
			*SectionFilename, NumDiffsForLogStatLocal - NumDiffsLoggedLocal, FirstUnreportedDiffIndex));
	}
}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1045

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void FAccumulator::CompareWithPrevious

Source code excerpt:

	{
		int32 NumHeaderDiffMessages = 0;
		DumpPackageHeaderDiffs(Globals, SourcePackage, DestPackage, Filename, MaxDiffsToLog,
			PackageHeaderFormat,
			[&NumHeaderDiffMessages, this](ELogVerbosity::Type Verbosity, FStringView Message)
			{
				MessageCallback(Verbosity, Message);
				++NumHeaderDiffMessages;
			});

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1161

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void FAccumulator::GenerateDiffMapForSection

Source code excerpt:

		{
			bIdentical = false;
			if (DiffMap.Num() < MaxDiffsToLog)
			{
				const int32 DifferenceCallstackOffsetIndex = Callstacks.GetCallstackIndexAtOffset(DestAbsoluteOffset, FMath::Max<int32>(LastDifferenceCallstackOffsetIndex, 0));
				if (DifferenceCallstackOffsetIndex >= 0 && DifferenceCallstackOffsetIndex != LastDifferenceCallstackOffsetIndex)
				{
					const FCallstacks::FCallstackAtOffset& CallstackAtOffset = Callstacks.GetCallstack(DifferenceCallstackOffsetIndex);
					if (!CallstackAtOffset.bSuppressLogging)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1185

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void FAccumulator::GenerateDiffMapForSection

Source code excerpt:


		// Add all the remaining callstacks to the diff map
		for (int32 OffsetIndex = LastDifferenceCallstackOffsetIndex + 1; OffsetIndex < Callstacks.Num() && DiffMap.Num() < MaxDiffsToLog; ++OffsetIndex)
		{
			const FCallstacks::FCallstackAtOffset& CallstackAtOffset = Callstacks.GetCallstack(OffsetIndex);
			// Compare against the size without start offset as all callstack offsets are absolute (from the merged header + exports file)
			if (CallstackAtOffset.Offset < DestPackage.Size)
			{
				if (!CallstackAtOffset.bSuppressLogging)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1214

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void FAccumulator::GenerateDiffMap

Source code excerpt:

void FAccumulator::GenerateDiffMap()
{
	check(MaxDiffsToLog > 0);
	// An FDiffArchiveForLinker should have been constructed by SavePackage and should still be in memory
	check(LinkerArchive != nullptr);

	bHasDifferences = true;
	DiffMap.Reset();

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1325

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     static void DumpTableDifferences

Source code excerpt:

	const TCHAR* AssetFilename,
	const TCHAR* ItemName,
	const int32 MaxDiffsToLog
)
{
	FString HumanReadableString;
	int32 LoggedDiffs = 0;
	int32 NumDiffs = 0;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1385

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     static void DumpTableDifferences

Source code excerpt:

	}

	// For now just log everything out. When this becomes too spammy, respect the MaxDiffsToLog parameter
	NumDiffs = RemovedItems.Num() + AddedItems.Num();
	LoggedDiffs = NumDiffs;

	if (NumDiffs > LoggedDiffs)
	{
		HumanReadableString += IndentToken;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1413

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void DumpPackageHeaderDiffs_LinkerLoad

Source code excerpt:

	const FPackageData& DestPackage,
	const FString& AssetFilename,
	const int32 MaxDiffsToLog,
	const FMessageCallback& MessageCallback)
{
	FString AssetPathName = FPaths::Combine(*FPaths::GetPath(AssetFilename.Mid(AssetFilename.Find(TEXT(":"), ESearchCase::CaseSensitive) + 1)), *FPaths::GetBaseFilename(AssetFilename));
	// The root directory could have a period in it (d:/Release5.0/EngineTest/Saved/Cooked),
	// which is not a valid character for a LongPackageName. Remove it.
	for (TCHAR c : FStringView(INVALID_LONGPACKAGE_CHARACTERS))

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1456

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void DumpPackageHeaderDiffs_LinkerLoad

Source code excerpt:

		{
			DumpTableDifferences<FNameEntryId>(SourceContext, DestContext, SourceLinker->NameMap, DestLinker->NameMap,
				*AssetFilename, TEXT("Name"), MaxDiffsToLog);
		}

		if (!SourceContext.IsImportMapIdentical(DestContext))
		{
			DumpTableDifferences<FObjectImport>(SourceContext, DestContext, SourceLinker->ImportMap, DestLinker->ImportMap,
				*AssetFilename, TEXT("Import"), MaxDiffsToLog);
		}

		if (!SourceContext.IsExportMapIdentical(DestContext))
		{
			DumpTableDifferences<FObjectExport>(SourceContext, DestContext, SourceLinker->ExportMap, DestLinker->ExportMap,
				*AssetFilename, TEXT("Export"), MaxDiffsToLog);
		}
	}

	if (SourceLinker)
	{
		UE::ArchiveStackTrace::ForceKillPackageAndLinker(SourceLinker);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1487

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void DumpPackageHeaderDiffs_ZenPackage

Source code excerpt:

	const FPackageData& DestPackage,
	const FString& AssetFilename,
	const int32 MaxDiffsToLog,
	const FMessageCallback& MessageCallback)
{
	FDiffWriterZenHeader SourceHeader(Globals, MessageCallback, true /* bUseZenStore */, SourcePackage, AssetFilename,
		TEXT("source"));
	FDiffWriterZenHeader DestHeader(Globals, MessageCallback, false /* bUseZenStore */, DestPackage, AssetFilename,
		TEXT("dest"));

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1526

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void DumpPackageHeaderDiffs_ZenPackage

Source code excerpt:

	{
		DumpTableDifferences<FString>(SourceHeader, DestHeader, SourceNames, DestNames,
			*AssetFilename, TEXT("Name"), MaxDiffsToLog);
	}

	if (!SourceHeader.IsImportMapIdentical(DestHeader))
	{
		DumpTableDifferences<FPackageObjectIndex>(SourceHeader, DestHeader, SourceHeader.GetPackageHeader().ImportMap,
			DestHeader.GetPackageHeader().ImportMap, *AssetFilename, TEXT("Import"), MaxDiffsToLog);
	}

	if (!SourceHeader.IsExportMapIdentical(DestHeader))
	{
		int32 SourceNum = SourceHeader.GetPackageHeader().ExportMap.Num();
		int32 DestNum = DestHeader.GetPackageHeader().ExportMap.Num();

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.cpp:1552

Scope (from outer to inner):

file
namespace    UE::DiffWriter
function     void DumpPackageHeaderDiffs_ZenPackage

Source code excerpt:

		}
		DumpTableDifferences<FZenHeaderIndexIntoExportMap>(SourceHeader, DestHeader, SourceIndices, DestIndices,
			*AssetFilename, TEXT("Export"), MaxDiffsToLog);
	}
}

void DumpPackageHeaderDiffs(
	FAccumulatorGlobals& Globals,
	const FPackageData& SourcePackage,
	const FPackageData& DestPackage,
	const FString& AssetFilename,
	const int32 MaxDiffsToLog,
	const EPackageHeaderFormat PackageHeaderFormat,
	const FMessageCallback& MessageCallback)
{
	switch (PackageHeaderFormat)
	{
	case EPackageHeaderFormat::PackageFileSummary:
		DumpPackageHeaderDiffs_LinkerLoad(Globals, SourcePackage, DestPackage, AssetFilename, MaxDiffsToLog, MessageCallback);
		break;
	case EPackageHeaderFormat::ZenPackageSummary:
		DumpPackageHeaderDiffs_ZenPackage(Globals, SourcePackage, DestPackage, AssetFilename, MaxDiffsToLog, MessageCallback);
		break;
	default:
		unimplemented();
	}
}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/DiffWriterArchive.h:291

Scope (from outer to inner):

file
namespace    UE::DiffWriter
class        class FAccumulator : public FRefCountBase

Source code excerpt:

	int64 HeaderSize = 0;
	int64 PreTransformHeaderSize = 0;
	int32 MaxDiffsToLog = 5;
	EPackageHeaderFormat PackageHeaderFormat = EPackageHeaderFormat::PackageFileSummary;
	bool bFirstSaveComplete = false;
	bool bHasDifferences = false;
	bool bIgnoreHeaderDiffs = false;

	friend class FCallstacks;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Tests/DiffWriterArchiveTests.cpp:47

Scope (from outer to inner):

file
function     bool FDiffWriterArchiveTestsCallstacks::RunTest

Source code excerpt:

	using namespace UE::DiffWriter::Tests;

	const int32 MaxDiffsToLog = 1000;
	bool bIgnoreHeaderDiffs = false;
	FName PackageName(TEXT("PackageName"));
	EPackageHeaderFormat HeaderFormat(EPackageHeaderFormat::PackageFileSummary);
	UE::DiffWriter::FAccumulatorGlobals AccumulatorGlobals;

	TRefCountPtr<FAccumulator> Accumulator = new FAccumulator(AccumulatorGlobals, nullptr, PackageName, MaxDiffsToLog,
		bIgnoreHeaderDiffs, [](ELogVerbosity::Type Verbosity, FStringView Message) {}, HeaderFormat);
	FBasicDiffState State = FBasicDiffState{ 1,2,3 };
	FDiffArchiveForLinker Ar(*Accumulator);

	State.Serialize(Ar);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Tests/DiffWriterArchiveTests.cpp:83

Scope (from outer to inner):

file
function     bool FDiffWriterArchiveTestsBasic::RunTest

Source code excerpt:

	using namespace UE::DiffWriter::Tests;

	const int32 MaxDiffsToLog = 1000;
	bool bIgnoreHeaderDiffs = false;
	FName PackageName(TEXT("PackageName"));
	FString Filename(TEXT("Filename"));
	EPackageHeaderFormat HeaderFormat(EPackageHeaderFormat::PackageFileSummary);
	UE::DiffWriter::FAccumulatorGlobals AccumulatorGlobals;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Tests/DiffWriterArchiveTests.cpp:93

Scope (from outer to inner):

file
function     bool FDiffWriterArchiveTestsBasic::RunTest

Source code excerpt:

	{
		TRefCountPtr<FAccumulator> Accumulator = new FAccumulator(AccumulatorGlobals, nullptr, PackageName,
			MaxDiffsToLog, bIgnoreHeaderDiffs,
			[](ELogVerbosity::Type Verbosity, FStringView Message) {}, HeaderFormat);

		FLargeMemoryWriter InitialState;
		{
			FBasicDiffState State = FBasicDiffState {1,2,3};
			State.Serialize(InitialState);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Tests/DiffWriterArchiveTests.cpp:117

Scope (from outer to inner):

file
function     bool FDiffWriterArchiveTestsBasic::RunTest

Source code excerpt:

	{
		TRefCountPtr<FAccumulator> Accumulator = new FAccumulator(AccumulatorGlobals, nullptr, PackageName,
			MaxDiffsToLog, bIgnoreHeaderDiffs,
			[](ELogVerbosity::Type Verbosity, FStringView Message) {}, HeaderFormat);

		FLargeMemoryWriter InitialState;
		{
			FBasicDiffState State = FBasicDiffState {1,2,3};
			State.Serialize(InitialState);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Tests/DiffWriterArchiveTests.cpp:141

Scope (from outer to inner):

file
function     bool FDiffWriterArchiveTestsBasic::RunTest

Source code excerpt:

	{
		TRefCountPtr<FAccumulator> Accumulator = new FAccumulator(AccumulatorGlobals, nullptr, PackageName,
			MaxDiffsToLog, bIgnoreHeaderDiffs,
			[](ELogVerbosity::Type Verbosity, FStringView Message) {}, HeaderFormat);

		FBasicDiffState InitialState = FBasicDiffState {1,2,3};
		FLargeMemoryWriter InitialMemory;
		InitialMemory.SetByteSwapping(false);
		InitialState.Serialize(InitialMemory);

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:732

Scope (from outer to inner):

file
function     void FArchiveStackTraceWriter::Compare

Source code excerpt:

	const TCHAR* AssetFilename,
	const TCHAR* CallstackCutoffText,
	const int64 MaxDiffsToLog,
	int32& InOutDiffsLogged,
	TMap<FName, FArchiveDiffStats>& OutStats,
	bool bSuppressLogging)
{
#if !NO_LOGGING
	const TCHAR* const Indent = FDiffFormatHelper::Get().Indent;

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:811

Scope (from outer to inner):

file
function     void FArchiveStackTraceWriter::Compare

Source code excerpt:

			};

			if (!CallstackAtOffset.bIgnore && (MaxDiffsToLog < 0 || InOutDiffsLogged < MaxDiffsToLog))
			{
				FString BeforePropertyVal;
				FString AfterPropertyVal;
				if (FProperty* SerProp = DifferenceCallstackData.SerializedProp)
				{
					if (SourceSize == DestSize && ShouldDumpPropertyValueState(SerProp))

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:938

Scope (from outer to inner):

file
function     void FArchiveStackTraceWriter::Compare

Source code excerpt:

	}

	if (MaxDiffsToLog >= 0 && NumDiffsLocal > NumDiffsLoggedLocal)
	{
		if (FirstUnreportedDiffIndex != -1)
		{
			UE_CLOG(!bSuppressLogging, LogArchiveDiff, Warning, TEXT("%s: %lld difference(s) not logged (first at absolute offset: %lld)."), AssetFilename, NumDiffsLocal - NumDiffsLoggedLocal, FirstUnreportedDiffIndex);
		}
		else

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:952

Scope (from outer to inner):

file
function     void FArchiveStackTrace::CompareWith

Source code excerpt:

}

void FArchiveStackTrace::CompareWith(const TCHAR* InFilename, const int64 TotalHeaderSize, const TCHAR* CallstackCutoffText, const int32 MaxDiffsToLog, TMap<FName, FArchiveDiffStats>& OutStats)
{
	TUniquePtr<uint8, UE::ArchiveStackTrace::FDeleteByFree> SourcePackageBytes;
	FPackageData SourcePackage;
	LoadPackageIntoMemory(InFilename, SourcePackage, SourcePackageBytes);
	CompareWith(SourcePackage, InFilename, TotalHeaderSize, CallstackCutoffText, MaxDiffsToLog, OutStats);
}

void FArchiveStackTrace::CompareWith(const FPackageData& SourcePackage, const TCHAR* FileDisplayName, const int64 TotalHeaderSize,
	const TCHAR* CallstackCutoffText, const int32 MaxDiffsToLog, TMap<FName, FArchiveDiffStats>&OutStats,
	const FArchiveStackTraceWriter::EPackageHeaderFormat PackageHeaderFormat /* = FArchiveStackTraceWriter::EPackageHeaderFormat::PackageFileSummary */)
{
	const FName AssetClass = Callstacks.GetAssetClass();
	OutStats.FindOrAdd(AssetClass).NewFileTotalSize = TotalSize();
	if (SourcePackage.Size == 0)
	{

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:994

Scope (from outer to inner):

file
function     void FArchiveStackTrace::CompareWith

Source code excerpt:

	DestPackageHeader.StartOffset = 0;

	FArchiveStackTraceWriter::Compare(SourcePackageHeader, DestPackageHeader, Callstacks, StackTraceWriter.GetDiffMap(), FileDisplayName, CallstackCutoffText, MaxDiffsToLog, NumLoggedDiffs, OutStats);

	if (TotalHeaderSize > 0 && OutStats.FindOrAdd(AssetClass).NumDiffs > 0)
	{
		FArchiveStackTraceWriter::DumpPackageHeaderDiffs(SourcePackage, DestPackage, FileDisplayName, MaxDiffsToLog, PackageHeaderFormat);
	}

	FPackageData SourcePackageExports = SourcePackage;
	SourcePackageExports.HeaderSize = 0;
	SourcePackageExports.StartOffset = SourcePackage.HeaderSize;

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:1019

Scope (from outer to inner):

file
function     void FArchiveStackTrace::CompareWith

Source code excerpt:

	}

	FArchiveStackTraceWriter::Compare(SourcePackageExports, DestPackageExports, Callstacks, StackTraceWriter.GetDiffMap(), *AssetName, CallstackCutoffText, MaxDiffsToLog, NumLoggedDiffs, OutStats);

	// Optionally save out any differences we detected.
	const FArchiveDiffStats& Stats = OutStats.FindOrAdd(AssetClass);
	if (Stats.NumDiffs > 0)
	{
		static struct FDiffOutputSettings

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:1507

Scope (from outer to inner):

file
function     static void DumpTableDifferences

Source code excerpt:

	const TCHAR* AssetFilename,
	const TCHAR* ItemName,
	const int32 MaxDiffsToLog
)
{
#if !NO_LOGGING
	const TCHAR* const LineTerminator = FDiffFormatHelper::Get().LineTerminator;
	const TCHAR* const Indent = FDiffFormatHelper::Get().Indent;

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:1570

Scope (from outer to inner):

file
function     static void DumpTableDifferences

Source code excerpt:

	}

	// For now just log everything out. When this becomes too spammy, respect the MaxDiffsToLog parameter
	NumDiffs = RemovedItems.Num() + AddedItems.Num();
	LoggedDiffs = NumDiffs;

	if (NumDiffs > LoggedDiffs)
	{
		HumanReadableString += Indent;

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:1600

Scope (from outer to inner):

file
function     static void DumpPackageHeaderDiffs_LinkerLoad

Source code excerpt:

	const FArchiveStackTraceWriter::FPackageData& DestPackage,
	const FString& AssetFilename,
	const int32 MaxDiffsToLog)
{
#if !NO_LOGGING
	FString AssetPathName = FPaths::Combine(*FPaths::GetPath(AssetFilename.Mid(AssetFilename.Find(TEXT(":"), ESearchCase::CaseSensitive) + 1)), *FPaths::GetBaseFilename(AssetFilename));
	// The root directory could have a period in it (d:/Release5.0/EngineTest/Saved/Cooked),
	// which is not a valid character for a LongPackageName. Remove it.
	for (TCHAR c : FStringView(INVALID_LONGPACKAGE_CHARACTERS))

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:1639

Scope (from outer to inner):

file
function     static void DumpPackageHeaderDiffs_LinkerLoad

Source code excerpt:

		if (SourceLinker->NameMap != DestLinker->NameMap)
		{
			DumpTableDifferences<FNameEntryId>(SourceLinker, DestLinker, SourceLinker->NameMap, DestLinker->NameMap, *AssetFilename, TEXT("Name"), MaxDiffsToLog);
		}

		if (!IsImportMapIdentical(SourceLinker, DestLinker))
		{
			DumpTableDifferences<FObjectImport>(SourceLinker, DestLinker, SourceLinker->ImportMap, DestLinker->ImportMap, *AssetFilename, TEXT("Import"), MaxDiffsToLog);
		}

		if (!IsExportMapIdentical(SourceLinker, DestLinker))
		{
			DumpTableDifferences<FObjectExport>(SourceLinker, DestLinker, SourceLinker->ExportMap, DestLinker->ExportMap, *AssetFilename, TEXT("Export"), MaxDiffsToLog);
		}
	}

	if (SourceLinker)
	{
		UE::ArchiveStackTrace::ForceKillPackageAndLinker(SourceLinker);

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:1668

Scope (from outer to inner):

file
function     static void DumpPackageHeaderDiffs_ZenPackage

Source code excerpt:

	const FArchiveStackTraceWriter::FPackageData& DestPackage,
	const FString& AssetFilename,
	const int32 MaxDiffsToLog)
{
#if !NO_LOGGING
	// TODO: Fill in detailed diffing of Zen Package Summary
#endif // !NO_LOGGING
}

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Private/Serialization/ArchiveStackTrace.cpp:1679

Scope (from outer to inner):

file
function     void FArchiveStackTraceWriter::DumpPackageHeaderDiffs

Source code excerpt:

	const FPackageData& DestPackage,
	const FString& AssetFilename,
	const int32 MaxDiffsToLog,
	const EPackageHeaderFormat PackageHeaderFormat /* = EPackageHeaderFormat::PackageFileSummary */)
{
#if !NO_LOGGING
	switch (PackageHeaderFormat)
	{
	case EPackageHeaderFormat::PackageFileSummary:
		DumpPackageHeaderDiffs_LinkerLoad(SourcePackage, DestPackage, AssetFilename, MaxDiffsToLog);
		break;
	case EPackageHeaderFormat::ZenPackageSummary:
		DumpPackageHeaderDiffs_ZenPackage(SourcePackage, DestPackage, AssetFilename, MaxDiffsToLog);
		break;
	default:
		unimplemented();
	}
#endif // !NO_LOGGING
}

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Public/Serialization/ArchiveStackTrace.h:319

Scope (from outer to inner):

file
class        class /*EPRECATED(5.3, "FArchiveStackTrace was only used by DiffPackageWriter, and has been moved into a private helper class. Contact Epic if you need this class for another reason.")*/ FArchiveStackTraceWriter : public FArchiveProxy

Source code excerpt:

		const TCHAR* AssetFilename,
		const TCHAR* CallstackCutoffText,
		const int64 MaxDiffsToLog,
		int32& InOutDiffsLogged,
		TMap<FName, FArchiveDiffStats>& OutStats,
		bool bSuppressLogging = false);

	/** Creates map with mismatching callstacks. */
	static COREUOBJECT_API bool GenerateDiffMap(

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Public/Serialization/ArchiveStackTrace.h:337

Scope (from outer to inner):

file
class        class /*EPRECATED(5.3, "FArchiveStackTrace was only used by DiffPackageWriter, and has been moved into a private helper class. Contact Epic if you need this class for another reason.")*/ FArchiveStackTraceWriter : public FArchiveProxy

Source code excerpt:

		const FPackageData& DestPackage,
		const FString& AssetFilename,
		const int32 MaxDiffsToLog,
		const EPackageHeaderFormat PackageHeaderFormat = EPackageHeaderFormat::PackageFileSummary);

	/** Returns a new linker for loading the specified package. */
	static COREUOBJECT_API FLinkerLoad* CreateLinkerForPackage(
		FUObjectSerializeContext* LoadContext,
		const FString& InPackageName,

#Loc: <Workspace>/Engine/Source/Runtime/CoreUObject/Public/Serialization/ArchiveStackTrace.h:422

Scope (from outer to inner):

file
class        class /*EPRECATED(5.3, "FArchiveStackTrace was only used by DiffPackageWriter, and has been moved into a private helper class. Contact Epic if you need this class for another reason.")*/ FArchiveStackTrace : public FLargeMemoryWriter

Source code excerpt:

	/** Compares this archive with the given bytes from disk or FPackageData. Dumps all differences to log. */
	COREUOBJECT_API void CompareWith(const TCHAR* InFilename, const int64 TotalHeaderSize, const TCHAR* CallstackCutoffText,
		const int32 MaxDiffsToLog, TMap<FName, FArchiveDiffStats>& OutStats);
	COREUOBJECT_API void CompareWith(const FPackageData& SourcePackage, const TCHAR* FileDisplayName, const int64 TotalHeaderSize,
		const TCHAR* CallstackCutoffText, const int32 MaxDiffsToLog, TMap<FName, FArchiveDiffStats>& OutStats,
		const FArchiveStackTraceWriter::EPackageHeaderFormat PackageHeaderFormat = FArchiveStackTraceWriter::EPackageHeaderFormat::PackageFileSummary);

	/** Generates a map of all differences between this archive and the given bytes from disk or FPackageData. */
	COREUOBJECT_API bool GenerateDiffMap(const TCHAR* InFilename, int64 TotalHeaderSize, int32 MaxDiffsToFind, FArchiveDiffMap& OutDiffMap);
	COREUOBJECT_API bool GenerateDiffMap(const FPackageData& SourcePackage, int64 TotalHeaderSize, int32 MaxDiffsToFind,
		FArchiveDiffMap& OutDiffMap);