-
Notifications
You must be signed in to change notification settings - Fork 0
Blueprint Spec Format
The .uebp.json spec format lets you describe a complete Blueprint declaratively and apply it reproducibly across projects. It is the recommended approach for large or version-controlled Blueprints.
| Property | Value |
|---|---|
| File extension | .uebp.json |
| Schema versions |
1.0, 2.0
|
| Max file size | 1 MiB (hard ceiling) |
| Encoding | UTF-8 |
| Mode |
Create-only (v0.1.0); patch is handled via PlanBlueprintPatch / ApplyBlueprintPatch
|
By default, spec files live at:
<YourProject>/BlueprintSpecs/
Configurable via UEBPCrackerSettings::SpecRootDirectory.
Spec paths in tool calls are relative to the spec root:
{ "file": "BP_HealthActor.uebp.json" }Absolute paths, .. traversal, and non-.uebp.json extensions are all rejected.
{
"schema_version": "2.0",
"document_id": "health_actor_v2",
"target": {
"path": "/Game/AI/BP_HealthActor",
"parent_class": "/Script/Engine.Actor",
"conflict_policy": "reject"
},
"variables": [ ... ],
"components": [ ... ],
"graphs": [ ... ]
}| Field | Type | Required | Description |
|---|---|---|---|
schema_version |
string | ✅ |
"1.0" or "2.0"
|
document_id |
string | ✅ | Stable identifier; used for ownership tracking |
target |
object | ✅ | Blueprint target definition |
variables |
array | No | Variable definitions |
components |
array | No | SCS component definitions |
graphs |
array | ✅ | ≥ 1 graph entry required |
Root uses additionalProperties: false — unknown fields are rejected.
"target": {
"path": "/Game/AI/BP_HealthActor",
"parent_class": "/Script/Engine.Actor",
"conflict_policy": "reject"
}| Field | Type | Required | Description |
|---|---|---|---|
path |
string | ✅ | Content path (must be within write root) |
parent_class |
string | ✅ | Class path. Must pass FKismetEditorUtilities::CanCreateBlueprintOfClass
|
conflict_policy |
enum | No |
reject (default) · overwrite · rename
|
"variables": [
{
"id": "health",
"name": "Health",
"type": "float",
"default_value": "100.0",
"instance_editable": true,
"expose_on_spawn": false,
"replication": "None",
"category": "Stats",
"tooltip": "Current health points"
}
]| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Spec-local logical ID (stable across versions) |
name |
string | ✅ | Unreal variable name |
type |
string | ✅ | Type string (see type reference below) |
default_value |
string | No | JSON-encoded value; codec round-trip validated |
instance_editable |
bool | No | |
expose_on_spawn |
bool | No | |
replication |
string | No |
None · Replicated · RepNotify
|
category |
string | No | Editor category |
tooltip |
string | No | (v2.0+) |
| Type string | Unreal type |
|---|---|
bool |
Boolean |
int32 |
Integer |
float |
Float (real, float subcategory) |
double |
Double (real, double subcategory) |
FString |
String |
FName |
Name |
FText |
Text |
FVector |
Vector |
FRotator |
Rotator |
FTransform |
Transform |
FLinearColor |
Linear Color |
TArray<float> |
Array of float |
TMap<FString,int32> |
Map of string to int |
/Script/Engine.Actor |
Object reference (Actor) |
/Script/Engine.StaticMeshComponent |
Object reference (component) |
"components": [
{
"id": "root",
"name": "DefaultSceneRoot",
"class": "/Script/Engine.SceneComponent",
"is_root": true
},
{
"id": "mesh",
"name": "BodyMesh",
"class": "/Script/Engine.StaticMeshComponent",
"parent_id": "root"
}
]| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Spec-local logical ID |
name |
string | ✅ | Component name in SCS |
class |
string | ✅ | Component class path |
parent_id |
string | No | Parent component spec ID (for tree structure) |
is_root |
bool | No | Mark as SCS root node |
"graphs": [
{
"id": "event-graph",
"kind": "event_graph",
"operation": "use_existing",
"nodes": [ ... ],
"connections": [ ... ]
},
{
"id": "calc-damage",
"kind": "function",
"operation": "create",
"name": "CalculateDamage",
"nodes": [ ... ],
"connections": [ ... ]
}
]| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Spec-local logical ID |
kind |
enum | ✅ |
event_graph · construction_script · function
|
operation |
enum | ✅ |
use_existing (event_graph/construction_script) · create (function) |
name |
string | Conditional | Required when kind=function and operation=create
|
nodes |
array | No | Node definitions |
connections |
array | No | Connection definitions |
Rules:
-
event_graphandconstruction_scriptrequireoperation: "use_existing" -
functionrequiresoperation: "create"withname - Spec must have ≥ 1 graph entry
"nodes": [
{
"id": "begin",
"kind": "event_override",
"event_name": "ReceiveBeginPlay",
"event_owner_class": "/Script/Engine.Actor",
"position": { "x": 0, "y": 0 }
},
{
"id": "print",
"kind": "function_call",
"function_path": "/Script/Engine.KismetSystemLibrary:PrintString",
"position": { "x": 320, "y": 0 },
"pin_defaults": [
{ "pin": "InString", "value": "Hello from UEBPCracker!" },
{ "pin": "Duration", "value": "5.0" }
]
},
{
"id": "get_health",
"kind": "variable_get",
"variable_name": "Health",
"position": { "x": 160, "y": 80 }
}
]| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Spec-local node ID (referenced in connections) |
kind |
enum | ✅ | See node kinds below |
position |
object | No |
{ "x": int, "y": int } — snapped to 16-unit grid |
pin_defaults |
array | No | [ { "pin": "name", "value": "raw_string" } ] |
| Kind | Required extra fields | Description |
|---|---|---|
event_override |
event_name |
Override a Blueprint-implementable event (ReceiveBeginPlay, NOT BeginPlay) |
function_call |
function_path (Owner:FunctionName) |
Call a static/member function |
variable_get |
variable_name |
Get variable node |
variable_set |
variable_name |
Set variable node |
branch |
— | If/Else (exec splits) |
sequence |
output_count |
Exec sequence |
cast |
cast_target_class |
Cast to class |
comment |
comment_text, width, height
|
Graph comment box |
macro_instance |
macro_path |
Blueprint macro |
Important:
ReceiveBeginPlayis the correct event name for BeginPlay override.AActor::BeginPlayis not a UFUNCTION and has no BP-overridable event; the overridable event isReceiveBeginPlay.
"connections": [
{
"from_node": "begin",
"from_pin": "then",
"to_node": "print",
"to_pin": "execute"
},
{
"from_node": "get_health",
"from_pin": "Health",
"to_node": "print",
"to_pin": "WorldContextObject"
}
]| Field | Type | Required | Description |
|---|---|---|---|
from_node |
string | ✅ | Source node spec ID |
from_pin |
string | ✅ | Source pin internal name (not display label) |
to_node |
string | ✅ | Target node spec ID |
to_pin |
string | ✅ | Target pin internal name |
Rule: The same input pin cannot have both a connection and a default value.
Differences in v2.0 vs v1.0:
-
schema_versionformat:"1.0"/"2.0"(string, not int) - Variables gain
tooltipfield -
target.conflict_policyis now explicit (was implicitlyreject)
Migration via MigrateBlueprintSpec tool:
- Reads source spec
- Bumps
schema_versionto"2.0" - Adds variable metadata defaults
- Validates output via
FUEBPSpecService::LoadValidatedDocument - Writes atomically (temp file + rename); rollback on validation failure
- Source is never overwritten — output is a new file
{
"schema_version": "2.0",
"document_id": "health_actor_v1",
"target": {
"path": "/Game/AI/BP_HealthActor",
"parent_class": "/Script/Engine.Actor",
"conflict_policy": "reject"
},
"variables": [
{
"id": "health",
"name": "Health",
"type": "float",
"default_value": "100.0",
"instance_editable": true,
"category": "Stats"
}
],
"components": [
{
"id": "scene_root",
"name": "DefaultSceneRoot",
"class": "/Script/Engine.SceneComponent",
"is_root": true
},
{
"id": "body_mesh",
"name": "BodyMesh",
"class": "/Script/Engine.StaticMeshComponent",
"parent_id": "scene_root"
}
],
"graphs": [
{
"id": "event-graph",
"kind": "event_graph",
"operation": "use_existing",
"nodes": [
{
"id": "begin_play",
"kind": "event_override",
"event_name": "ReceiveBeginPlay",
"event_owner_class": "/Script/Engine.Actor",
"position": { "x": 0, "y": 0 }
},
{
"id": "print",
"kind": "function_call",
"function_path": "/Script/Engine.KismetSystemLibrary:PrintString",
"position": { "x": 320, "y": 0 },
"pin_defaults": [
{ "pin": "InString", "value": "Health Actor initialized!" },
{ "pin": "Duration", "value": "3.0" }
]
}
],
"connections": [
{
"from_node": "begin_play",
"from_pin": "then",
"to_node": "print",
"to_pin": "execute"
}
]
}
]
}Apply this with:
validate_blueprint_spec → plan_blueprint_spec → apply_blueprint_spec
-
Tool Reference —
ValidateBlueprintSpec,PlanBlueprintSpec,ApplyBlueprintSpec - Patch and Idempotency — applying specs to existing Blueprints
- UE 5.8 Gotchas — JSON parsing quirks, event name gotchas