Kenechukwu Umelo
Technical Game Designer | AI • Gameplay Systems • Open World • XR

I previously took a Gameplay Engineer Test for a game company where one question required me to build a "Boids" system originally developed by Craig Reynolds in 1986, using Unreal Engine 5. At that time, I didn't progress as far as I had hoped, so I didn't get the role. After completing an extensive Unreal C++ course, I revisited this challenge to demonstrate what I had learned from it.
As someone who enjoys emergent gameplay and behaviors in game AI, I considered this project a personal showcase of my growth since my initial attempt.

Question Prompt
A School of Fish
A Swarm of Bugs
Implementing Flocking Rules
With resources available detailing the flocking algorithm. This source included tons of pseudocode and methods for implementing a "boid," which helped me get started. Since I was working in a 3D space, I began by having the boid move forward within set boundaries.
Boids always travel forward, but I set up the Boid Manager to randomize their facing direction each time at Start.
Once that was established, I implemented the three core flocking rules into each boid individually in C++. Funny enough, after implementing these rules, I found that combining the cohesion and separation values gives the best results for "schooling" boids that the prompt asked for.
Here are all the code samples for separation, alignment, and cohesion below:
1. Alignment (Boids steers in the same direction of their neighbor)

2. Seperation (Boids trying to steer away from one another)

3. Cohesion (Boids steering towards the center of their nearby neighbors)

Obstacle Avoidance
With the rules of flocking implemented, the next challenging step was to avoid obstacles. Obstacle avoidance consists of a large number of raycasts pointing in several different directions. When the boid is near an obstacle or collides with it, the raycast generates steering directions toward or away from the obstacle. This process is quite similar to how Unity manages obstacle avoidance with its NavMesh Agents.
During my research, I came across a Stack Overflow thread that helped me set up a sphere of points evenly distributed around the main points to initialize the tracing directions. Since this was the last piece, I researched examples of this code in C++ and had to reuse the logic from this source, even though I didn't fully understand all the math details.

Logic generating avoidance rays around a boid
I implemented avoidance steering detection logic by utilizing a straightforward line trace and a dot product to limit the view angle. I realized that using the actor's forward direction and position would be the simplest method to establish an effective view angle for the avoidance steer vector. As a result, I was able to get the avoidance working, but I added extra speed here to improve steering, since it the avoidance vector slowed the overall velocity vector.
Obstacle avoidance example

My approach to determine best avoidence steering direction
Code Samples
Boid.h
Code below contains functionality header for the boids.
Boid.cpp
Code below contains functionality for boids movement.
Post Mortum
Potential Improvements
-
Add Debugging Tools
-
The lack of debugging made it difficult to test whether the flocking rules were working, whether boids would exit bounds, or whether their speed would remain clamped. I was able to implement line-trace debugging late in development, but I aim to do it early for any systems I work on.
-
-
Polished Boid Manager
-
The boid manager was built primarily in C++. I had difficulty using child blueprints to create separate scenes, primarily due to the UI, which made it hard to configure the flocking-rule sliders without causing crashes at times. Looking back at the script, I realized the lack of fail-safes (return calls) I don't include for out of range limitation on the scripts.
-