5
\$\begingroup\$

I have a game-world with a fair amount of AI that have some Senses, like vision, hearing, touch, smell, etc.

But I'm not sure how to put that information in a single place for the individual AI to then iterate over it and make a decision.

For example, each sense (emitter and receiver) currently returns a structure called a Stimulus with information like position, direction, stimulus type (sight, sound, smell, etc), npc type (human, animal, monster, etc), and so on.

And currently, the monster AI just have a hard-coded hierarchy of preference - touch (e.g., damage events) > sight > sound > smell, so if you fire a gun it'll try to follow that noise but if he then sees you, he'll switch to tracking you visually and forget about the noise.

However, this isn't very robust. It doesn't deal with repeated damage events or one player kiting or stale stimuli vs new stimuli very well. Ideally I'd want to use some sort of utility evaluation so that I can get more complex and dynamic behaviour out and I can fix edge cases where it feels like the AI isn't interacting right (e.g., ignoring stimuli that it shouldn't be).

I'm not sure how to approach that implementation. Should I just have an array of every stimulus the AI encounters and loop over that every tick? But then how do I prune that list since it'd get very large very quickly and might contain really old stimuli (currently the AI only has one "target stimuli" and new stimuli go through that hierarchy of preference before being either discarded or replacing the target stimuli).

(As a side note, this GDC Talk about Creating the Living, Breathing World of Hitman has provided some great information about how they deal with Knowledge, but I wasn't able to discern how they store it and iterate through multiple Knowledge fields of a single AI and so on).

(I'd also love any advice on the Knowledge/Stimulus data structure itself; to be modular enough to hold different types of information, instead of having a bunch of unused fields; say how a sound might need only type and direction, but a visual stimulus might only need type and position and so on)

\$\endgroup\$
  • 1
    \$\begingroup\$ The best way to implement it would heavily depend on how you're actually using this data, and there are many, many ways to do that. If you just want to store the last n stimuli, you're probably looking for a circular array, linked-list, map or just a database (each has their pros and cons). If you're not already there, I'd suggest starting by trying to get a working game with a very simple AI and iterating from there. \$\endgroup\$ – Dukeling Oct 17 at 22:27
  • \$\begingroup\$ @Dukeling that is the stage I am at currently. The AI works, this isn't theoretical, but it's not performing at the level I would like it to so I'm trying to find a better way forwards. I suppose the main thing is I want my AI to be able to take multiple stimuli (multiple gunshots going off, noises, sights) and be able to have a 'living' assessment of that information that may change based on how fresh or stale said stimuli is and the internal npc factors and so on. \$\endgroup\$ – Visulth Oct 17 at 23:33
  • 1
    \$\begingroup\$ @Visulth if you get a specific input like you mention, say, 5 gunshot sounds, 2 smells and a sighting, can you say what you want the output to be? I bet if you define a couple of these cases (with edge cases) and determine what you would want the output would be for each one, then a model will start forming in your head and implementation will be easier. If you can't tell yourself what you want the output to be then it makes no sense to even start coding anything... :) \$\endgroup\$ – Mikael Högström Oct 23 at 16:33
1
\$\begingroup\$

As you might know, it is common for ai to act and change behaviour in a Finite State Machine. This a state referes to some kind emotional state of the ai: idle, searching, fighting, running etc.
Now normally, these states are context-free. Its not important, that state of the ai changed from B to K, only that the state right now is in K.

You could use a modified version of an FSM. Lets say, the ai is idle or guarding. It is activly looking for stimuli. if it recieves a stimulus, the state of the ai may change. E.g. the Guard Orc smells something. Now, does the orc recognize the smell? Is he smelling food? Then change the state to hungry. Does he smell another orc, stay in guarding mode or whatever.

To solve your Problem of multiple stimuli, you could:

  • Only accept the hightest kind of stimuli.
    If the orc fights the character, it should not matter that he hears fighting in the distance.
  • Evalute Several stimuli based on the state
    If the orc is fighting one player, but sees 3 other players approaching, he might try to escape. Or maybe he hears a signal to retreat while fighting. But if he is not fighting, he could ignore those signals or maybe just change his state to enraged or something. For this you should definitly have some sort of hirachy list of stimuli tha the orc might recieve at every moment.

It seems like you would prefer the second solution. So now what to modify in the FSM?
An example: The orc just hears something from behind the rocks while he smells enemies from another direction. He tries to approach the place he heared the noise from, until the sound stops. Although the sound stops, he would not follow the smell to the other direction immediatly. Of course he would first look for the source of the sound, altough the sound is gone.

To do that, you could have your states with exit. These exits have conditions. if a condition is fulfilled, go through the exit to the connected next state. Now, if a state change needs a stimuli for a state change, save that stimuli to the connection edge. If you are in the next state, you can still access the stimuli, that brought you there, without the stimuli still being active.

The idea is this. The Orc was in the guard state, when he recieved the smell and sound stimuli. The sound gave him some sort of position or maybe only a direction and distance, the smell only direction and distance. When he recieves both stimuli at the same time, he evaluates the sound has higher priority and switches to "looking for sound". Even when the sound stops (so it is removed from the current stimuli list), he can still go there and check. If he does not find anything, he can then follow the smell. If on the way to the sound position he finds something of higher priority, he of course changes the state from "looking for sound" to "saw enemy" or "saw wonded ally" or something. This way, he can even go from "found wounded ally" or "Saw enemy" back to "looking for sound".

So if the orc is fighting and you have several hit detection stimuli or just when his health goes low, he can switch to the "retreat" state, but can still tell his allies, that there is an enemy following him.

As you can see, this kind of FSM does archive what you want, while it can get arbitrarily complex but also saves the needed and followed states.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.