
System and tool
Adaptive Commander Boss
I wanted to know whether players can tell when a boss is adapting to them, so I built one that does and then measured whether anyone noticed.
- C++
- Hierarchical State Machines
- Utility AI
- Boids
- EQS
- 91.7%Player satisfaction
- 83.3%Would replay
- 58.3%Recognised the adaptation
- 7Coordinated enemy types
This was my dissertation: a boss encounter built to test whether adaptive AI is something players actually perceive, or something that only exists in the code.
How the boss decides
The boss runs a hierarchical state machine over three escalating stages, with utility-based scoring choosing between actions inside each one. It has four attacks, a slam, a throw, a stomp and a meteor, each with its own cooldown and animation montage.
A flat state machine would have worked for three stages. The hierarchy earns its place because stage transitions need to preserve some state and reset the rest, and expressing that as nesting is far clearer than as transition rules between every pair of states.
Reading the player
The system tracks player health, distance and damage output continuously and feeds that into what the boss does next. Fight it at range and it commits to closing. Burn it down quickly and it escalates sooner. The adaptation is in what it chooses, not in numbers being quietly scaled behind your back, which was the point.
Seven enemy types, coordinated
The boss spawns fast melee, slow melee, basic and advanced archers, healers and shields. Spawn placement uses the Environment Query System, scoring candidate locations on pathfinding cost, proximity to the player and tactical value, so reinforcements arrive somewhere that means something.
The swarming units run a boids implementation with configurable separation, alignment and cohesion. Flocking gives coordinated movement without central control, and it keeps them out of each other’s way while they converge on you.
Keeping it running
Off-screen agents are culled, spatial partitioning cuts the neighbour checks that flocking would otherwise make quadratic, and the heavier work is threaded off the game thread. Seven enemy types on screen at once is the load case, and every one of those optimisations was needed to hold it.
What the testing showed
Twelve players tested the encounter. 91.7% reported being satisfied with the fight and 83.3% said they would play it again. 58.3% identified, unprompted, that the boss was responding to how they played.
That last number is the honest one. Slightly more than half noticed. The rest enjoyed the fight without knowing why it felt responsive, which is arguably the better outcome, and it is the finding I would want to design the next version around.
Breakdown
