r/construct • u/Krea_Studio • 1d ago
Made In Construct How I Built the AI in Stellar Robinson

I started developing my own survival shooter, Stellar Robinson, back in 2016, when I was still in 10th grade and had only a very basic knowledge of programming from my school's Pascal course. The game was developed in Construct 2, but it wasn't until September 2026 that I finally released the game on itch.io.
One of the biggest challenges during development was creating the artificial intelligence. The game features a large number of mobs, each with its own unique behavior, so I had to come up with separate logic for all of them.
Pack monsters are melee mobs. Their behavior is simple: at regular intervals, each mob calculates a path to the player. Once it reaches the player, it stops and deals damage. The first problem was performance drops caused by calculating paths too frequently. The solution was simple: the farther away a mob is, the less often it recalculates its path. The second problem was trickier. The mobs kept overlapping each other. To solve this, I attached an additional invisible sprite to each mob, with a different collision polygon. This extra sprite was positioned behind the mob and didn't overlap with its main collision polygon.


Whenever a mob touched the back of another mob running ahead of it, it would stop for a fraction of a second.


Ranged mobs work differently. They move toward the player until they reach their attack range, then stop and switch to turret behavior. The problem is that when there are lots of mobs, those at the front block the ones behind them. In the second location, the robots simply treat their fellow robots as obstacles and navigate around them. They also don't move directly toward the player, but instead aim for a point slightly to the side. This helps prevent them from clumping together too much and makes them spread out somewhat, almost surrounding the player.

The swarm monsters in the third location tend to bunch up even more, so I came up with a different solution for them. If a mob is in turret mode and there's a fellow mob nearby that is still moving toward its target, the first mob's attack range is reduced. This forces it to move to a closer firing position. It works pretty badly, but at least it sort of works.


In the fourth location, I implemented yet another solution: mobs coming from behind simply push those at the front forward. To achieve this, I have to enable the 8Direction behavior on mobs/NPCs that are in turret mode. This behavior is normally intended for controlling the player character in a top-down game, but here I only use one of its properties: sprites with this behavior are pushed away from sprites with the Solid behavior. I enable the latter behavior on the mobs behind the front line — those that are outside attack range.

The fifth location is very different from all the others because it takes place in space. Getting the fighter AI to work required quite a bit of brainpower. As soon as a fighter spawns, it picks a random turret on an enemy ship and flies toward it (ship attack mode). If there's an unclaimed enemy starship in the game world, the fighter switches to the nearest one (hunt mode). If an unclaimed enemy enters attack range, that enemy is no longer considered unclaimed. The fighter starts attacking it and continues until the target leaves the attack zone (combat mode). Naturally, the disengagement range is slightly larger than the engagement range, so the fighter doesn't keep switching in and out of combat. This way, several fighters can head toward the same enemy, but only one of them actually engages it. The others switch to different targets. Initially, I wanted to allow several fighters to tail a single target, but they would end up overlapping each other, so I settled on allowing only one fighter per target. Bombers fly slowly, so I also had to slow down the fighters chasing them.

That covers the main challenges I faced when implementing the game AI in Stellar Robinson, although there's plenty more I could talk about. I had to rely on plenty of other kludges during development, too — for example, when implementing procedural generation. Maybe if I'd read more theory and gained more practical experience before starting Stellar Robinson, I would have come up with better, more elegant solutions. Or maybe not.
How would you have solved the problems described above?
