ProjectID

ProjectID

#Overview

name: ProjectID

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 24 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of ProjectID is to provide a unique identifier for the project. This setting variable is primarily used for project identification and tracking across various Unreal Engine subsystems and tools. Here’s a detailed breakdown:

  1. Unreal Engine subsystems that rely on this variable:

    • Analytics systems (Engine analytics, Editor analytics)
    • Project generation and management
    • Blueprint editor
    • Studio Telemetry
  2. The value of this variable is typically set when a new project is created. It’s generated as a new GUID (Globally Unique Identifier) during project creation and stored in the project’s configuration files.

  3. Other variables that interact with ProjectID:

    • ProjectName
    • ProjectVersion
    • Other project-related settings in the GeneralProjectSettings class
  4. Special considerations for developers:

    • ProjectID should remain constant throughout the project’s lifecycle.
    • It’s used for analytics and tracking, so changing it may affect data consistency.
    • It’s stored in the project’s configuration files, so manual editing of these files should be done carefully.
  5. Best practices:

    • Don’t modify the ProjectID manually unless absolutely necessary.
    • When cloning or forking a project, generate a new ProjectID to avoid conflicts.
    • Use the ProjectID when integrating with external tools or services that need to uniquely identify the project.
    • Include the ProjectID in crash reports or bug submissions to help with issue tracking.

The ProjectID is a crucial identifier for your Unreal Engine project, used across various engine systems for tracking, analytics, and project management. It’s automatically generated and managed by the engine, so in most cases, developers don’t need to interact with it directly.

#Setting Variables

#References In INI files

Location: <Workspace>/Projects/Lyra/Config/DefaultGame.ini:4, section: [/Script/EngineSettings.GeneralProjectSettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Experimental/StudioTelemetry/Source/StudioTelemetry/Private/StudioTelemetry.cpp:103

Scope (from outer to inner):

file
function     void FStudioTelemetry::StartSession

Source code excerpt:

		
		FString ProjectIDString;
		GConfig->GetString(TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectID"), ProjectIDString, GGameIni);

		FGuid ProjectID;

		TArray<FString> Elements;
		if (ProjectIDString.ParseIntoArray(Elements, TEXT("=")) == 5) 
		{
			ProjectID = FGuid(FCString::Atoi(*(Elements[1])), FCString::Atoi(*(Elements[2])), FCString::Atoi(*(Elements[3])), FCString::Atoi(*(Elements[4])));
		}

		FGuid SessionID;
		FPlatformMisc::CreateGuid(SessionID);
		
		FString SessionLabel;

#Loc: <Workspace>/Engine/Plugins/Experimental/StudioTelemetry/Source/StudioTelemetry/Private/StudioTelemetry.cpp:121

Scope (from outer to inner):

file
function     void FStudioTelemetry::StartSession

Source code excerpt:

		// Set the default event attributes	
		DefaultEventAttributes.Emplace(TEXT("ProjectName"), ProjectName);
		DefaultEventAttributes.Emplace(TEXT("ProjectID"), ProjectID);

		DefaultEventAttributes.Emplace(TEXT("Session_ID"), SessionID.ToString(EGuidFormats::DigitsWithHyphensInBraces));
		DefaultEventAttributes.Emplace(TEXT("Session_Label"), SessionLabel);
		DefaultEventAttributes.Emplace(TEXT("Session_StartUTC"), FDateTime::UtcNow().ToUnixTimestampDecimal());

		DefaultEventAttributes.Emplace(TEXT("Build_Configuration"), LexToString(FApp::GetBuildConfiguration()));

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:836

Scope (from outer to inner):

file
function     bool GameProjectUtils::CreateProject

Source code excerpt:

	SlowTask.MakeDialog();

	TOptional<FGuid> ProjectID;
	FString TemplateName;
	if ( InProjectInfo.TemplateFile.IsEmpty() )
	{
		ProjectID = GenerateProjectFromScratch(InProjectInfo, OutFailReason, OutFailLog);
		TemplateName = InProjectInfo.bShouldGenerateCode ? TEXT("Basic Code") : TEXT("Blank");
	}
	else
	{
		ProjectID = CreateProjectFromTemplate(InProjectInfo, OutFailReason, OutFailLog, OutCreatedFiles);
		TemplateName = FPaths::GetBaseFilename(InProjectInfo.TemplateFile);
	}

	bool bProjectCreationSuccessful = ProjectID.IsSet();

	if (!bProjectCreationSuccessful && CleanupIsEnabled())
	{
		// Delete the new project folder
		const FString NewProjectFolder = FPaths::GetPath(InProjectInfo.ProjectFilename);
		IFileManager::Get().DeleteDirectory(*NewProjectFolder, /*RequireExists=*/false, /*Tree=*/true);

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:869

Scope (from outer to inner):

file
function     bool GameProjectUtils::CreateProject

Source code excerpt:

		EventAttributes.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), InProjectInfo.bShouldGenerateCode ? TEXT("C++ Code") : TEXT("Content Only")));
		EventAttributes.Add(FAnalyticsEventAttribute(TEXT("Outcome"), bProjectCreationSuccessful ? TEXT("Successful") : TEXT("Failed")));
		EventAttributes.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), *(bProjectCreationSuccessful ? ProjectID.GetValue().ToString() : FString())));

		if (InProjectInfo.TargetedHardware.IsSet())
		{
			UEnum* HardwareClassEnum = StaticEnum<EHardwareClass>();
			if (HardwareClassEnum != nullptr)
			{

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1379

Scope (from outer to inner):

file
function     TOptional<FGuid> GameProjectUtils::GenerateProjectFromScratch

Source code excerpt:

	ResetCurrentProjectModulesCache();

	FGuid ProjectID;
	// Generate config files
	if (!GenerateConfigFiles(InProjectInfo, CreatedFiles, OutFailReason, ProjectID))
	{
		return TOptional<FGuid>();
	}

	// Insert any required feature packs (EG starter content) into ini file. These will be imported automatically when the editor is first run
	if(!InsertFeaturePacksIntoINIFile(InProjectInfo, OutFailReason))

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1484

Scope (from outer to inner):

file
function     TOptional<FGuid> GameProjectUtils::GenerateProjectFromScratch

Source code excerpt:


	UE_LOG(LogGameProjectGeneration, Log, TEXT("Created new project with %d files (plus project files)"), CreatedFiles.Num());
	return ProjectID;
}

static bool SaveConfigValues(const FProjectInformation& InProjectInfo, const TArray<FTemplateConfigValue>& ConfigValues, FText& OutFailReason)
{
	const FString ProjectConfigPath = FPaths::GetPath(InProjectInfo.ProjectFilename) / TEXT("Config");

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1824

Scope (from outer to inner):

file
function     TOptional<FGuid> GameProjectUtils::CreateProjectFromTemplate

Source code excerpt:

	TemplateDefs->AddConfigValues(ConfigValuesToSet, TemplateName, ProjectName, InProjectInfo.bShouldGenerateCode);

	FGuid ProjectID = FGuid::NewGuid();
	ConfigValuesToSet.Emplace(TEXT("DefaultGame.ini"), TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectID"), ProjectID.ToString(), /*InShouldReplaceExistingValue=*/true);

	// Add all classname fixups
	for (const TPair<FString, FString>& Rename : ClassRenames)
	{
		const FString ClassRedirectString = FString::Printf(TEXT("(OldClassName=\"%s\",NewClassName=\"%s\")"), *Rename.Key, *Rename.Value);
		ConfigValuesToSet.Emplace(TEXT("DefaultEngine.ini"), TEXT("/Script/Engine.Engine"), TEXT("+ActiveClassRedirects"), *ClassRedirectString, /*InShouldReplaceExistingValue=*/false);

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1919

Scope (from outer to inner):

file
function     TOptional<FGuid> GameProjectUtils::CreateProjectFromTemplate

Source code excerpt:

	}

	return ProjectID;
}

bool GameProjectUtils::SetEngineAssociationForForeignProject(const FString& ProjectFileName, FText& OutFailReason)
{
	if(FUProjectDictionary(FPaths::RootDir()).IsForeignProject(ProjectFileName))
	{

#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:926

Scope (from outer to inner):

file
function     void FBlueprintEditor::AnalyticsTrackNodeEvent

Source code excerpt:

		// Build Node Details
		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		FString ProjectID = ProjectSettings.ProjectID.ToString();
		TArray<FAnalyticsEventAttribute> NodeAttributes;
		NodeAttributes.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));
		NodeAttributes.Add(FAnalyticsEventAttribute(TEXT("BlueprintId"), Blueprint->GetBlueprintGuid().ToString()));
		TArray<TKeyValuePair<FString, FString>> Attributes;

		if (UK2Node* K2Node = Cast<UK2Node>(GraphNode))
		{
			K2Node->GetNodeAttributes(Attributes);

#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:966

Scope (from outer to inner):

file
function     void FBlueprintEditor::AnalyticsTrackCompileEvent

Source code excerpt:

		// Build Node Details
		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		FString ProjectID = ProjectSettings.ProjectID.ToString();

		const bool bSuccess = NumErrors == 0;
		TArray<FAnalyticsEventAttribute> Attributes;
		Attributes.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));
		Attributes.Add(FAnalyticsEventAttribute(TEXT("BlueprintId"), Blueprint->GetBlueprintGuid().ToString()));
		Attributes.Add(FAnalyticsEventAttribute(TEXT("Success"), bSuccess? TEXT("True") : TEXT("False")));
		Attributes.Add(FAnalyticsEventAttribute(TEXT("NumErrors"), FString::FromInt(NumErrors)));
		Attributes.Add(FAnalyticsEventAttribute(TEXT("NumWarnings"), FString::FromInt(NumWarnings)));

		// Send Analytics event 

#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:2897

Scope (from outer to inner):

file
function     FBlueprintEditor::~FBlueprintEditor

Source code excerpt:

	{
		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		FString ProjectID = ProjectSettings.ProjectID.ToString();

		TArray<FAnalyticsEventAttribute> BPEditorAttribs;
		BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("GraphActionMenusExecuted.NonContextSensitive"), AnalyticsStats.GraphActionMenusNonCtxtSensitiveExecCount));
		BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("GraphActionMenusExecuted.ContextSensitive"), AnalyticsStats.GraphActionMenusCtxtSensitiveExecCount));
		BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("GraphActionMenusClosed"), AnalyticsStats.GraphActionMenusCancelledCount));

#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:2911

Scope (from outer to inner):

file
function     FBlueprintEditor::~FBlueprintEditor

Source code excerpt:

		BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("PastedNodesCreated"), AnalyticsStats.NodePasteCreateCount));

		BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));
		FEngineAnalytics::GetProvider().RecordEvent(TEXT("Editor.Usage.BlueprintEditorSummary"), BPEditorAttribs);

		for (auto Iter = AnalyticsStats.GraphDisallowedPinConnections.CreateConstIterator(); Iter; ++Iter)
		{
			TArray<FAnalyticsEventAttribute> BPEditorPinConnectAttribs;
			BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("FromPin.Category"), Iter->PinTypeCategoryA));

#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:2925

Scope (from outer to inner):

file
function     FBlueprintEditor::~FBlueprintEditor

Source code excerpt:

			BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("ToPin.IsReference"), Iter->bPinIsReferenceB));
			BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("ToPin.IsWeakPointer"), Iter->bPinIsWeakPointerB));
			BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));

			FEngineAnalytics::GetProvider().RecordEvent(TEXT("Editor.Usage.BPDisallowedPinConnection"), BPEditorPinConnectAttribs);
		}
	}

	SaveEditorSettings();

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Analytics/EditorAnalytics.cpp:25

Scope (from outer to inner):

file
function     void FEditorAnalytics::ReportEvent

Source code excerpt:

		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		TArray<FAnalyticsEventAttribute> ParamArray;
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString()));
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("Platform"), PlatformName));
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), bHasCode ? TEXT("C++ Code") : TEXT("Content Only")));
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("VanillaEditor"), (GEngine && GEngine->IsVanillaProduct()) ? TEXT("Yes") : TEXT("No")));
		ParamArray.Append(ExtraParams);

		FEngineAnalytics::GetProvider().RecordEvent( EventName, ParamArray );

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Analytics/EditorAnalytics.cpp:41

Scope (from outer to inner):

file
function     void FEditorAnalytics::ReportEvent

Source code excerpt:

		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		TArray<FAnalyticsEventAttribute> ParamArray;
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString()));
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("Platform"), PlatformName));
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), bHasCode ? TEXT("C++ Code") : TEXT("Content Only")));
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("VanillaEditor"), (GEngine && GEngine->IsVanillaProduct()) ? TEXT("Yes") : TEXT("No")));
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("ErrorCode"), ErrorCode));
		const FString ErrorMessage = TranslateErrorCode(ErrorCode);
		ParamArray.Add(FAnalyticsEventAttribute(TEXT("ErrorName"), ErrorMessage));

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Kismet2/Kismet2.cpp:593

Scope (from outer to inner):

file
function     UBlueprint* FKismetEditorUtilities::CreateBlueprint

Source code excerpt:


		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		Attribs.Add(FAnalyticsEventAttribute(FString("ProjectId"), ProjectSettings.ProjectID.ToString()));
		Attribs.Add(FAnalyticsEventAttribute(FString("BlueprintId"), NewBP->GetBlueprintGuid().ToString()));

		FEngineAnalytics::GetProvider().RecordEvent(FString("Editor.Usage.BlueprintCreated"), Attribs);
	}

	return NewBP;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:657

Scope (from outer to inner):

file
function     void FUnrealEdMisc::InitEngineAnalytics

Source code excerpt:

			TArray< FAnalyticsEventAttribute > ProjectAttributes;
			ProjectAttributes.Add( FAnalyticsEventAttribute( FString( "Name" ), *GetDefault<UGeneralProjectSettings>()->ProjectName ));
			ProjectAttributes.Add( FAnalyticsEventAttribute( FString( "Id" ), *GetDefault<UGeneralProjectSettings>()->ProjectID.ToString() ));

			FGameProjectGenerationModule& GameProjectModule = FModuleManager::LoadModuleChecked<FGameProjectGenerationModule>(TEXT("GameProjectGeneration"));
			
			bool bShouldIncludeSourceFileCountAndSize = true;
			GConfig->GetBool(TEXT("EngineAnalytics"), TEXT("IncludeSourceFileCountAndSize"), bShouldIncludeSourceFileCountAndSize, GEditorIni);
			if (bShouldIncludeSourceFileCountAndSize)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:873

Scope (from outer to inner):

file
function     void FUnrealEdMisc::TickAssetAnalytics

Source code excerpt:

			}
			const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
			AssetAttributes.Add( FAnalyticsEventAttribute( FString( "ProjectId" ), *ProjectSettings.ProjectID.ToString() ));
			AssetAttributes.Add( FAnalyticsEventAttribute( FString( "AssetPackageCount" ), PackageNames.Num() ));
			AssetAttributes.Add( FAnalyticsEventAttribute( FString( "Maps" ), NumMapFiles ));
			AssetAttributes.Emplace( TEXT("Enterprise"), IProjectManager::Get().IsEnterpriseProject() );

			// Send project analytics
			FEngineAnalytics::GetProvider().RecordEvent( FString( "Editor.Usage.AssetCounts" ), AssetAttributes );

			TArray< FAnalyticsEventAttribute > AssetInstances;
			AssetInstances.Add( FAnalyticsEventAttribute( FString( "ProjectId" ), *ProjectSettings.ProjectID.ToString() ));
			for( auto ClassIter = ClassInstanceCounts.CreateIterator(); ClassIter; ++ClassIter )
			{
				AssetInstances.Add( FAnalyticsEventAttribute( ClassIter.Key().ToString(), ClassIter.Value() ) );
			}
			// Send class instance analytics
			FEngineAnalytics::GetProvider().RecordEvent( FString( "Editor.Usage.AssetClasses" ), AssetInstances );

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:1018

Scope (from outer to inner):

file
function     void FUnrealEdMisc::OnExit

Source code excerpt:


		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		TabsAttribs.Add(FAnalyticsEventAttribute(FString("ProjectId"), ProjectSettings.ProjectID.ToString()));

		FEngineAnalytics::GetProvider().RecordEvent(FString("Editor.Usage.WindowCounts"), TabsAttribs);
		
		// Report asset updates (to reflect forward progress made by the user)
		TArray<FAnalyticsEventAttribute> AssetUpdateCountAttribs;
		for (auto& UpdatedAssetPair : NumUpdatesByAssetName)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:1199

Scope (from outer to inner):

file
function     void FUnrealEdMisc::PreSaveWorld

Source code excerpt:

	BrushAttributes.Add( FAnalyticsEventAttribute( FString( "Subtractive" ), NumSubtractiveBrushes ));
	const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
	BrushAttributes.Add( FAnalyticsEventAttribute( FString( "ProjectId" ), ProjectSettings.ProjectID.ToString()) );

	FEngineAnalytics::GetProvider().RecordEvent( FString( "Editor.Usage.Brushes" ), BrushAttributes );
}

void FUnrealEdMisc::CB_MapChange( uint32 InFlags )
{

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:1268

Scope (from outer to inner):

file
function     void FUnrealEdMisc::CB_LevelActorsAdded

Source code excerpt:

	{
		const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
		FEngineAnalytics::GetProvider().RecordEvent(FString("Editor.Usage.PawnPlacement"), FString( "ProjectId" ), ProjectSettings.ProjectID.ToString());
	}
}

void FUnrealEdMisc::CB_PreAutomationTesting()
{
	// Shut down SCC if it's enabled, as unit tests shouldn't be allowed to make any modifications to source control

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Analytics/EngineAnalyticsSessionSummary.cpp:180

Scope (from outer to inner):

file
function     FEngineAnalyticsSessionSummary::FEngineAnalyticsSessionSummary

Source code excerpt:

	Store->Set(TEXT("GRHIAdapterMemory"), static_cast<uint64>(TextureMemStats.DedicatedVideoMemory));
	Store->Set(TEXT("ProjectName"), EngineAnalyticsProperties::GetProjectName(ProjectSettings));
	Store->Set(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString(EGuidFormats::DigitsWithHyphens));
	Store->Set(TEXT("ProjectDescription"), ProjectSettings.Description);
	Store->Set(TEXT("ProjectVersion"), ProjectSettings.ProjectVersion);
	Store->Set(TEXT("EngineVersion"), FEngineVersion::Current().ToString(EVersionComponent::Changelist));
	Store->Set(TEXT("CommandLine"), FString(FCommandLine::GetForLogging()));
	Store->Set(TEXT("MonitorPid"), CrcProcessId); // CrashReportClient acts as the monitoring/reporting process.
	Store->Set(TEXT("Plugins"), FString::Join(PluginNames, TEXT(",")));

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/EngineAnalytics.cpp:248

Scope (from outer to inner):

file
function     void FEngineAnalytics::AppendMachineStats

Source code excerpt:

	// Add project info whether we are in editor or game.
	EventAttributes.Emplace(TEXT("ProjectName"), ProjectSettings.ProjectName);
	EventAttributes.Emplace(TEXT("ProjectID"), ProjectSettings.ProjectID);
	EventAttributes.Emplace(TEXT("ProjectDescription"), ProjectSettings.Description);
	EventAttributes.Emplace(TEXT("ProjectVersion"), ProjectSettings.ProjectVersion);
	EventAttributes.Emplace(TEXT("Application.Commandline"), FCommandLine::Get());
	EventAttributes.Emplace(TEXT("Build.Configuration"), LexToString(FApp::GetBuildConfiguration()));
	EventAttributes.Emplace(TEXT("Build.IsInternalBuild"), FEngineBuildSettings::IsInternalBuild());
	EventAttributes.Emplace(TEXT("Build.IsPerforceBuild"), FEngineBuildSettings::IsPerforceBuild());

#Loc: <Workspace>/Engine/Source/Runtime/EngineSettings/Classes/GeneralProjectSettings.h:45

Scope (from outer to inner):

file
class        class UGeneralProjectSettings : public UObject

Source code excerpt:

	/** The project's unique identifier. */
	UPROPERTY(config, EditAnywhere, Category=About)
	FGuid ProjectID;

	/** The project's non-localized name. */
	UPROPERTY(config, EditAnywhere, Category=About)
	FString ProjectName;

	/** The project's version number. */