BP Virtual Machine and Threads

Does anyone have an understanding of how the Blueprint Virtual Machine is implemented and how it relates to the Game Thread and Rendering Thread? And where does the Blueprint Virtual Machine exist in the source code?

I created a custom Game Instance c++ class and implemented the Init function, which makes a UE_LOG call after the call to Super::Init(). I also created a blueprint version of my custom Game Instance class and in the Init event I made a call to Print String. When an instance of the game is run, the Print String will execute before the c++ log call unless if I add a delay node before the Print String. I read that blueprint don’t have parallelism implemented. So, does this mean that the delay node is being executed concurrently or is the Blueprint code running separately in its own thread (and it was just a coincidence that my first test would result in the Print String always executing before the C++ log call)?

BP runs in main game thread same that you got in C++, when you call blueprint event it will pass the thread to VM and execute blueprint code with it until function (events counts as functions) in blueprint is ended, majority of nodes are also C++ bindings so blueprint VM simply calls C++ functions. Yes, that means when you would infinitly loop blueprint you would freeze entire engine, but VM has protection for that and stops execution if it detects long loops.

Order of execution depends on implementation of perticilar event how it is binded to blueprint, In case of Init in GameInstance it is renamed implementable event

/** Opportunity for blueprints to handle the game instance being initialized. */
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName = "Init"))
void ReceiveInit();

Called at begining of UGameInstance:Init()

void UGameInstance::Init()
{
	ReceiveInit();

	if (!IsRunningCommandlet())
	{
		UClass* SpawnClass = GetOnlineSessionClass();
		OnlineSession = NewObject<UOnlineSession>(this, SpawnClass);
		if (OnlineSession)
     ....

So technically when you call Super::Init()

Delay node use system called Latent Action, clock icon on node indicates that, it’s a special “Wait For” event system where you make class that tracks specific action (in case f delay it checks time passed) where VM binds to it and being checked on every tick (engine loop) if conditions are meet, if they are, it will execute binded function (in case of blueprint it will exec pin on the node). Yo can see how they are made here:

So paralism here is just a illusion kind of like in JavaScript (Node JS aspecially), CPU is so fast that some delay system may look like it’s run in parallel where in reality it just being binded to system that tracks on every specific occasion if conditions for execution are meet. Same goes with timer system in UE4.

Thanks, that was very helpful. I forgot about this video, which provides a great insight into how the reflection system work in Unreal and I think this also explains where the blueprint virtual machine comes from Building a C+ Reflection System in One Weekend Using Clang and LLVM: Wikipedia also has some nice info as to what LLVM does.

UE4 got it own solution that video may be misleading, way it works is you got UnrealHeaderTool which parse header field and generate code based on empty macros like UCLASS, UPROPERTY etc. that generated code is called when you load the module and it creates UField objects which works as identifiers.

Then you can use TFieldIterator and standard TObjectIterator to search for those. Generated code which keeps refrence to UField of created object and you can access via StaticClass and StaticStruct so you don’t need to do iterations if you already interact with specific object and you can use later TFieldIterator and UClass or UStruct objects object to gerther analize class structure

VM is different thing but indeed it using reflection system to compile code and reference functions, reflection system also alows to create virtual field objects for VM code. I know that in UnrealScript you needed to manually declere native function with “native” option, but we have no idea how UE3 reflection system worked the same, but there lot of thigns that passed from UE3 to UE4.