Runtime Blueprints, have your end user write their own blueprint scripts to use in your game

Overview
This project allows for visual scripting in UE4 similar to Blueprints, but at runtime. The way this is set up does not make use of any UE4 boilerplate

How does this work?
I’ve tried to replicate UE4’s Blueprint editor as close as possible for the end user. So for the end user, it should be very familiar to them if they’ve used UE4 Blueprints before.

Internally, each node is an UObject which contains its runtime data. Think of things like how many pins the node has, what pin is connected to what pin, and what the default value for each input pin is. These nodes then communicate and can be triggered by a starting node like Begin Play. When using multithreading, all execution is ran on one background thread, with the exception of code that is required to be run on the GameThread, like spawning an actor.

Features

  • Functions exposed from C++

  • Latent functions

  • For Loops

  • Some common BP macros like FlipFlop & Sequence

  • Casts and support for inheritance (Can connect a child output to an input which wants a parent class)

  • An extendable list of variable types

  • Variables at runtime

  • Common variables like bool, int.

  • Structs like FVector, FTransform

  • Created object types like UObject, AActor

  • Asset files like UClass* & UStaticMesh*

  • Wildcards

  • Support for arrays for both variables and functions

  • Custom functions with local variables

  • Support for calling custom functions from different scripts

  • UEnum interpretation for C++ functions

  • A basic editor based on the UE4 Blueprint editor

  • Infinite loop checks

  • Multithreading, enabled by default

  • Saving & loading through Json

  • A Python script allowing you to mass convert functions from existing function libraries to Runtime Blueprints function

  • An example using a scriptable, throwable grenade.

  • Simple undo/redo for placement, removal and movement of nodes.

**Examples

Mass spawn

Grenade teleporting
A more practical Runtime Blueprints example - YouTube**

FAQ

Q: Why isn’t this a plugin?
A: Now, I know I’ve put the plugin tag in the title but I actually have a reason to not make it a plugin. I have not made this a plugin because from my experience it is hard for a plugin to communicate with your project source code. I wanted to keep that flexibility in the case of adding a variable type that is defined in your project source and not the engine source.

Q: Can I copy/paste Blueprints I’ve made in UE4?
A: No. Not out of the box. UE4 blueprints store a lot more variables per node and some in a different way, one would need to make a conversion script to do so.

Q: How performant is this compared to UE4 blueprints
A: I’ve not tested this extensively, but the added overhead seems to be slightly worse than regular Blueprints. This is one of the reasons I’ve included multithread support.

Q: Does this work in a networked game?
A: The scripts are to be ran on the server only, with the intention that any replicated functions is merely called from the function and the game code does the rest.

Q: Would you recommend using this for any game?
A: With some pollish, and with the assumption you don’t want to use a text-based scripting language, yes.

Q: Why didn’t you do it like X or Y?
A: Probably because I didn’t know about X or Y, if you have improvements to be made, feel free to fork and make a PR.

Q: How can I contact you for questions and whatnot?
A: I’m active in the Unreal Slackers Discord server (https://unrealslackers.org/). My tag is Moot#0021.

Q: Is replicating blueprint functionality legal?
A: I’ve asked this question on the Answerhub a few years ago. I cannot guarantee you that using this is legal but according to the Answerhub there should be no issue: https://answers.unrealengine.com/que…0458/view.html

Q: What is the game in the last example?
A: That’s Contingency, a fan-made Halo game in UE4. I used to work with them so I used the game in that video to make a more practical example. Check them out at https://project-contingency.com/. The grenade teleport script is available in the source.

Links
Github link:

Other resources:
Multithreading: https://michaeljcole.github.io/wiki…hreads_in_UE4/
Wildcard structs: https://forums.unrealengine.com/comm…our-ufunctions
Barlow font: Barlow - Google Fonts

This looks very interesting, i have looked for something like this for a while :slight_smile: However, after trying to open it, UE just tells me, that it´s missing some modules and rebuilding failed (tr to rebuild it from source). Do you have any idea, what went wrong or how i can bring my UE to rebuild them? Note, my Visual Studio testphase is expired :frowning:

Missing-Module.jpg

Could you post the log it generates? You can use Visual Studio Code to compile. It is free. Make sure you have 4.22 as well.

Found the problem. My whole EPIC stuff is stored on D:\Epic Games\etc. However, the compiler script or whatever it is cannot handle that space between Epic and Games, so it tried to check just D:\Epic and aborted, because this folder does not exist. After unpacking your project in a location without such a space, everything compiled and worked fine :slight_smile:

I know of this issue, I’ll fix it once I’m available to do so. It’s to do with the Powershell script in the source folder.

EDIT: This has been fixed now.

Thank you so very much :slight_smile:

this works great with a compiled source build 4.22. don’t work so good with the launcher version though. but I don’t use launcher builds anymore. its never working right from the launcher anymore lol

one question though how can you get all actors of class? and how can you get an actor in the current level? i don’t see any way of doing it.

Getting actor in current level isn’t possible without GetActorsOfAllClass. Just like regular Blueprints.

That node has not been exposed to this system yet. One will have to add it yourself through this example. You’ll have to take into account multithreading as well considering that specific function can’t be called on an async thread.

https://github.com/HiIAmMoot/Runtime…ing-a-function
https://github.com/HiIAmMoot/Runtime…multithreading

EDIT: Had some time so I’ve added it myself.

[ATTACH=JSON]{“data-align”:“none”,“data-size”:“full”,“data-tempid”:“temp_190508_1588342152560_705”}[/ATTACH]


// .cpp

UGetAllActorsOfClass::UGetAllActorsOfClass()
{
    NodeName = "Get All Actors Of Class";
    NodeCategory = "Utilities";

    InputPins.SetNum(2);
    InputPins[0].MakeNodePin();// No args means execute

    InputPins[1].MakeNodePin("Actor Class", EVariableTypes::Class);
    InputPins[1].Value.Array[0].SetClassArg(); // Default value

    OutputPins.SetNum(2);
    OutputPins[0].MakeNodePin("Then");
    OutputPins[1].MakeNodeArray("Out Actors", EVariableTypes::Actor);

}

void UGetAllActorsOfClass::Execute(int Index, int FromLoopIndex)
{
    TSubclassOf<AActor> ActorClass = GetConnectedPinValue(InputPins[1]).GetClassArg();
    if (ActorClass)
    {
        if (BPConstructor->GetMultiThread())
        {
            // We must execute the actual spawning inside the GameThread, a crash will occur otherwise
            AsyncTask(ENamedThreads::GameThread, [this, ActorClass, FromLoopIndex]()
            {
                UGameplayStatics::GetAllActorsOfClass(this, ActorClass, OutActors);
                OutputPins[1].Value.SetActorArg(OutActors);
                URuntimeBpConstructor::Thread->ContinueExecute(BPConstructor, NodeIndex, 0, FromLoopIndex, FunctionIndex);
            });
        }
        else
        {
            UGameplayStatics::GetAllActorsOfClass(this, GetConnectedPinValue(InputPins[1]).GetClassArg(), OutActors);
            OutputPins[1].Value.SetActorArg(OutActors);
            Super::Execute(0, FromLoopIndex);// Index here is the output pins array index
        }
    }
    else
    {
        Super::Execute(0, FromLoopIndex);// 0 here is the output pins array index
    }
}


// .h

UCLASS()
class RUNTIMEBLUEPRINTS_API UGetAllActorsOfClass : public URuntimeBpObject
{
    GENERATED_BODY()

public:

    TArray<AActor*> OutActors;

    UGetAllActorsOfClass();

    virtual void Execute(int Index, int FromLoopIndex = -1) override;
};

Awesome! works like a charm thankyou!

I’ve updated the code to properly support most Actor delegates, check em out! These will fire when the nodes of the parent actor fire.
I’ve also added the UDamageType and FHitResult variable type considering the new nodes use them.

I’ve added a simple undo/redo feature, check it out!

This is pretty awesome. Can definitely see the opportunity to use a 3D representation of Blueprints. Perhaps that in itself would be a game?

Amazing Work!

Thanks! Yeah definetely you could make a 3D representation. Either through 3D UMG widgets or by making custom actors that are based on the BPNode widget.

I was stuck on 4.22 for a while but I finally got around updating the engine version. Supports up to 4.25 atm, older versions are in their respective branches and will not be developed on. I did do a few updates before upgrading though so you may want to pull regardless.

I still think it would be more advantageous to develop a Plugin for more user-end modularity and exposure via Unreal Marketplace. You could probably pull it off with wrappers or similar exposed to Blueprints. I’m certain that Many are interested in a Player-side Scripting Interface and a Visual Scripting Interface is forward thinking, IMHO.

I was developing one myself called WIZMO (BASIC-like Scripting Engine) a few years back. I was thinking BPNodes using meshes, but 3D UMG Widgets would be cool too. So if was to rekindle my work on WIZMO , I would go 3D/2.5D & Text-based with Collaborative/Multiplayer Editing & Sharing support.

Keep up the Awesome Work!

Thanks! Yeah multiple people have approached me regarding making it an actual plugin now. I’ll look into communicating modules with plugins.

You make a plugin, me buy it:)

Thanks but scripting languages in UE4 are not allowed to be sold. It must be free!

Who said that? There are severalscripting systems being sold. To include a visual scripting plugin.