How does the Blueprint system really work? [mapping out the Blueprint-related source]

Q: What is Blueprint really? At first I thought it was just an FSM, but the sheer complexity of the source code makes me doubt this now. Am I right in assuming that Blueprint really is some kind of intelligent code-snippet-parser that actually creates and compiles entirely new classes for each Level/Class-Blueprint that one creates?
A: Yes, the blueprint system actually creates new classes and compiles them. Like most of the editor, the Blueprint system relies heavily on reflection. Therefore most classes won’t actually exist in the final build, but will be necessary “steppingstones” for the compiler. For more info, please see the post below, by Michael Noland.

I think a lot of developers would like a small map of the Blueprint system, so I’ll be starting one in this thread, let’s see how far I get :smiley:
What I know so far(I will update this thread over the next weeks each time I find out what a class does exactly):

ObjectBase.h contains all the UPROPERTY, UFUNCTION etc enums

Source/Editor/BlueprintGraph/ contains all the basic node functions. Nodes like the Get and Set node are located here, as well as all the other “dynamic/automatic” stuff that happens in the graph, like casting, error checking (eg if nodes reference classes that are no longer there) etc.

Source/Editor/KismetCompiler/ Contains the actual compiler.

Source/Editor/KismetWidgets/

Source/Editor/Blutility/ (awesome name btw :D)

Quote by Michael Noland

Source/Editor/UnrealEd/Kismet2 Unique struct naming, error fixing, and the like

Runtime/Engine/Classes/Kismet/ (The .cpp files in the private folder are not in a separated folder, so I noted down the header path for ease of access) I’ve no idea what these files do really. BlueprintGeneratedClass.cpp and BlueprintGeneratedStruct.cpp might be wrappers.

Actor.h/Actor.cpp contains most of the blueprint “state”-classes and variables that are related to Actors, which is a lot.

I know this is increadibly shallow at the moment, but I’ll be drilling down a lot over the next days. The final map should have individual info on each class and the most important functions and should be in a format that can be used in the/as docs. If you have additions, please post them. :slight_smile:

Cheers,

One of my blog posts went up here (Unreal Property System (Reflection) - Unreal Engine) yesterday, it goes into a lot of detail on the property system, including the class hierarchy. Have a look at that first, as I’ll be using terms from there without defining them here.

I’ve got an old presentation that talks about more of the compiler internals and how to extend it in more advanced ways than simply exposing functions or variables. I’ll try to update it and hammer it out into a blog post in the next few weeks but here is a quick and dirty summary.

Graphs
The ‘editor graph’ system is system agnostic; we use the same setup for sound cues, Blueprints, animation graphs and state machines, behavior trees, and materials. The basic unit is a UEdGraph which references a UEdGraphSchema that defines what it can contain, as well as zero or more UEdGraphNode instances. The UEdGraphSchema (never instanced, stateless) is responsible for determining what kinds of nodes can be placed in a graph, and it drives things like the context sensitive menus, palette, etc… in the various editors. We’re working over time to devolve much of the control the schema had over the graph to the individual nodes, which makes extension a lot easier and avoids a single giant file of doom, but it’s still the ‘first stop’ for the editor and compiler in a lot of cases, then turning to the nodes from there.

Compilation
Conceptually, none of the graphs or nodes are ever needed at runtime (and are in editor/developer modules as a result). They’re ‘source code’ that gets compiled down into a regular class. Compiling a blueprint creates a new UClass (specifically a UBlueprintGeneratedClass) that works just like a regular UClass generated from a reflected C++ class, containing information about the properties and functions of the blueprint (every entry point into the blueprint such as functions and events turns into an individual UFunction, as well as one additional special UFunction for the entire event graph state machine).

There are actually two classes associated with any given blueprint: the skeleton and the generated class. The skeleton class is more like a ‘header’ for the blueprint, defining the surface area, but without any details. We regenerate this any time you make a ‘structural’ modification to the blueprint graph, such as adding/removing an event, variable, or function parameter, and it lets the BP editor work with the latest information. This avoids the need to do a full compilation for every little change, making the editor workflow smoother.

Compilation phases

CompilationPhases.jpg&d=1396039968

The compilation process goes in several phases; the two red sections only happen during the full generated class compile, the rest are common across both.

The ‘create function list’ phase is actually a bit complicated, as it also handles node expansion. Many of the nodes in a graph are composite; they’re either explicitly so (macros and collapsed graphs) or implicitly so (things like UK2Node_InputKey actually turn into several simpler nodes during expansion). Many of the different compilation steps are exposed to nodes to override, either directly via UK2Node virtuals or via subclasses of FNodeHandlingFunctor, especially on the ‘core nodes’ such as function calls and variable reads/writes.

Module responsibilities

  • Blueprint nodes (subclasses of UK2Node) are mostly declared in the BlueprintGraph module (though some are declared in-situ in other modules with associated code they deal with).
  • The compiler is in the KismetCompiler module.
  • Various editor helpers are in UnrealEd (most of this code should eventually be moved out of there)
  • Runtime classes are in Engine (UBlueprintGeneratedClass, UBlueprint (this will eventually be editor-only too, with runtime classes being almost indistinguishable to any C++ class), etc…
  • Core contains a bit of blueprint-related code as well, but without actual knowledge of Blueprints (mostly related to compile-on-load; it calls delegates to the compiler where necessary, and doesn’t happen in a standalone cooked game)

You’re a bit off on Blutilities. They’re not part of making detail panels work for regular blueprints (that’s handled by the property system just like a C++ class), they’re a prototype of how editor scripting using Blueprints would work. We’ve got a feature request pending to push the ‘event button’ aspect of Blutilities out to be available for any blueprint, then they’ll pretty much just be a library of editor-specific functionality like working with assets and the selection set.

Cheers,
Michael Noland

Blerg, well that is kind of a random brain dump, but there are a lot of moving parts related to Blueprints; it should give some touch points to dive in from at least.

Thank you for taking the time Michael!

It was a great read for me!

:slight_smile:

Rama

wow, this really is a big help! I’ve once written a reflection-based serializer and it took me ages, I can’t imagine how much work you guys must’ve put into this beast :). And yes, another blog post would be very appreciated, though like you said, now that we understand the basic shape of things it should be possible to get into it on our own :smiley:

Thanks again!