Spisen - Node Editor

Introduction

At the beginning of Spite: Spell Shock we programmers decided to rework our entire engine so we could make our entire game with only scripting. This was probably a mistake on our part but it seemed like such a fun idea and since no one in TGA had done it before we went for it. We did not create the underlying architecture of the node system Gustav Ralmark did, but we have improved,removed and transfused so many new things in it I can’t help but be proud for all the hundreds of hours of work it took to actually make it all come together. Most importantly it is not just a tech demo that is left ignored, but something we, together with all the other disciplines use for creating games.

In this overview I will not go over the more then 200 hundred nodes that exist since they are rather small in scope and I would rather speak about the big chunky systems that we have created for making our scripting system powerful enough to create games with. If you want more concrete examples of what was done with the script editor check out our Level designers work: Jacob Tjernström, Noel Toivio.

Beautiful Storage nodes

Storage Variables

To make a game with any kind of permanence you need variables. So I started working on storage variables which are the variables that the script editor uses. When you create a storage variable you get to pick which type you want to use and manipulate. Which are the ones you see the right.

These variables act like public variables for the script and can be accessed by getting the id of the object. So if a player hits an enemy with a collider and you want to deal damage it would look like this:

On component begin overlap node was made by Simon Eriksson

One very neat thing about storage variables is that if you have a ranged enemy and a melee enemy and want to deal damage to both of them you don’t need another storage variable called “Ranged Enemy HP”. If they have the same storage variable so the script above will work on all enemies which greatly reduces script bloating.

To avoid having to much of a pull behavior in my code I created a event system. So if you want to play a sound when an enemy takes damage you could do something as seen below.

Beautiful events

Skafferiet

Early on in our Diablo game project we had a ton of problems of strings crashing and being generally kind awful to use so I started making Skafferiet

Skafferiet is the name for our collection of models, variables,prefabs and all other game related data we have in our engine. I created the system to avoid bloating the scripting system with strings. So instead of writing a path to an animated file, having a chance to write a faulty path and having strings slow down our engine we use skafferiet as a way to get file identifiers.

Examples of how skafferiet is used can be seen in all the nodes above with EnemyCurHp or the Play2D Sound . Skafferiet is context sensitive so if you have a Play2D Sound node seen above you only get the option of choosing audio related files.

Break Points

The most important part for my workflow when programming or scripting is debugging. I often think that every line of code is a new bug so i’m an avid user of breakpoints and living without breakpoints will probably cause me to rethink my life choices. Naturally I created a simple breakpoint system to stop myself from going insane from debugging in our scripting system with only console writelines.

My breakpoint system is very simple. When a node in a script is “Entered“ it pauses the game, opens up the script editor zooms to the triggered node. Then it shows most of the data on the node such as the data on the pins and which pin it was entered from.

Beautiful breakpoint on an animation node

Additionally we do have comments but I did not create that feature I kindly asked a programmer from Oddbox for the code which I then implemented in our engine.

Custom nodes/functions

Our script editor is not complete until our scripters make the game without us programmers. To make this dream come true scripters should be able to make their own nodes. I tried my best to base it on Unreals Engine Functions. Not even close to unreals ease of use but i’m still pretty satisified.

How calling a created function looks.

Notable Nodes

Most nodes are as simple as value+value = new value, but these nodes are a bit more complex and interesting.

Imgui Storage Variable (name pending)

In the FPS it took a lot of time to get the right values for our variables in script. Our original pipeline issue was that for a variable to be changed you first had to change it in the script and then save and reload the script which often caused the game to slowdown or crash which then required us to restart the game for changes to actually happen. To circumvent this I created a node that lets you expose variables made in the script editor.

The chosen variable and script

With the node you can then manipulate the chosen variable to find the perfect value.

Spawn Game Object node

One thing I really enjoy when scripting in unity is the prefab system. So I decided to implement a prefab system. The prefabs can be created in our level editor which are then available to our script editor for can then be spawned via our script editor. It is used for spawning enemies in our games, Bullets and many other things. You can read more about how the creation of prefabs works here.

Key Event node

Simple but used very often, it is a node that plays/flows when you press the chosen key.

Get Animation Bone Node

Works with the animation system to get the position of a joint/bone in the animated model. Made with Simon Eriksson.

Next
Next

The Gunk