I thought I’d take some time to highlight the absolute greatest feature of the Donkey Tech 1 (DT1) engine… the visual scripting system.
Many developers seem to be steering towards integrating Lua, Python, etc into their game projects with the hope that it’ll streamline the game creation process. I did it too. An earlier version of the engine had full Lua support. The problem is that it still forces much of the game logic on to a programmer instead of putting it where it should be – with the artists or level designers.
I decided I’d try and develop a visual, node-based, scripting system that would easily allow anyone to define complex relationships between entities in the game. Since we were targeting the iPhone it also had to be very efficient as well.
The solution looks like this: By linking the nodes together you form a graph that performs the operations that you want to do. Nodes are lazily evaluated – i.e. if you need the value of a plug at the end of a chain of nodes, all of its dependencies upstream of it are evaluated first. this is key to its efficiency.
So what does this look like in C++? In a nutshell, all a class has to do is inherit from a PlugNode base class and define it’s member functions much like this:
Plug<Vector3> _position;
Plug<Matrix3> _orientation;
Plug<TWfloat> _scale;
There’s an initialization function a little later in the .cpp file that looks like this:
PLUG_INFO(_position).Init("Position",PLUG_OFFSET(_position),plug_node_info)
.Affects(PLUG_INFO(_world_position))
.Affects(PLUG_INFO(_world_orientation))
.Affects(PLUG_INFO(_world_scale))
.Set_Input(true)
.Set_Output(true);
PLUG_INFO(_orientation).Init("Orientation",PLUG_OFFSET(_orientation),plug_node_info)
.Affects(PLUG_INFO(_world_position))
.Affects(PLUG_INFO(_world_orientation))
.Affects(PLUG_INFO(_world_scale))
.Set_Input(true)
.Set_Output(true);
PLUG_INFO(_scale).Init("Scale",PLUG_OFFSET(_scale),plug_node_info)
.Affects(PLUG_INFO(_world_position))
.Affects(PLUG_INFO(_world_orientation))
.Affects(PLUG_INFO(_world_scale))
.Set_Input(true)
.Set_Output(true);
What does all of this do? In a nutshell, the Plug template wraps the primitive type in the logic for maintaining the plug state and connections while making it behave much like a the primitive type. PLUG_INFO is simply a macro that is the object that contains static information about the plug (like name and flags). this information is constant for all of the instances of this node type. The Affects statement defines which inputs affect which outputs which is necessary in tracking dirty states for the lazy evaluation. Set_Input and Set_Output are just flags that say whether the plug is an input or an output.
I realize that details are a little scarce here. It’s meant to me more of an introduction that an exact how-to.
What kind of things can be done with this system? Well, as it turns out, a lot! Here’s a few examples:
- The camera rig: The players position, with an offset added and going through a smoothing node to the camera’s position.
- Opening doors: A player enters a zone which causes a timer to increment which is connected to the y-position of a door.
- Cut scenes: All of the cut scenes in tapfu use this system. Switching between cameras, playing sounds, messages, etc.
- Particles: Particles are completely defined by this system with new behaviors chained up in series.
All of this stuff can now be driven by an artist instead of a programmer. So if you are a programmer, do yourself a favour and implement something like this now! You won’t be sorry


