Systems

Console Commands & Variables

A console command is sent to the engine to execute a specific functionality.

A console variable is a global state in which data is stored and can be modified through the console.

The supported types are int, float and string.

The following table shows the corresponding C++ types, and the methods to obtain the value of a console variable.

TypeC++ TypeAccessor
intint32GetInt
floatfloatGetFloat
stringFStringGetString

Create a Console Variable

Console variables should be created early when the engine starts, to make sure that auto completion in the editor works.

Therefore, the recommended way to declare a console variable is through static variables.

A console variable is declared with the TAutoConsoleVariable template type and the template argument represents the data type of the variable.

A console variable is created with a name, a default value, a description, and EConsoleVariableFlags flags.

The flags are defined in IConsoleManager.h.

static TAutoConsoleVariable<int32> CVar(
    TEXT("MyVariable"),
    42,
    TEXT("A variable"),
    ECVF_Cheat);

Consoles variables can also be created by calling the IConsoleManager::RegisterConsoleVariable function.

The global instance of the console manager is accessed using IConsoleManager.Get().

IConsoleManager::Get().RegisterConsoleVariable(
    TEXT("MyCVar"),
    42,
    TEXT("A variable"),
    ECVF_Cheat);

Access a Console Variable

The most efficient way to access a console variable is perform a look up with IConsoleManager::FindConsoleVariable and store the result in a static variable.

As console variables persist during the lifetime of the project, it is safe.

static const auto MyCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("MyCVar")); 
int32 Value = MyCVar->GetInt();

Command-Line

The value of console variables can be set when starting the editor using the -ExecCmds argument.

UE4Editor.exe GAMENAME -ExecCmds="r.MyCvar 42"

Memory Allocators

Allocation Rules

Blocks equal or larger than 16 bytes are 16-byte-aligned.

Blocks smaller than 16 bytes are 8-byte aligned.

Global Allocators

The global allocator is GMalloc. It is a FMalloc allocator.

The instance to the global allocator is platform-dependent.

It is accessed using FPlatformMemory::BaseAllocator.

On most platforms, it returns the ANSI malloc implementation represented by FMallocAnsi.

FMallocAnsi performs aligned allocations using a platform-dependent function such as _aligned_malloc (Microsoft), posix_memalign (Apple, Linux, Web), or memalign (PS4).

On platforms that do not provide aligned allocations, the allocation falls back to a regular malloc call with custom padding.

On some platforms, the default base allocator can be replaced with a different implementation using specific preprocessor symbols or command-line options.

The other allocators are:

Containers

There are different allocation policies for containers, represented by allocator traits.

The base template type for traits is TAllocatorTraits.

It actually derive from the non-template type TAllocatorTraitsBase.

Low-Level Memory

Memory allocations are tracked by the Low-Level Memory (LLM) Tracker.

Every memory allocation is assigned a tag value identifying the category to which it belongs.

The tags are applied using tag-scope macros.

LLM is stripped out of Shipping builds.

Usage

To enable LLM, launch the project with the -LLM Enables command-line argument.

To continuously writes out all values to a CSV file, use the -LLMCSV argument instead.

There are two trackers represented by the ELLMTracker enumerated type: Default and Platform.

The Platform tracker is used by the platform-dependent modules such as Windows, macOS, Direct3D, Metal, Vulkan, and so on.

There are two corresponding scope macros:

The macros are called with the tag to associate with the allocations.

Tags are represented by the ELLMTag enumerated type.

Example

In FAssetRegistryModule::StartupModule, the scope macro is used with the AssetRegistry tag.

void FAssetRegistryModule::StartupModule()
{
    LLM_SCOPE(ELLMTag::AssetRegistry);
    ...
}

Implementation

LLM maintains a map of all allocations indexed by a pointer.

LLM uses 21 bytes per allocation.

AllocationSize
Pointer8 bytes
Pointer Hash Key4 bytes
Size4 bytes
Tag1 byte
Hash Map Index4 bytes

The memory used by LLM is managed by the LLMAlloc and LLMFree functions.

Add a New Tag

  1. Add a value to the ELLMTag enumerated type in LowLevelMemTracker.h.
  1. Add a corresponding element to the ELLMTagNames array in LowLevelMemTracker.cpp.
  1. Add tag scopes using the LLM_SCOPE macro.