bSendUsageData

bSendUsageData

#Overview

name: bSendUsageData

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

#Summary

#Usage in the C++ source code

The purpose of bSendUsageData is to determine whether the editor or application should send usage information to Epic Games for the purpose of improving Unreal Engine. This setting is part of the analytics and privacy configuration in Unreal Engine.

Based on the provided code references, this variable is primarily used in the following Unreal Engine subsystems and modules:

  1. Analytics system
  2. Crash reporting system
  3. Editor settings

The value of this variable is typically set in the following ways:

  1. Through the engine configuration files, specifically in the BaseEditorSettings.ini file.
  2. It can be modified through the Editor UI, as it’s exposed as an editable property in the UAnalyticsPrivacySettings class.
  3. It may be overridden programmatically in certain scenarios, such as for licensee builds or dedicated servers.

This variable often interacts with other privacy-related settings, such as:

  1. bSendUnattendedBugReports
  2. bNoDialog
  3. bImplicitSend

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

  1. It affects the collection and transmission of usage data, which is used to improve Unreal Engine.
  2. It has implications for crash reporting and analytics in both editor and runtime scenarios.
  3. Its default value may differ between editor and non-editor builds, especially for licensee versions.

Best practices when using this variable include:

  1. Respect user privacy by clearly communicating what data is collected when this setting is enabled.
  2. Ensure that the default value in configuration files aligns with your project’s privacy policy.
  3. Consider the implications of this setting on crash reporting and adjust your error handling accordingly.
  4. For licensee versions, carefully consider whether to allow usage data collection, especially in non-editor builds.
  5. Regularly review and update privacy settings to comply with relevant data protection regulations.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditorSettings.ini:17, section: [/Script/UnrealEd.AnalyticsPrivacySettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Analytics/AnalyticsPrivacySettings.h:22

Scope (from outer to inner):

file
class        class UAnalyticsPrivacySettings : public UObject, public IImportantToggleSettingInterface

Source code excerpt:

	/** Determines whether the editor sends usage information to Epic Games in order to improve Unreal Engine. Your information will never be shared with 3rd parties. */
	UPROPERTY(EditAnywhere, config, Category=Options)
	bool bSendUsageData;

	/** Determines whether the editor asks for your industry and sends that information to Epic Games in order to improve Unreal Engine. Your information will never be shared with 3rd parties. 
	* As Unreal Engine is used across a range of industries, we want to make sure we are addressing the needs of those verticals. A one-time prompt will show up for a user asking if they 
	* are using the editor for the field of: Game Development, Film & TV, Architecture, Automotive & Manufacturing, Broadcasting & Live Events, Advertising & Marketing, Simulation & Training, or Other.
	* 
	* If you would like to block the prompt from showing up for members of your team, but otherwise send usage data back to Epic Games, you can add the following to your BaseEditorSettings.ini:

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Analytics/AnalyticsPrivacySettings.cpp:10

Scope (from outer to inner):

file
function     UAnalyticsPrivacySettings::UAnalyticsPrivacySettings

Source code excerpt:

UAnalyticsPrivacySettings::UAnalyticsPrivacySettings(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
	, bSendUsageData(true)
{
}

void UAnalyticsPrivacySettings::GetToggleCategoryAndPropertyNames(FName& OutCategory, FName& OutProperty) const
{
	OutCategory = FName("Options");

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Analytics/AnalyticsPrivacySettings.cpp:66

Scope (from outer to inner):

file
function     void UAnalyticsPrivacySettings::PostEditChangeProperty

Source code excerpt:


	const FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
	if (PropertyName == GET_MEMBER_NAME_CHECKED(UAnalyticsPrivacySettings, bSendUsageData))
	{
		OnSendFullUsageDataChanged();

		FCrashOverrideParameters Params;
		Params.bSetCrashReportClientMessageText = false;
		Params.bSetGameNameSuffix = false;
		Params.SendUsageData = bSendUsageData;

		FCoreDelegates::CrashOverrideParamsChanged.Broadcast(Params);
	}
}

void UAnalyticsPrivacySettings::OnSendFullUsageDataChanged()
{
	if (bSendUsageData)
	{
		// Attempt to initialize analytics and send opt-in event
		if (!FEngineAnalytics::IsAvailable())
		{
			FEngineAnalytics::Initialize();
			if (FEngineAnalytics::IsAvailable())

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp:1217

Scope (from outer to inner):

file
function     bool UEditorEngine::AreEditorAnalyticsEnabled

Source code excerpt:

bool UEditorEngine::AreEditorAnalyticsEnabled() const 
{
	return GetDefault<UAnalyticsPrivacySettings>()->bSendUsageData;
}

void UEditorEngine::CreateStartupAnalyticsAttributes( TArray<FAnalyticsEventAttribute>& StartSessionAttributes ) const
{
	Super::CreateStartupAnalyticsAttributes( StartSessionAttributes );

#Loc: <Workspace>/Engine/Source/Programs/CrashReportClient/Private/CrashReportClientApp.cpp:650

Scope (from outer to inner):

file
function     FPlatformErrorReport CollectErrorReport

Source code excerpt:

	if (RecoveryService && 
		DirectoryExists && 
		SharedCrashContext.UserSettings.bSendUsageData && 
		!FPlatformCrashContext::IsTypeContinuable(SharedCrashContext.CrashType)
	{
		RecoveryService->CollectFiles(ReportDirectoryAbsolutePath);
	}
#endif

#Loc: <Workspace>/Engine/Source/Programs/CrashReportClient/Private/CrashReportClientApp.cpp:955

Scope (from outer to inner):

file
function     static bool LoadTempCrashContextFromFile

Source code excerpt:

	FindAndParseValue(ContextProperties, TEXT("NoDialog"), UserSettings.bNoDialog);
	FindAndParseValue(ContextProperties, TEXT("SendUnattendedBugReports"), UserSettings.bSendUnattendedBugReports);
	FindAndParseValue(ContextProperties, TEXT("SendUsageData"), UserSettings.bSendUsageData);
	FindAndCopyValue(ContextProperties, TEXT("LogFilePath"), UserSettings.LogFilePath);

	return true;
}

FString FormatExitCode(int32 ExitCode)

#Loc: <Workspace>/Engine/Source/Programs/CrashReportClient/Private/CrashReportClientApp.cpp:1039

Scope (from outer to inner):

file
function     static void HandleAbnormalShutdown

Source code excerpt:

		PlatformFile.DeleteDirectoryRecursively(*TempCrashDirectory);

		if (CrashContext.UserSettings.bSendUsageData)
		{
			// If analytics is enabled make sure they are submitted now.
			FCrashReportAnalytics::GetProvider().BlockUntilFlushed(5.0f);
		}
	}
}

#Loc: <Workspace>/Engine/Source/Programs/CrashReportClient/Private/CrashReportClientApp.cpp:1167

Scope (from outer to inner):

file
function     void RunCrashReportClient

Source code excerpt:

					FCrashReportAnalyticsSessionSummary::Get().OnCrashReportStarted(CrashContext.CrashType, CrashContext.ErrorMessage);

					const bool bReportCrashAnalyticInfo = CrashContext.UserSettings.bSendUsageData;
					if (bReportCrashAnalyticInfo)
					{
						FCrashReportAnalytics::Initialize(CrashContext.SessionContext.EpicAccountId);
					}

					FCrashReportAnalyticsSessionSummary::Get().OnCrashReportCollecting();

#Loc: <Workspace>/Engine/Source/Programs/CrashReportClient/Private/CrashReportClientApp.cpp:1249

Scope (from outer to inner):

file
function     void RunCrashReportClient

Source code excerpt:

			FSharedCrashContextEx TempCrashContext;
			FMemory::Memzero(TempCrashContext);
			if (LoadTempCrashContextFromFile(TempCrashContext, MonitorPid) && TempCrashContext.UserSettings.bSendUsageData)
			{
				FCrashReportAnalytics::Initialize(TempCrashContext.SessionContext.EpicAccountId);
				if (FCrashReportAnalytics::IsAvailable())
				{
					TOptional<int32> ExitCodeOpt;
					int32 ExitCode;

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/GenericPlatform/GenericPlatformCrashContext.cpp:503

Scope (from outer to inner):

file
function     void FGenericCrashContext::Initialize
lambda-function

Source code excerpt:

		if (InParams.SendUsageData.IsSet())
		{
			NCached::UserSettings.bSendUsageData = InParams.SendUsageData.GetValue();
		}
		SerializeTempCrashContextToFile();
	});

	FCoreDelegates::OnPostEngineInit.AddLambda([] 
	{

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/GenericPlatform/GenericPlatformCrashContext.cpp:726

Scope (from outer to inner):

file
function     void FGenericCrashContext::InitializeFromConfig

Source code excerpt:

	// Set privacy settings -> WARNING: Ensure those setting have a default values in Engine/Config/BaseEditorSettings.ini file, otherwise, they will not be found.
	GConfig->GetBool(TEXT("/Script/UnrealEd.CrashReportsPrivacySettings"), TEXT("bSendUnattendedBugReports"), NCached::UserSettings.bSendUnattendedBugReports, GEditorSettingsIni);
	GConfig->GetBool(TEXT("/Script/UnrealEd.AnalyticsPrivacySettings"), TEXT("bSendUsageData"), NCached::UserSettings.bSendUsageData, GEditorSettingsIni);
#elif CRASH_REPORTER_WITH_ANALYTICS
	NCached::UserSettings.bSendUnattendedBugReports = true; // Give CRC permission to generate and send an 'AbnormalShutdown' report if the application died suddently, mainly to collect the logs post-mortem and count those occurrences.
	NCached::UserSettings.bSendUsageData = true; // Give CRC permission to send its analytics and the application session summary (if one exist)
#endif
	
	// Write a marker file to disk indicating the user has allowed unattended crash reports being
	// sent. This allows us to submit reports for crashes during static initialization when user
	// settings are not available. 
	FString MarkerFilePath = FPaths::Combine(FPlatformProcess::ApplicationSettingsDir(), TEXT("NotAllowedUnattendedBugReports"));

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/GenericPlatform/GenericPlatformCrashContext.cpp:1006

Scope (from outer to inner):

file
function     void FGenericCrashContext::SerializeUserSettings

Source code excerpt:

	AddCrashPropertyInternal(Buffer, TEXT("NoDialog"), NCached::UserSettings.bNoDialog);
	AddCrashPropertyInternal(Buffer, TEXT("SendUnattendedBugReports"), NCached::UserSettings.bSendUnattendedBugReports);
	AddCrashPropertyInternal(Buffer, TEXT("SendUsageData"), NCached::UserSettings.bSendUsageData);
	AddCrashPropertyInternal(Buffer, FGenericCrashContext::LogFilePathTag, FPlatformOutputDevices::GetAbsoluteLogFilename()); // Don't use the value cached, it may be out of date.
}

// This function may be called in the crashing executable or in an external crash reporter program. Take care with accessing global variables vs member variables or 
// fields in NCached!
void FGenericCrashContext::SerializeContentToBuffer() const

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Mac/MacPlatformMisc.cpp:2342

Scope (from outer to inner):

file
function     void FMacCrashContext::GenerateCrashInfoAndLaunchReporter

Source code excerpt:

	}

	bool bSendUsageData = true;
	if (GConfig)
	{
		GConfig->GetBool(TEXT("/Script/UnrealEd.AnalyticsPrivacySettings"), TEXT("bSendUsageData"), bSendUsageData, GEditorSettingsIni);
	}

	// NOTE: A blueprint-only game packaged from a vanilla engine downloaded from Epic Game Store isn't considered a 'Licensee' version because the engine was built by Epic.
	//       There is no way at the moment do distinguish this case properly.
	if (BuildSettings::IsLicenseeVersion() && !UE_EDITOR)
	{
		// do not send unattended reports in licensees' builds except for the editor, where it is governed by the above setting
		bSendUnattendedBugReports = false;
		bSendUsageData = false;
	}

	const bool bUnattended = GMacAppInfo.bIsUnattended || IsRunningDedicatedServer();
	if (bUnattended && !bSendUnattendedBugReports)
	{
		bCanRunCrashReportClient = false;

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Mac/MacPlatformMisc.cpp:2394

Scope (from outer to inner):

file
function     void FMacCrashContext::GenerateCrashInfoAndLaunchReporter

Source code excerpt:

		else
		{
			if (!bSendUsageData)
			{
				Argv[Argc++] = "-NoAnalytics";
			}
		}

		// We've generated the crash report above since we were able to,

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Mac/MacPlatformMisc.cpp:2476

Scope (from outer to inner):

file
function     void FMacCrashContext::GenerateEnsureInfoAndLaunchReporter

Source code excerpt:

	}

	bool bSendUsageData = true;
	if (GConfig)
	{
		GConfig->GetBool(TEXT("/Script/UnrealEd.AnalyticsPrivacySettings"), TEXT("bSendUsageData"), bSendUsageData, GEditorSettingsIni);
	}

	// NOTE: A blueprint-only game packaged from a vanilla engine downloaded from Epic Game Store isn't considered a 'Licensee' version because the engine was built by Epic.
	//       There is no way at the moment do distinguish this case properly.
	if (BuildSettings::IsLicenseeVersion() && !UE_EDITOR)
	{
		// do not send unattended reports in licensees' builds except for the editor, where it is governed by the above setting
		bSendUnattendedBugReports = false;
		bSendUsageData = false;
	}

	const bool bUnattended = GMacAppInfo.bIsUnattended || !IsInteractiveEnsureMode() || IsRunningDedicatedServer();
	if (bUnattended && !bSendUnattendedBugReports)
	{
		bCanRunCrashReportClient = false;

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Mac/MacPlatformMisc.cpp:2523

Scope (from outer to inner):

file
function     void FMacCrashContext::GenerateEnsureInfoAndLaunchReporter

Source code excerpt:


		// If the editor setting has been disabled to not send analytics extend this to the CRC
		if (!bSendUsageData)
		{
			Arguments += TEXT(" -NoAnalytics");
		}

		FString ReportClient = FPaths::ConvertRelativePathToFull(FPlatformProcess::GenerateApplicationPath(TEXT("CrashReportClient"), EBuildConfiguration::Development));
		FPlatformProcess::ExecProcess(*ReportClient, *Arguments, nullptr, nullptr, nullptr);

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformCrashContext.cpp:578

Scope (from outer to inner):

file
function     void FUnixCrashContext::GenerateCrashInfoAndLaunchReporter

Source code excerpt:


	// Controls if we want analytics in the crash report client
	bool bSendUsageData = true;
	if (GConfig)
	{
		GConfig->GetBool(TEXT("/Script/UnrealEd.AnalyticsPrivacySettings"), TEXT("bSendUsageData"), bSendUsageData, GEditorSettingsIni);
	}

	// If we are not an editor but still want to agree to upload for non-licensee check the settings
	bool bAgreeToCrashUpload = false;
	if (!UE_EDITOR && GConfig)
	{

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformCrashContext.cpp:596

Scope (from outer to inner):

file
function     void FUnixCrashContext::GenerateCrashInfoAndLaunchReporter

Source code excerpt:

		bSendUnattendedBugReports = false;
		bAgreeToCrashUpload = false;
		bSendUsageData = false;
	}

	bool bSkipCRC = bUnattended && !bSendUnattendedBugReports && !bAgreeToCrashUpload;

	if (!bSkipCRC)
	{

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformCrashContext.cpp:726

Scope (from outer to inner):

file
function     void FUnixCrashContext::GenerateCrashInfoAndLaunchReporter

Source code excerpt:


			// If the editor setting has been disabled to not send analytics extend this to the CRC
			if (!bSendUsageData)
			{
				CrashReportClientArguments += TEXT(" -NoAnalytics ");
			}

			if (bImplicitSend)
			{

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp:610

Scope (from outer to inner):

file
namespace    anonymous
function     int32 ReportCrashForMonitor

Source code excerpt:

	bNoDialog |= UE::Core::Private::CVarForceCrashReportDialogOff.GetValueOnAnyThread() == true;
	bool bSendUnattendedBugReports = true;
	bool bSendUsageData = true;
	bool bCanSendCrashReport = true;
	// Some projects set this value in non editor builds to automatically send error reports unattended, but display
	// a plain message box in the crash report client. See CRC app code for details.
	bool bImplicitSend = false;
	// IsRunningDedicatedServer will check command line arguments, but only for editor builds. 
#if UE_EDITOR

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp:634

Scope (from outer to inner):

file
namespace    anonymous
function     int32 ReportCrashForMonitor

Source code excerpt:

	{
		GConfig->GetBool(TEXT("/Script/UnrealEd.CrashReportsPrivacySettings"), TEXT("bSendUnattendedBugReports"), bSendUnattendedBugReports, GEditorSettingsIni);
		GConfig->GetBool(TEXT("/Script/UnrealEd.AnalyticsPrivacySettings"), TEXT("bSendUsageData"), bSendUsageData, GEditorSettingsIni);
		
#if !UE_EDITOR
		if (ReportUI != EErrorReportUI::ReportInUnattendedMode)
		{
			// Only check if we are in a non-editor build
			GConfig->GetBool(TEXT("CrashReportClient"), TEXT("bImplicitSend"), bImplicitSend, GEngineIni);

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp:663

Scope (from outer to inner):

file
namespace    anonymous
function     int32 ReportCrashForMonitor

Source code excerpt:

		// do not send unattended reports in licensees' builds except for the editor, where it is governed by the above setting
		bSendUnattendedBugReports = false;
		bSendUsageData = false;
	}
#endif

	if (bNoDialog && !bSendUnattendedBugReports)
	{
		// If we shouldn't display a dialog (like for ensures) and the user

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp:681

Scope (from outer to inner):

file
namespace    anonymous
function     int32 ReportCrashForMonitor

Source code excerpt:

	SharedContext->UserSettings.bNoDialog = bNoDialog;
	SharedContext->UserSettings.bSendUnattendedBugReports = bSendUnattendedBugReports;
	SharedContext->UserSettings.bSendUsageData = bSendUsageData;
	SharedContext->UserSettings.bImplicitSend = bImplicitSend;

	SharedContext->SessionContext.bIsExitRequested = IsEngineExitRequested();
	FCString::Strncpy(SharedContext->ErrorMessage, ErrorMessage, CR_MAX_ERROR_MESSAGE_CHARS);

	// Setup all the thread ids and names using snapshot dbghelp. Since it's not possible to 

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp:839

Scope (from outer to inner):

file
namespace    anonymous
function     int32 ReportCrashUsingCrashReportClient

Source code excerpt:


	// Controls if we want analytics in the crash report client
	bool bSendUsageData = true;
	if (GConfig)
	{
		GConfig->GetBool(TEXT("/Script/UnrealEd.AnalyticsPrivacySettings"), TEXT("bSendUsageData"), bSendUsageData, GEditorSettingsIni);
	}

#if !UE_EDITOR
	// NOTE: A blueprint-only game packaged from a vanilla engine downloaded from Epic Game Store isn't considered a 'Licensee' version because the engine was built by Epic.
	//       There is no way at the moment do distinguish this case properly.
	if (BuildSettings::IsLicenseeVersion())

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp:852

Scope (from outer to inner):

file
namespace    anonymous
function     int32 ReportCrashUsingCrashReportClient

Source code excerpt:

		// do not send unattended reports in licensees' builds except for the editor, where it is governed by the above setting
		bSendUnattendedBugReports = false;
		bSendUsageData = false;
	}
#endif

	if (bNoDialog && !bSendUnattendedBugReports)
	{
		bCanRunCrashReportClient = false;

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp:898

Scope (from outer to inner):

file
namespace    anonymous
function     int32 ReportCrashUsingCrashReportClient

Source code excerpt:


			// If the editor setting has been disabled to not send analytics extend this to the CRC
			if (!bSendUsageData)
			{
				CrashReportClientArguments += TEXT(" -NoAnalytics ");
			}

			// Pass nullrhi to CRC when the engine is in this mode to stop the CRC attempting to initialize RHI when the capability isn't available
			bool bNullRHI = !FApp::CanEverRender();

#Loc: <Workspace>/Engine/Source/Runtime/Core/Public/GenericPlatform/GenericPlatformCrashContext.h:216

Scope: file

Source code excerpt:

	bool					bNoDialog = false;
	bool					bSendUnattendedBugReports = false;
	bool					bSendUsageData = false;
	bool					bImplicitSend = false;
	TCHAR					LogFilePath[CR_MAX_DIRECTORY_CHARS];
};

/**
 * Fixed size struct holds crash information and session specific state. It is designed