dealing with a multiplicity of AI states

Started by
20 comments, last by IADaveMark 8 years, 4 months ago

game: Caveman 3.0

FPSRPG

seamless
open world
sandbox
survival
paleolithic setting
emphasis on realism
single player
1pv / 3pv

the latest addition to the rules for animal behavior is that animals flee from fires.

this leads to a "fleeing from fire" state, to go along with all the existing AI states.

some states are mutually exclusive, some are not.

states are prioritized, so using a single AI state variable with a state stack is possible.

multiple AI state variables (IE flags) is another approach.

i started with a setstate/runstate type architecture with a single AI state variable.

i've moved to a design that uses multiple AI state flags, and find it a bit more flexible.

but now i have a ton of flags.

and now it looks like i have to add another one for "fleeing from fire"

IE if fire within 50 feet, set "fleeing from fire" flag, set "flee from fire" direction, and init "fleeing_from_fire" counter to zero.

if "fleeing from fire" flag is set, turn towards "flee from fire" direction, move at max speed, inc counter, if counter >= max, clear "feeing from fire" flag.

i have 13 types of AI, and there are probably half a dozen of these types of flags. the total number of possible setstate/runstate type states for one type of AI is probably somewhere between 10 and 20. total unique states for all 13 types might be 40 or more. i'd have to count.

any good way to handle this?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement

This doesn't really help your overall problem, but you could have a generic Fleeing from X state, as it seems like fleeing from fire would be the same as fleeing from a rampaging woolly mammoth. If you have unique bark strings / shouts for fleeing from fire over fleeing from a woolly mammoth, you could reflect that based upon what the AI is fleeing from.

object AI deals with behavior based on external situation and internal working state

'state' data can be several different things

How many independant effects are there which indicate what currently is externally active upon the object (its situation)? Evaluating these may modify how/which behaviors (goals/actions) are specified/activated. If they are not constantly redetermined (reevaluated) then they may need to be cached (flags/data) and others temporarily maintained (like a target/threat list) while being evaluated.

How many 'goals' can an object have simultaneously which are determined by an object's situation?

These must be prioritized/selected from to determine the current behavioral activity of the object.

High level goals may have sub goals (their own state machine and data)

How many behavior actions do you have which are dependent and cannot be done simultaneous and one must be picked at any point in time?

These can have a single behavior ID variable and a 'union' of pertinant state defined variables

--------------------------------------------[size="1"]Ratings are Opinion, not Fact
Decision making has three principal components:

- Things I know about the world around me
- Things I know about myself
- What I do about the first two


Let's take the example of running from a rampant fire:

- I know there is a fire in the world near me
- I know I fear fire
- Therefore I can choose to act in a way that removes me from the presence of the fire


Organize your data such that these facts are accessible in distinct locations. You should have data that knows about the world state. You should have data describing how a character is likely to respond to various stimuli. And then you should have code that combines the two and produces a decision.


I'm a big fan of utility-based reasoning for this kind of thing, because it scales very well with the number of unique inputs (in both categories) and can easily produce a believable output (decision) regardless of scenario complexity.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

perhaps a concrete example to look at will help.

i'll post one once i finish the round of changes i'm currently working on.


This doesn't really help your overall problem, but you could have a generic Fleeing from X state, as it seems like fleeing from fire would be the same as fleeing from a rampaging woolly mammoth.

as a quick and dirty implementation, i hooked up the new "flee from nearby campfire" behavior to the flag, direction, and counter variables for "flee from incoming missile fire of unknown origin".

of course, technically speaking, "if within 50 feet of a campfire, run the other way for a while", only to turn right back around and try to approach the player near the fire again, is not what animals would do. guess they'd get to 50 feet and stop or something like that. or perhaps circle at a radius of 50. but that's behavior, not implementation.

perhaps its just a case of lots of AI states means lots of vars to track things. or perhaps some consolidation is possible.

i'll post an example, maybe someone will have some suggestions.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

I think what people are pushing at is that your approach of "lots of vars to track things" is untenable and highly inefficient as the number of inputs and decisions scales.


You need to bucket information into "stuff I know about the world" and "stuff that defines how I behave." Then introduce a single logic layer that looks at both sets of information to make decisions.

Pleasantly, "stuff I know about the world" is usually shared data across many actors, so you only need one world representation to store it. You then filter the world representation through the "personality" data to yield a decision. Concretely: a fire might be "pleasant" to a lava golem, while it is "dangerous" to a rabbit. Same world representation (fire exists here) filtered through different preferences yields different decisions (move into fire vs. move away from fire).


Decisions can be pretty granular. You don't really need five ways to represent moving to a new location, for example. You might tag the movement with animations at the moment of deciding to move, but that's presentation polish, and doesn't need a lot of internal simulation state.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


You then filter the world representation through the "personality" data to yield a decision. Concretely: a fire might be "pleasant" to a lava golem, while it is "dangerous" to a rabbit. Same world representation (fire exists here) filtered through different preferences yields different decisions (move into fire vs. move away from fire).

Gee... this sounds oddly familiar.

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!"

ok, here's a concrete example.

these are the current "rules of behavior" for predators in Caveman 3.0, stuff like saber-tooths and such:

1. select target: closest detected PC, NPC, or animal of different species.

2. if cornered (surrounded bya combo of terrain and / or other entities), attack.

3. if in collision recovery, do collision recovery

4. if not in collision avoidance and obstacle ahead, go into collision avoidance mode

5. if in collision avoidance mode, avoid collision

6. if taking incoming missile fire and have a target, attack.

7. if taking incoming missile fire and don't have a target, go into "flee from missile fire of unknown origin" mode <g>.

8. if in "flee from missile fire" mode, flee from missile fire.

9. if half dead and have a target, flee

10. if have a target, and range to target is <= 20 ft (a nearby threat): if the target is stronger, flee - else attack.

11. if not fleeing from nearby campfire, and near a campfire, go into "flee from campfire" mode. // this is the new rule i just added

12. if in "flee from campfire" mode, flee from campfire // this is the new rule i just added

13. if fatigued, rest

the above rules are common for all non-avian AI's except for the "maintain distance" AI used by things like proto-horses. the game has 13 types of AI altogether.

the following rules are the ones specific to predators, they are applied after the common AI rules, if no common AI rule has yet been acted upon:

14. if hunting, and there's a carcass nearby, turn to the carcass. if more than a few feet away, run, else stand. once they're standing at the carcass, after a random amount of time, they will "finish eating", which switches them from "hunting" mode to "graze" mode.

15. if hunting, but no carcass nearby, and have a target, attack.

16. if hunting, but no carcass, and no target, switch from hunting mode to graze mode.

17. do graze mode. graze mode transitions at random between the following states: stand, wander, flock, and migrate (in the case of a "leader" of a group). after a random amount of time, the animal will "get hungry" and switch to "hunting" mode.

so i have variables for

target type (animal or human)

target ID number

range to target

"in collision recovery" fag

collision recovery direction (what direction to move to recover)

collision recovery counter (how many updates they've been in collision recovery)

"in collision avoidance" flag

collision avoidance moveto x (where they should move to to avoid the collision)

collision avoidance moveto z

"taking missile fire" flag

taking missile fire direction (what direction to run from missile fire of unknown origin)

taking missile fire counter (how many updates they've been running from missile fire of unknown origin)

hit points (for "is half dead?")

damage (for "is half dead?")

"fleeing from campfire" flag (at the moment i'm using the flee from missile fire variables for flee from campfire).

"flee from campfire" direction (at the moment i'm using the flee from missile fire variables for flee from campfire).

"flee from campfire" counter (at the moment i'm using the flee from missile fire variables for flee from campfire).
fatigue (for "if fatigued, rest")
"is hunting" flag
graze AI state variable (stand, wander, flock, or migrate)
wander direction (what direction to wander off in)
wander counter (how many updates they've been wandering)
its was having to add yet another flag, direction, and counter for "flee from campfire" that prompted my original post.
note that a lot of them are the "flag, direction and counter" pattern (so to speak). with "flag and target x,z" being another "pattern" used.
i suppose i could determine all the mutually exclusive states that use the "flag, direction, and counter" pattern (so to speak), and just use a single flag, direction and counter for them all. that would simplify things somewhat...
basically i'm using rule based decision trees to create "expert systems" for each of the 13 AI types in the game.
is there another approach that's going to be less complicated?
in the past when i've looked at other methods of implementing a set of behavior rules such as the one above, none has really struck me as being simpler or better.
also, a lot of folks seem to swear by planners. would a planner be appropriate for implementing the above rule set?
if so, how? for some reason, i;ve never quite gotten the idea of how they work. maybe i just haven't read up enough on them. but the examples i've seen don't really seem to fit well with implementing rule sets like the one above.
a simple example of how a planner would implement even just a couple of the rules would be greatly appreciated.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

I see the cases can be broken down into three behaviours: Attack, flee and collision response.

Is the problem that the decision system (if..then..else) is becoming unwieldy because of too many cases?

I mean, if you really want to hard code all your logic, sure.


But there have already been several suggestions for how to do that in a much more maintainable and scalable fashion.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement