This is a review of Bolt. a visual scripting plugin for Unity. The plugin has been developed and published by Ludiq.

With Bolt you create flowgraphs to create logic for your game. The goal of the plugin is to make it easier for non-programmers to be able to write game logic. Making it a potential tool for less programming oriented people in your team such as artists and designers. You may have heard of similar tools, such as Blueprints for Unreal. But also Playmaker and Flowcanvas.

The goal of this review is to explain the base functionality of Bolt and how it works. And to give my own opinion on how well it can accompany someone that is already used to C# in Unity. Finally I will also perform some performance benchmarks in this review. In order to properly test this plugin and give a fair review of Bolt I decided to create a sample project called “Happy Flappy”. This sample project will be made available in the future on the Unity Asset Store. This sample project has a C# version as well as a Bolt version.

Preview of Flappy Happy, a sample project that I first made in C# and then converted to Bolt.



One of the unique aspects of Bolt visual scripting is that it uses reflection to get references to C# code in your project. What reflection means is that it, scans through all the code in the project to see what it can talk to. This makes it easy to call C# methods from Bolt, eliminating the time-cost to create custom nodes to interface between Bolt and C#. However, it is harder to communicate towards Bolt then the other way around, and using reflection does have a performance cost.

You can clearly see that the user experience of the plugin has been heavily influenced by the Blueprinting system from Unreal Engine by epic games. Which is a good thing.

This is an affiliated link, by purchasing this plugin you will support me. Helping development of new games & products!


Usability – Getting started

Getting started with the plugin is very easy. You get a startup prompt asking you to configure the plugin. You can choose to view the nodes in a human like-naming scheme or a programming scheme.

Setup wizard that shows up after you import the plugin
Select Human naming or Programmer naming

After these selections you get the option to select your assemblies. This is useful if you have any external plugins that are distributed as a DLL. Allowing you to use them using Bolt visual scripting.

A lot of plugins do have source code tough, meaning that they will get placed in Assembly-CSharp-firstpass. Meaning that if you have new plugins or C# code you would only have to update the Unit Options in Tools/Bolt/Update Unit Options.

Assembly options menu

Type options menu

After the setup is complete, you dont a lot of guidance on what to do next within the engine itself. It may have been cool to see a create your first graph button, or to have sample bolt graphs, example one that implements basic movement. However it does display Manual and Support buttons that bring you to useful pages on the website. It is also worth mentioning that there are a couple of free sample projects available

In order to get started, you create an empty Game Object. And Add Component> Bolt> Flow Machine. And afterwards on the component you press new, this asks you to create a new .asset file. Which is called a Flow Macro.

Add the Flow Machine component to get a flow graph.

Create a new macro file and press edit graph, a new window pops up.

Getting started is quite straightforward. Instead of creating C# files you create .asset files which contain the instructions required. Getting started with Bolt feels very streamlined and premium.


Usability – Finder

Easily find methods and nodes to call using the finder.

In order to start implementing logic you can easily find nodes using the finder.
Which can be toggled using Right Click.

The scanning of the search bar is fast enough and takes 1-2 seconds at best (depending on the scale of your search) using a I7-8700K upon the first search. If you do the same search again it will be instant. This means searches get cached after you have performed them.

I’ve tested if it persists after (stored in the library folder of a project) when you restart Unity. It seems like this is not the case, but I wouldn’t consider that an issue.

Control nodes, ordered from more common to less common


Usability – Configuring your graphs

Flow Graph settings

Bolt allows you to name and give a summary for each graph you make. Allowing you to keep the project organised

Control/Value input and outputs are meant to be used for Super Units. These units are meant to be callable like functions. I will get to these later, as they can be useful to avoid a lot of repetition.

As you can see, Bolt supports variables of various scopes. Starting with the most local, to the entire application. With the addition of saved variables.

It is worth mentioning that, when you add a existing flow graph to an object, no variables get declared. So it may be wise to make use of prefabs, in case you want to reuse functionality. In my opinion it would be nice to have a “Auto generate feature”. So it would fill in the Variables component automatically based on the requirements of a graph.

Being able to declare global variables within the App or Scene can be useful for smaller applications. However I can imagine that it can become messy when the game starts to scale up. I would personally recommend creating multiple scenes for multiple purposes In case you go for a bigger scale game with Bolt. So you would have one scene for the Player and Camera. One for global user interface, one for the game interface. Etc. Else you may have to start working with a very big list of variables over time.

Object variables get placed in a Variables Component, on the game object.
Scene variables get placed in a separate object in the scene. With the added component called “Scene Variables”

Usability – Live editing

This is one of the greatest strengths of Bolt. You are able to edit graphs while the game is running. Or even add new nodes while it is running. Meaning you can prototype functionality very quickly.


Usability – Communication between Bolt and C#

Bolt has the upper hand in terms of communication. There are limited options when it comes to calling functionality in Bolt from C#. Most of it is the other way around, meaning you can call any public function you make in C# from Bolt. But it isn’t possible to call all event node from C#. Altough to be fair, there is little reason to call those things from C#, since you want optimal performance.


One of the options for calling Bolt code is by triggering custom events.
The sample below shows you how to do this.

using Ludiq;
using Bolt;

CustomEvent.Trigger(targetGameObject, argument1, argument2, ...)

Usability – State machines

Super units are useful if you have a graph that you want to use multiple times. A super unit is just a regular Flow Graph, with the Inputs and Outputs configured. I personally think it’s great that Bolt has this feature, since having to repeat yourself isn’t good practice. In the second picture, you can see how the Super Unit of the first picture is used.

Example Flow Graph that can be used as a Super Unit. This one is used to get a position based on the camera. So I can place a pipe just right outside of the camera view.

Example of how the super unit is used to determine the spawning position (x) of the pipes.

Usability – Communicating between graphs

When you make games, it is often useful to decouple scripts to keep your code/graphs flexible and extendable. As far as I know events are the one and only way of doing this at the moment in Bolt. In order to use events, you have to call the Custom Event node.

On the left, a custom event is called. On the right code is defined to be called once event is triggered.

In order to use events, you have to call the Custom Event node. There are some things you may have to keep in mind when using Custom Events tough:

KEEP IN MIND: Events only get triggered based on the target you set for them.
In the case of the nodes below, the event will only be called flow graphs that are on the same Game Object. So this would not call any flow graphs that listen for the event.
Solution: Use a global object in the scene, or app and use that as a target. Unless you intend to just use the event trigger within the same graph.

KEEP IN MIND: Usage of strings is more prone to human error
Mistakes happen, sometimes there may be a space, an incorrect capital letter or any other small issue. My recommendation is to store the strings as variables, and just reference those variables instead.

EXTRA: You can also call events as a coroutine. This means you can run a method that takes a certain amount of time. Just tag it as a coroutine and use the Next Frame node (Wait one frame) or the Wait For Seconds node.

Example nodes that are called when the restart game event has been called in Happy Flappy.
You can see that both the object input and name are based on existing references.
Example of a event that is used as a coroutine. In this case a menu moves upwards after the bird has died.

Usability – State machines

Bolt also features usability of state machines. The sample game I made does not make use of them. But from my understanding it you to hook up multiple flow graphs and move between them based on a transition condition. Similar to how the Animator does transitions.

Image of the state machine that was used in the Bolt Kit: First Person

A graph will call “On Enter State” after it has switched to that state. In the example above It will run a coroutine in a while loop indefinitely and wait 1-4 seconds each tick. I’m assuming it automatically cancels the coroutine once the transition has been exited.

Transition condition for Chase to happen. It applies a simple distance check that is contained within a super unit.


Performance – Startup Time & Plugin Size

Performance is a big consideration when using a plugin. In this example I will be taking a look at the startup time of the plugin, testing it on builds of several devices.

using UnityEngine;
using UnityEngine.UI;

public class StartupTimeCheck : MonoBehaviour
{
    [SerializeField] private Text text;

    void Start()
    {
        text.text = Time.realtimeSinceStartup.ToString();        
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
            Application.Quit();
    }
}

Startup time tests have been conducted without the splash screen using Unity 2019.1.7f1 and Bolt version 1.4.9 NET4. These packages have been included during testing the empty projects, so the total size could be reduced even more. Above all I’m most interested in the size and startup speeds that Bolt adds.

Please do note that the results vary per device, and they only serve as a indicator.

The application size increase is very acceptable in my opinion. With it adding just about 3.1 mb for the IL2CPP build. And less for the Mono Build. Of course, the acceptability does depends on the kind of application you are making.

Building with Mono takes a big performance hit in terms of startup speed on mobile, in contrast to IL2CPP. While on PC it is less of an issue. Also, for users that do not use Unity Plus or Pro. The splash screen itself takes time, allowing for a couple of seconds of loading. Resulting in a bit more leeway in terms of noticeable slowdown with boot time. During my tests the game started right away after the splash screen faded out.


Performance – Code Performance

Since Bolt uses Reflection, you can expect performance overhead.
Therefore I decided to run some tests to share with you. Giving you an indication of the potential performance cost of using Bolt instead of C#.

private void Start()
{
    StringBuilder sb = new StringBuilder();

    sb.AppendLine($"C# Test - {CSharpTest()}");
    sb.AppendLine($"Bolt Self Log - {RunBoltTest("TestSelfLog")}");
    sb.AppendLine($"Bolt Iterate - {RunBoltTest("TestIterate")}");
    sb.AppendLine($"Bolt Pure - {RunBoltTest("TestPure")}");

    text.text = sb.ToString();
}

public string CSharpTest()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();

    for (int i = 0; i < 10000; i++)
    {
        var length = Vector3.Distance(new Vector3(1, 4, 6), new Vector3(3, 25, 66));
    }

    sw.Stop();
    return sw.Elapsed.TotalMilliseconds.ToString();
}
        
private string RunBoltTest(string eventName)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();

    CustomEvent.Trigger(boltObject, eventName);

    sw.Stop();
    return sw.Elapsed.TotalMilliseconds.ToString();
}

As you can see from the code above, I’m applying a simple distance check between two vectors using Vector3.Distance(v1,v2). The tests are done using the Stopwatch class and the StringBuilder class to create a string to read the results from. As a result this made it possible for me to read the results from any target device.

Test in Bolt that logs time and writes it to a text component

As seen above, there is a significant performance cost of using Bolt, in comparison to C#. I’ve also tested the results by using a C# stopwatch, but the results were about the same as using the Stopwatch class in Bolt. Based on these results it is safe to say that it is wise to write more expensive methods and systems in C#.

Calling the code directly from Bolt. C# will track the total execution time

When comparing the C# call from Bolt to the direct call, there is little difference in terms of milliseconds. Whereas the direct C# call for “Android Mono” has a speed of 3.9 milliseconds, and the Bolt call has 4 milliseconds. The IL2CPP one has an increase of 0.01 milliseconds. This indicates that a single C# call from Bolt doesn’t apply a real effect on the duration of a frame. The difference falls in margin of error.


Bolt 2.0

You can expect Bbolt to be released in 2020. Early versions are already obtainable. Bolt 2.0 will be a free update. As you can see on the image below, it has a vertical alignment instead of horizontal. Seemingly this has the potential to produce less “Visual Spaghetti”. However that remains to be seen. Aside from the visual changes there is a very important change “C# Code Generation”. Meaning you will be able to use visual scripting in Unity without a performance loss. As a result you can have the best of both worlds when working on your game, being able to live edit your game. And then after you want to make a build, you let it generate all C# code for you.

What bolt 2.0 is going to look like. Source

Conclusion

After having created the “Happy Flappy” prototype in both C# and Bolt. I can say that I prefer C# more, this is mainly because of my own speed of using C#. Personally, for me it is just faster to write it down in code.

Some things are just a lot quicker to type in C# then in Bolt. One example of this is including simple calculations in a function call. In Bolt you would have to get a separate node, with multiple connections to enter a calculation. Although, if you are proficient with Bolt, it can still be done quickly.

What I do like about Bolt is that you can literally turn your Bolt graph into C#. This makes it straightforward to optimize a Bolt project. It could actually serve as a bridge towards using and learning C#, since you are coding in a visual manner. I can imagine it takes away the scariness of using code for new users, instead giving users a feeling of a sandbox they can play with.

The results in C# tend to be a bit shorter and smaller then with graphs.

Is Bolt a good fit for your project?

For medium sized games I can imagine Bolt being useful for simple systems that do not execute each frame. For instance for a dialogue system. Or for small one time actions that do not warrant having a custom made component.

If your main intent is to use some kind of graph system, and you want a bare bones node solution where you can script high performance nodes yourself. Then xNode is a viable consideration for you opposed to Bolt. However, Bolt could prove to be useful to actually prototype such a node based system before you write the nodes in C#.

Small games are a good fit for Bolt. Because it helps you iterate quickly, and those types of games are generally very lightweight in terms of coding requirements. Getting 60 fps from your games with Bolt is certainly a possibility, but it isn’t going to be easy for bigger projects unless you use C# as well. Consequently I would personally not dare making a bigger sized project with just pure Bolt. You can make bigger projects with Bolt, just don’t expect the best performance for now. I’m sure Bolt 2.0 will be a life changer in this regard. Despite the performance issues, Bolt is a great plugin and has a good premium feel to it.


Did you like this review? Consider trying out any of my plugins or games.

Thank you for reading this review. I hope it was of help to you. In case you have any suggestions for this article. Or things you would really like to know, please leave a comment. Have a good day!