BPVM Snack Pack #9 - Variables Become Properties: The Transformation | ebp BPVM Snack Pack #9 - Variables Become Properties: The Transformation | ebp BPVM Snack Pack #9 - Variables Become Properties: The Transformation | ebp
Post

BPVM Snack Pack #9 - Variables Become Properties: The Transformation

When you create a variable in Blueprint, it's not really a variable yet. It's just a description waiting to become a real property. Here's the metamorphosis.

BPVM Snack Pack #9 - Variables Become Properties: The Transformation

The content in this post is based on Unreal Engine 5.6.0

BPVM Snack Pack - Quick Blueprint knowledge drops! Part of the Blueprint to Bytecode series.

The Variable Illusion

In the Blueprint editor, you click “+Variable” and create Health:

![Blueprint variable creation in editor]

You think you just created a variable. You didn’t.

You created a description of a variable. The real variable doesn’t exist yet!

Meet FBPVariableDescription

When you create a Blueprint variable, this is what actually gets stored:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct FBPVariableDescription
{
    FName VarName;           // "Health"
    FEdGraphPinType VarType; // Float
    FString Category;        // "Stats"
    uint64 PropertyFlags;    // EditAnywhere, BlueprintReadWrite, etc.

    // Metadata
    FString Tooltip;         // "Player's current health"
    FName RepNotifyFunc;     // "OnRep_Health"

    // NOT an actual property yet!
};

It’s just data about a variable, not the variable itself!

The Compilation Transformation

During compilation, these descriptions become real properties:

1
2
3
4
5
6
7
8
9
10
11
void CreateClassVariablesFromBlueprint()
{
    // Loop through all variable descriptions
    for (FBPVariableDescription& Variable : Blueprint->NewVariables)
    {
        // Transform description into real property!
        FProperty* NewProperty = CreateVariable(Variable.VarName, Variable.VarType);

        // Now it's a REAL property on the class!
    }
}

The Birth of a Property

Here’s the magical moment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FProperty* CreateVariable(FName VarName, FEdGraphPinType& VarType)
{
    // Determine property type
    if (VarType.PinCategory == "Float") {
        // Create REAL float property
        FFloatProperty* NewProp = new FFloatProperty(
            NewClass,     // Owner class
            VarName,      // "Health"
            RF_Public     // Flags
        );

        // It's alive! Real memory will be allocated!
        return NewProp;
    }
}

Why the Two-Step Process?

Why not create real properties immediately?

1. Editor Performance

1
2
3
4
5
6
7
8
9
10
11
12
// Bad: Create real property every edit
Click +Variable  Allocate memory
Type name  Reallocate
Change type  Reallocate again
Set tooltip  Reallocate AGAIN

// Good: Just update description
Click +Variable  Create description
Type name  Update string
Change type  Update enum
Set tooltip  Update string
// Only create real property on compile!

2. Hot Reload Safety

1
2
3
4
5
6
// During editing (safe)
VariableDescription.VarName = "NewName";  // Just data

// During compilation (careful!)
OldProperty->Destroy();
NewProperty = CreateProperty("NewName");  // Real memory operation

3. Validation First

1
2
3
4
5
6
// Check all descriptions BEFORE creating properties
for (auto& Desc : Variables) {
    if (IsDuplicate(Desc)) return;  // Stop before damage!
    if (IsInvalid(Desc)) return;
}
// All good? Now create real properties

The Property Creation Pipeline

Step 1: Gather Descriptions

1
2
3
4
TArray<FBPVariableDescription> Descriptions;
Descriptions.Add("Health", Float);
Descriptions.Add("Armor", Int32);
Descriptions.Add("Name", String);

Step 2: Sort by Size (Optimization!)

1
2
3
4
// Large properties first for better memory alignment
Descriptions.Sort([](auto& A, auto& B) {
    return GetSize(A) > GetSize(B);
});

Step 3: Create Real Properties

1
2
3
4
5
6
7
8
9
10
11
for (auto& Desc : Descriptions) {
    FProperty* Prop = CreatePropertyOnScope(
        NewClass,           // Where it lives
        Desc.VarName,       // Its name
        Desc.VarType        // Its type
    );

    // Configure the property
    Prop->SetPropertyFlags(Desc.PropertyFlags);
    Prop->SetMetaData("Tooltip", Desc.Tooltip);
}

Step 4: Link to Class

1
2
3
4
5
6
// Add to class's property chain
NewClass->AddCppProperty(NewProperty);

// Calculate memory offsets
NewProperty->Offset = CurrentOffset;
CurrentOffset += NewProperty->ElementSize;

Special Property Types

Some variables need extra transformation:

Timeline Variables:

1
2
3
4
5
6
7
// You create one timeline in editor
"MyTimeline"

// Compiler creates MULTIPLE properties:
FTimelineComponent* MyTimeline;        // Component
FOnTimelineFloat MyTimeline_UpdateFunc; // Delegate
FOnTimelineEvent MyTimeline_FinishFunc; // Delegate

Component Variables:

1
2
3
4
5
6
7
// You add a component variable
"MyMeshComp" (StaticMeshComponent)

// Compiler does extra work:
CreateComponentProperty("MyMeshComp");
RegisterComponent("MyMeshComp");
SetupComponentDefaults("MyMeshComp");

The Memory Layout

After all properties are created:

1
2
3
4
5
6
7
8
9
10
class BP_MyActor {
    // Memory layout (ordered by size!)
    0x0000: UStaticMeshComponent* MyMesh;  // 8 bytes
    0x0008: FString Name;                   // 16 bytes (TArray)
    0x0018: float Health;                   // 4 bytes
    0x001C: int32 Armor;                    // 4 bytes
    0x0020: bool bIsAlive;                  // 1 byte
    0x0021: [padding]                       // 7 bytes
    // Total size: 0x0028 (40 bytes)
}

The compiler optimizes the layout for cache efficiency!

Quick Takeaway

  • Blueprint variables start as FBPVariableDescription (just metadata)
  • During compilation, they become FProperty objects (real memory)
  • This two-step process enables safe editing and hot reload
  • Properties are sorted by size for optimal memory layout
  • Special types (Timeline, Component) create multiple properties
  • The transformation happens in CreateClassVariablesFromBlueprint()

From Description to Reality

Next time you create a variable in Blueprint, remember:

  • You’re creating a description, not a variable
  • The real property is born during compilation
  • The two-step process keeps the editor fast and safe
  • Your “simple” variable might create multiple properties!

Want More Details?

For the complete property creation breakdown:

Next up: How functions get manufactured!


🍿 BPVM Snack Pack Series

This post is licensed under CC BY 4.0 by the author.