What should a generic layer AI code contain?

Started by
2 comments, last by 7th_dragon_knight 4 years, 5 months ago

This question is less about AI and more about the code structure for approaching AI. I understand FSMs and use it heavily for structuring my AI code in my top down ARPG. But I also want unique behaviours for each enemy. Coding those individual states is not the problem. You have to code individual FSM classes for each enemy type. That means a considerable amount of duplicate code.

Ex: Enemy A and enemy B will both initially chase the player. But enemy A will transition to a charging attack when the player gets too close but enemy B should do a ranged attack. This means I need two chase states that do the same thing but the need to transition to different states. Surely there is a better way.

I've tried modularizing it by making attacks a separate thing/class and making each enemy have a list of attacks it chooses from. But then there is another problem. If I want an enemy to transition to X state after performing Y attack, it isn't possible easily.

I feel like I'm missing something here. Where should the line for the generic AI FSM code be drawn and what parts should made nodular for each enemy AI? Should I even bother to do so? I am sorely tempted to just duplicate the code and leave it be.

Also, all of these is based on my experience with Unity. I'm not sure how other engines handle AI code structure. Maybe you can help me out with your perspective.


Advertisement

You seem to be thinking about things in an odd slice pattern.

AI has "compartments" of:

  • knowledge representation
  • decision-making
  • behavior execution

Much of the KR layer is going to be the same for all types of agents.

Much of the execution of behaviors is going to be the same for things they do in common. e.g. "move to XY" is a simple command that puts a destination into the movement system. It doesn't matter who you are in large part.

The only part that differs is the decision-making process. That is, why does the sniper do QWER and the tank do ASDF? They would be accessing much the same KR layer (where enemies and allies are, for example) and "face", "move", and even "attack" can be boiled down to a single behavior. (The manifestation of that behavior might be different for a sniper shooting vs. a flame-thrower shooting, but in essence it is still a ranged attack.)

The reason you are unable to get around duplicating code is the #1 issue with FSMs. Lose them. In fact, the entire decision-making process isn't held in the "brain" of the agent... it is held in each individual state.


Do something different. Behavior Trees and Utility systems have been the go-to architectures for 20 years.

Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC
Professional consultant on game AI, mathematical modeling, simulation modeling
Co-founder and 10 year advisor of the GDC AI Summit
Author of the book, Behavioral Mathematics for Game AI
Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

IADaveMark said:

You seem to be thinking about things in an odd slice pattern.

AI has "compartments" of:

  • knowledge representation
  • decision-making
  • behavior execution

Much of the KR layer is going to be the same for all types of agents.

Much of the execution of behaviors is going to be the same for things they do in common. e.g. "move to XY" is a simple command that puts a destination into the movement system. It doesn't matter who you are in large part.

The only part that differs is the decision-making process. That is, why does the sniper do QWER and the tank do ASDF? They would be accessing much the same KR layer (where enemies and allies are, for example) and "face", "move", and even "attack" can be boiled down to a single behavior. (The manifestation of that behavior might be different for a sniper shooting vs. a flame-thrower shooting, but in essence it is still a ranged attack.)

The reason you are unable to get around duplicating code is the #1 issue with FSMs. Lose them. In fact, the entire decision-making process isn't held in the "brain" of the agent... it is held in each individual state.


Do something different. Behavior Trees and Utility systems have been the go-to architectures for 20 years.

You are absolutely right about me trying to modularize the wrong things. I've only been thinking about enemies in terms of what attacks they have without realising that that's not the only difference.

I have dabbled with behaviour trees in the past. They were really good at the execution part but it was hard to write the logic part in the behaviour tree. That may be due to the free tool that I used not having a good method for representing environment data.

I am somewhat tempted to write my own behaviour tree system. Writing code for decorator nodes is not very hard. But how should the Knowledge Representation part be like? Not all enemies care about the same things. In that case, should the blackboard representation be a dictionary/hashset so that I don't need to code every blackboard variable separately? Is that the normal way of doing things?

This topic is closed to new replies.

Advertisement