Understanding AI Logic from the Bottom-Up

Alex J. Champandard on August 2, 2007

At the base of any game AI system, you’ll find actions and conditions. They’re not only the interface to the virtual world, but also the foundations of the whole logic.

Looking at an AI system from this perspective makes things a lot simpler when designing the system, because it helps you focus on the essence of the problem.

Execution of Actions

Figure 1: Interface between the game and the AI logic.

The Lowest Level

When you think about abstract concepts like “behaviors”, it can be hard to wrap your head around the logic. But thinking in terms of actions and conditions bring you back to the software execution level. Specifically:

  • During an update, a chunk of code (like an action) is either executed or it’s not. It’s that simple!

  • All fuzzy concepts like doing something slightly, with difficulty, or half-heartedly are parameterizations of a running behavior.

So on this level, it’s completely clear what the choices are; it’s a matter of selecting which actions to start. Then when an action terminates, one of two things happen:

  1. A flag indicating “I’m finished” is set from the return status.

  2. An observer is is dispatched, providing the same termination status.

The question is, who’s responsible for dealing with what happens next?

A Chain of Responsibility

A consequence of looking at things from the software perspective is that there’s always one thread of execution responsible for any lower-level behavior. This can be considered as a strict hierarchy:

  • The top levels behaviors execute the lower levels, so there are no ambiguities or conflicts.

  • Decisions made by consensus or voting are still executed by only one arbitrator.

Modeling this chain of responsibility, like a call stack in programming, is very useful to understand relationships between behaviors. It follows the nature of control flow in software.

Execution of Actions

Figure 2: A hierarchy of behaviors for an action game.

Typically, the owner sets up an observer when executing a lower-level action, which provides a callback when it’s done. Then, the owner has the choice of:

  1. Handling the situation locally, or

  2. Passing back control to the next level.

This is very useful during design, as you can model the logic from the bottom-up, identifying precisely which callbacks may occur, and handling these in a hierarchical fashion. Have you used a similar approach when designing your AI logic?

Discussion 5 Comments

leghan on August 3rd, 2007

I dont undertand well if you are describing an architecture where there can be parallel behavior execution or not. If you allow multiple behaviors (so you have multiple threads of actions execution) then you cant way that there will be no ambiguities or conflicts. As you have mentioned in other articles, el parallel behaviors are essential for having a flexible and powerful AI Arquitecture, so the problem of conflicts is a very importante issue to deal with. When looking at running actions, several things can happen: + The action can finish by itselt and so notify it to the caller (via polling or by observers) + A conflict is detected and the actions shoult be terminated before they ends (example: we see and enemy while doing a talking action) So the actions shoult have a way of interrupting them, and the same can be extended to abstract behaviors in general. Any running behavior need to offer a way of interruption to its caller, so the caller can deal with conflicts. The difficult part arises when deciding the conflict resolution rules. Here you can apply priorities. Priorities is a flexible way to label actions and behaviors with a sense of relevance. But having a hierarchy of behaviors makes the problem much difficult to solve when a conflict appears, because you can end up with a hierarchy of priorities... Its indeed a non trivial problem to solve in a general way I think :)

alexjc on August 3rd, 2007

Angel, Yes, that's a great point. I didn't mention concurrency in this post, but you're right, it does make things somewhat harder to deal with! But I don't think it adds any "conflicts" per-se. There's still only one thread of execution responsible for starting any concurrent behavior, so the structure and control-flow is still hierarchical — just parallelized. When any behavior terminates, there's only one owner responsible for dealing with that, regardless of other concurrent behaviors. So each behavior has to take into account multiple other running behaviors when making decisions, but that's just more information, not necessarily a source of conflicts. That's a bit like how Erlang works, and it seems rather successful at it! Alex

leghan on August 3rd, 2007

Well, when I refer to "conflicts" I meant that when you have parallel behaviors running, you may want in some case start a new behavior that is not compatible con some other behavior already running. Then you have several options: + forget the new behavior and try something else. + check if the new behavior is really more important than the other behavior so as to stop (or inhibe) the running behavior and let the new behavior execute freely. Lets put an example. You may be executing a branch in your tree that is doing an attacking behavior. You may have another paralel behavior, maybe in a different tree branch, responsible for player orders. If any order arrives, and its response is incompatible with the attacking behavior, you may want that the attack behavior stops, so the response behavior can execute instead. Maybe the response is compatible con the attacking, and there is no need to stop the attacking (por example the response can be any spoken information). I think It whould be desirable to have a general way of managing this type of "conflict resolution" so as to reuse it easily. And with somekind of "Priority" and "inhibition" mechanisms, you could for example interrupt temporally the attacking behavior, and when te orden was responded, switch back to the attack.

leghan on August 3rd, 2007

Sorry, I put a little bit of spanish stuff in the comment above :) wherever I write 'con' it means 'with'...

krinosx on August 6th, 2007

And where you write "POR EXAMPLE" is "for example".. heheh About the POST: This view of the AI is very simple... and very "didatic"... a simple line of execution... with some diferrent states.... I have alredy said I´m working with Enterprise Applications... I´m not in Game market YET... but it is what I wish... anyway... I´m taking notes of your examples... and will try to implement a kind of "intelligent" business application... like a BI application that could suggest somethings using some kind of AI... lets see whats happen.. :)

If you'd like to add a comment or question on this page, simply log-in to the site. You can create an account from the sign-up page if necessary... It takes less than a minute!