How to structure complex enemy AI?

Hey,

So I’m working on a game. Semi-intermediate Unity/C# programmer at this point I guess, been learning for a little over a year.

I’ve got an enemy character with a dictionary-based state machine, and he has a large amount of different states, as his combat behavior is rather complex. I’m working on the decision making system, basically in charge of determining which action to take under a vast array of different circumstances, and I am struggling to come up with a system that is manageable.

As mentioned, this is not a basic enemy that does a couple of things. It is a highly dynamic and reactive enemy with a multitude of different attacks, evasive actions, defensive moves and utility abilities. He can dodge, dash, shoot, stab, kick, toss grenades, slide, tumble back and forward, deploy turrets, use stimpacks and MUCH more. And he is highly reactive to the player’s actions and position and is constantly evaluating what to do in relation to what the player is doing, what his environment is like and even evaluates his own recent actions and conditions (ie. if he’s just taken damage from the player, his next action decision will take that fact into account and alter his behavior, as just one of many examples).

So in short; he’s a smart boi with many talents.

I’ve tried setting up a nested switch / if-else tree but as no surprise to anyone it’s getting very out of hand very quickly. Here’s a simplified example of a typical logic loop his AI cycles through when making decisions;

Pseudo-code:

If (player is close to me)
    if (I recently evaded an attack from the player)
        if (my health is below 50%)
            if (I am backed into a corner with no escape)

Now imagine that logic with even more options and with numerous variables for each of those conditions, compounding on each other and influencing subsequent decisions based on which specific action he’s decided to take – is he preparing to attack? Is he preparing to evade the player? Is he preparing to defend himself against an incoming attack?

Each condition sends ripples through the decision making process, meaning with a switch or if-else tree, it would require probably thousands and thousands of lines and would be a nightmare beyond reason.

How is this sort of highly mutable AI logic handled without making the programmer lose their mind?

1 Like

Usually behavior trees (BT) are used for this kind of thing where you have to design the “states” manually. But when you have such a nested and complex system maybe look into goal oriented action planners (GOAP). They allow the definition of some (nested) goals and some actions to achieve these goals and it determines with a score which sequence of actions has the highest benefit towards the goals. For both there should be some assets in the AssetStore and on Github and the like.

But keep in mind that a complex AI is a “shitload” of work to test and balance no matter what tool you use. So really easy it won’t be with any of them so you may “lose your mind” anyway ;).

1 Like

Thanks. I am willing to lose my mind over this, I just want to make sure that I do it over a structured approach :wink:

I am currently actually using a “score” based decision logic, it’s just my own kitbashed concept mix of dictionaries, enums and function-based switch nestings. It works but yeah, it’s messy to read through and will likely get even messier to debug as it expands.

I think I was just lowkey hoping I could find a solution that did not require learning another new pattern on top of all the other concepts I’m also trying to learn. But yeah, the easy route is boring anyway. I’ll put GOAP and BT on the to-do list, thanks for the suggestion.

Still open to other ideas if anyone feels like pitching in.

You may wish to consider an iterative approach instead. You’re welcome to structure it as you go, but I guarantee you will not be able to structure it in advance. That’s simply not possible because you don’t know all the issues you will need to solve right now: you will discover them as you iterate.