Designing enemies
Tags: gamedev, godot
Published: 2024-02-08 11:35:00


In this article, I'm going to share my thinking / design process for the human enemies on the game I'm working on (Vectoria) 

I probably need to make another post telling a bit more about the game. For now, you just need to know it is a platformer ambiented on a space cruiser where the main characters uses a jetpack and have a laser gun.


![An IA generated cover for the game](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek7atci15j40ptmuyjly.jpeg)

---

## The prototype

To start with, I wanted to be able to have something to test on as quickly as possible. So for [the prototype](https://tehsis.itch.io/vectoria), I just copied most of the main character asset and made the enemy start to shoot as soon as it approaches (ie. enters a collision area)


![A prototype representation of the main character and the enemy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7snu8pnhnpha343knts.png)

This was… not very good. The player could just fly and avoid the battle all together.
So I made the enemy a bit smarter: it jumps if detects that the player is not on the floor. Now the battle was not avoidable.


![Sketch of the enemy jump when player flies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0s4ou8zhmkki6457lh6g.jpeg)


That was it for the prototype really. The simple “AI”[1] allowed me to test it with some friends and see how they react: On most of my tests, they found the battle engaging enough. Although it's worth mentioning none of them replayed the game.

## Now on the real game

Out of the prototype, I already knew I wanted my enemies to be smarter and keep iterating on how they behave. So while I would just mimic the same behavior as for the prototype to start with, I made it more modular and simpler to extend and modify utilizing a [Finite State Machine (FSM)](https://gameprogrammingpatterns.com/state.html)

The first state (Which I called _Idle_) was simple: the enemy won´t do anything, just wait for the player to appear.


![A Finite state machine with a single "Idle" state](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bq5ovafakovnjwajqg0.png)

Once the player approaches the enemy, it will start to shoot every fixed amount of time. This was the “Attack”  State.


![An FSM with an Idle state that transition to attack if the player approaches](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1koa5qja4nz5rarclsen.png)

And, of course, if the player tries to flight over the enemy, it will jump and get back to Attack.


![A new state "Jump" State is added. Enemy transition to it from Attack when the player flies.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b6z1e960djomub4vllpw.png)

Good, I was back to the prototype state, but now with a simpler way to extend the enemy “cleverness” (The source code for the prototype was a real spaghetti).


![Godot interface with a State Machine Component node and the three states mentioned as children](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h98ipnjm7m65v31ljhnp.png)

Once again I tested it again with some friends…. It was good, most people won’t try to _cheat_ on the very first try, but I want these enemies to be repeated several times, and after the first encounter, most people realized a few _simple strategies_ to just kill them without a problem:

1. Fly and shoot
2. Attack from a far distance
3. Shoot indefinitely 

These needs to be fixed, I do want this enemies to be simple enough to not being frustrating (remember there will be a lot of them) but also I don’t want them to be _trivial_ to kill to be boring (and so keep the player in [the flow](http://whats-in-a-game.com/controlling-flow/)).


![A graph representing the flow state which grows in balance with skill and difficulty](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wx4m815d3bps1raf34m.png)

To fix fly and shoot, I decided to make a key change that also affects other parts of the game but also makes a lot of sense: If the main character is holding the gun, they can’t manipulate the jetpack at the same time. This also affects the level design (which maybe deserves a different post) opening new possibilities and challenges, so I was happy with it.

For the second issue (**Attack from a far distance**) I thought of providing some way to deflect the lasers. Adding a shield (or a lightsaber) would probably make the combat a bit more interesting, but don’t align a lot with the plot of the game (again, that's for another post). Also, it would probably complicate things to a whole new level. So I just made the lasers to deflect each other. If a laser enters the player detection area, the enemy will shoot to deflect it. To make things a bit more interesting, the enemy will walk forward to try to see who’s shooting.

![A FSM representation of the above mentioned states](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/klawqvm770wghzmhecff.png)

Finally, to fix the **shoot indefinitely**… well, I needed to make it so the player just can’t do it. The gun already has a “pulse the trigger effect” (ie. the player can only fire every 0.5 seconds) but since now the lasers can be used to deflect lasers, you can just hit the trigger like a maniac, and shoots will eventually impact the enemy.
I needed some _bullets_… but this add **more balancing problems**: I'd need to make sure the player won’t just deplete their bullets and then not be able to advance the game. Some games fix this by giving you a weaker weapon that you can use indefinitely (like the knife in [Resident Evil](https://en.wikipedia.org/wiki/Resident_Evil)) or some areas where you can recharge (Like [Metroid Dread](https://en.wikipedia.org/wiki/Metroid_Dread)). 
The knife might be good but the gun is also used to open some doors and won’t make a lot of sense to open the doors with a knife.
Recharging areas, on the other hand, requires players to fly away from the combat to get to one of those areas. Given the enemies here are humans it would be unrealistic if they just let you go away… and adding a chase & attack system like in [The Last Of Us](https://en.wikipedia.org/wiki/The_Last_of_Us), would turn this on a completely different game.

Turns out the fix was already there… The jetpack already requires a _cooldown_ period if you try to use it for a long period of time. The laws of energy for this game are already settle so why don’t reuse it for the gun?
That’s it! The gun now has its own energy bar. Same as the jetpack. And given that now you can only use one of the two, makes sense they share the same energy.
This finally makes the combat a bit more interesting… If the player shoots indefinitely, they won’t be vulnerable as they can’t deflect attacks and won’t be able to fly to avoid them as they need the energy to power the backpack as well.

To sum up this combat system: The player has to shoot to attack the enemy and avoid shoots from the enemy.
For the latter they can shoot to deflect the lasers or fly to avoid them. Both actions take energy so they have to be smart enough to make good use of them without running out of energy and left vulnerable to the enemy’s attack.


![Final representation of the FSM with all the mentioned states](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dqadb8hrnb16yudrf2lx.png)

As a last touch, enemies now can have some _personality_ as they can shoot with different _strategies_: shoot on different times, only shoot to deflect, jump and move to difficult aiming or any combination of these.



![In progress game image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jpo02uuptela9brwem2.png)

Will I stop there? I don't really know. For a minion like enemy I do think this system is good and fun. I do have in mind a few _bosses_ which will require more tuning, but that's for another round. Now I do have what I need to build a few levels and keep testing.

If you want to talk about Video Game Development and design, reach me out on X at [@terradillospab](x.com/terradillospab)

[1] In the chatGPT era, calling a thing that shoots every certain time and jumps when you jump an AI seems way exaggerated… but it is what it is.