I would like to start today’s update by summarizing all the different features I worked on during this project. First, let’s remember what the initial idea of the project, to implement a solution for 3D Pathfinding using a Sparse Voxel Octree for representing the space and A* for finding a path between two voxels in the SVO. The main objective for using an SVO was to get an optimized way of representing the space, mainly because other approaches likes a uniform grid might incur in a heavy memory consumption. Thus, with these ideas in mind, I started working on the project.
My first step was to create the SVO structure that would hold all the data, and then generating that data, following these steps:
- First pass rasterization: check collisions at the layer previous to the last one, to determine which nodes had to be created
- Iterate from the bottom up creating all the nodes and setting the parent-child links
- Iterate from the top down, setting all the neighbor links
Visualization was a very important feature of this project, so I implemented the ability to draw the voxels in space so they could be seen in real time, as well as their identifiers and corresponding links. This was definitely of great relevance during development as it helped me debug much faster. Seriously, I can’t emphasize enough how important and necessary this is, so make sure you always have a debugging mechanism in place during your development, and also, the sooner the better!
With this, the SVO was ready for path finding and following, I implemented a version of A* that considered heuristics like manhattan and euclidean distance, and also some weight modifiers like the size of the node and the effect of the selected heuristic. With the solution in place, then I needed a way to follow that path, thus, I plugged my navigation component with Unreal’s following component, and surprisingly it was very smooth, I created a navigation task that the AI could use at any time, both in code and in blueprints.
Additionally, navigation implementation, I developed an async version of this, which would enable to have multiple agents and high cost pathfinding calls. This wasn’t exactly easy as there is little to nothing documentation on Unreal’s async tasks library, but I managed to get it working, and improvement were significant.
After that, I worked on the serialization of the SVO, so it could be baked before runtime and used until it needed to be baked again. I have to say that this turned out to be a really helpful feature, since until this point I always had to generate the SVO during runtime for my tests, adding support for serialization allowed me to work faster in general, specially for debugging purposes, where I could generate the SVO while in editor and have it drawn without having to run the game. As for the implementation side, it wasn’t that hard, thankfully, Unreal has already support for serialization, to which I only had to create some overloads for my custom data types and explicitly enable the serialization for the SVO data.
When that was done, I started working on the final big feature of the project: dynamic obstacles. I am going to be honest, it was quite the challenge, but it was definitely worth it. So the idea basically was to enable support for dynamic updates on the SVO data, because, for instance some obstacles could be moving, so they would be affecting the navigation space, and because of this, the SVO data needed to be updated accordingly. One approach was of course, to regenerate the whole SVO when needed, which could be a very expensive operation depending on the resolution of the data. Therefore, a better approach was needed, thus I worked on a solution to only update the parts of the SVO that were marked as “dirty”, keeping track of these nodes and then updating them when needed, greatly reducing the problem space and overhead. I managed to finish a first pass at this feature and the performance improvements were huge compared to the naive solution.
With everything in place, I created a small themed demo, featuring all my work on the project, which I will be showing in my last presentation. I really enjoyed working on this project, I honestly love every bit of it, and of course I learned a lot. I am really proud of the results and I hope I can keep working on things like this in the future. Speaking of future, there is still much room for improvements and new different features related to this project, for instance, to further optimize the generation of the SVO, one could stream its data, when requesting a section for the first time it is generated but then it can be unloaded when not needed and reloaded when needed, which would be much faster than regenerating that part, this would basically be an improved version of my solution for the dynamic obstacles.
Oh, I almost forgot, I made another video of the demo with a larger Pac-Man to demonstrate the ability of the pathfinding to go through or around holes, depending on its size. Here it is:

































