During the school's AI course, we received a behaviour tree base project for an assignment to implement an AI with. I used this base code
for the AI in project 6, but it was difficult to build and visualize in code.
So in project 7, I modified our script editor to support my own script nodes that would be used to create behaviour trees. The final result can be seen in the gif, where I also networked a communication between the editor and the engine, allowing me to visualize the flow in the behaviour tree. Much like Unreal does.
The AI characters in the 6th project and the 7th project all used behaviour trees to do their game logic. Spite - Ragnars Mjöd was the first project that used behaviour tree and it was all done in code. To visualize the behaviour tree, I drew all logic in Paint (Ouch!). This was tedious, since when I wanted to change the tree, I had to draw around in paint as well.
During the 6th project, we also had a course in scripting, where one assignment was to implemented a visual script editor to code. Flovin and Fredrik implemented it to work in our engine so our level designers could script events. As we started our 7th project, I wanted to implement support to create my behaviour trees in it as well. This would increase the speed of which I can work with the AI, and it would also allow me to let designers tweak behaviours as well. During pre-production of Gunbritt, it was implemented and upp and running!
After the 7th project's alpha sprint, I was inspired to visualize the AI characters in the editor, much how Unreal Engine does with their behaviour trees. So after the first of two beta sprints, I added the possibility to visualize what the AI was doing in the editor.
The solution to do it was by sending networked messages to the script editor from the engine. The Editor exports out the nodes ID, which I mapped to the behaviour nodes in engine. When they were triggered, I sent a network message with the ID of the node. If the editor has a matching node, I set a count of 60 onto that script node, that counts down everytime the window is repainted. The function is recursive, setting all the connected nodes count as well. Then with the count, I lerp the color and size so it is easier to visualize the flow.
I made the connection UDP, in order for both clients to be opened and closed whenever, ignoring required handshakes and sending messages back and forth.
Our script editor worked with Squirrel as programming language in the background, that then communicated to C++. To create a Behaviour Tree node, I first create a .nut file that would work as a node in the script editor. The nut file had two functions; holding a name and calling a function in the C++ Engine. The function in the C++ engine would collect the nodes arguments and send a message to the Behaviour Tree Factory, telling it to create a node.
The Behaviour Tree Factory was a class that would create and store "blueprints" of all the behaviour trees created in the script editor.
At engine startup, the factory would read all the behaviour tree .xml files that the editor had created.
The .xml files were scripts that would start at the root node and parse through all connections. The factory would start the scripts,
and then collect all the messages from the node scripts, and add them to the current tree in creation.
Our scripting system was covered with wrapped layers, not exposing squirrel to the rest of the engine. As I wanted to continue with this philosophy, I had to keep the C++ bridge functions behind the wrapped layers and send messages for which nodes should be created and their data needed. I wanted to actually work on AI as well and not just a cool editor, I resolved with a quick and dirty switch case to check which node was to be created.