top of page
NE_UE_IM.png

Behavior Tree Editor

This custom Behavior Tree Editor provides a streamlined way to create and manage AI logic using an Entity Component System (ENTT) with an intuitive node-based UI (based on ImNodes for ImGUI).

The system automatically handles serialization and editor integration, allowing developers to focus on AI logic. Additionally, it features a blackboard system, similar to Unreal Engine’s, enabling data storage and synchronization across multiple entities. While editing is PC-exclusive, the AI trees are fully functional on the PS5 as well.

I also wrote a blog post about this project which can be found here.

  • Role: Tools Programmer

  • Responsabilities:​

    • C++ custom node creation

    • Editor UI

    • Blackboards​

  • Team size:​ Solo

  • Tools/Language:

    • Custom engine​

    • C++

Final Result

The Behavior Tree Editor streamlines AI behavior creation, providing a node-based interface (Fig. 1) and seamless C++ integration.

The result is a highly flexible system where AI behaviors can be visually structured while maintaining full control through C++. Once created, these behaviors (Fig. 2) can be used across multiple entities and even run on PC and PS5, ensuring a smooth development workflow from design to implementation.

Fig. 1

PlayerChaseDemo.gif

Fig. 2

NodeMenu.png
GetItemResourcePins.png

Node based editor

  • Node-based workflow for AI behaviors using ImGUI with the ImNodes extension that is slightly modified to fit what I needed.

  • Each node represents an action, condition, or decorator, forming complex behaviors in a structured manner.

  • This visual system simplifies design and debugging of AI decision-making.

ChaseBlackboard.png

Fig. 2

Blackboards

  • Inspired by Unreal Engine's system,  the blackboard stores keys (Fig. 2) that nodes can read or write to, representing the communication between them.

  • A unique addition are the "Custom Keys" (Fig. 1), which allow any node pin to act as a blackboard key. Instead of hardcoded values, pins can dynamically reference stored data, reducing the need for multiple C++ nodes.

  • To enhance usability, a validation system highlights valid keys in green and invalid ones in red (Fig. 1), ensuring clarity and efficiency.

CustomKeyShowcase.gif

Fig. 1

Serialization

  • Developed a template‑driven serialization framework using nlohmann::json (Fig. 1), where when a node is registered (Fig. 3) the following are created:

    • Builder - returns a factory lambda that instantiates std::shared_ptr<T> by name and ID, streamlining node creation in the editor (Fig. 2).

    • Serializer - will output the node in json format

    • Deserializer - will create the node based on the json data

  • The deserializer was the trickiest part because I had to make sure it was compatible even if the node changed in the meantime:

    • Reads basic data (ID, name)

    • Merges in default values for missing fields

    • Filters out obsolete custom keys

    • Reconstructs the node safely, ensuring backward‑compatible loading.

  • The user doesn't have to worry about serialization when creating new nodes and can focus on the functionality of the node.

Fig. 3

Fig. 1

Fig. 2

Spaceship

Personal Impact

  • This project was the one that led me down the path of tools development.

  • Seeing how much others enjoyed using it made me realize the impact a well-designed tool can have on a team’s workflow.

  • I discovered that working on tools allows me to explore multiple fields in depth, from UI and engine integration to AI systems and performance optimization.

Creating new nodes

  • Each node has to inherit from one of the three base classes (LeafNode, CompositeNode, DecoratorNode) and define the ProcessNode function (Fig. 1).

  • Nodes are defined in C++ through a simple API (e.g., AddNodePin(), AddBlackboardPin()) which allows users to construct nodes efficiently (Fig. 2).

  • Serialization and editor integration are handled automatically, so new nodes appear seamlessly (Fig. 3 and 4).

Fig. 1

Fig. 2

Fig. 4

CustomKeyShowcase.gif

Fig. 3

bottom of page