🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Applying Utility AI to different situations - how granular can/should I go?

Started by
8 comments, last by IADaveMark 5 years, 11 months ago

I'm playing around in Unreal Engine with intention to create some kind of a small town scale Sims-like simulation. I don't need that much micro-managing as in Sims.

At first, I want to start with a bunch of simple NPCs that walk their route (using NavMesh, most probably) between work and home, based on time of day. But, depending on different factors, NPCs might choose to visit a shop or a cafe while on their way. Also, there are different jobs that require some flexible behaviors for cases when I closely follow an NPC or interact with it. Unreal Engine has Behavior Trees for AI but I find it somewhat limiting for my purposes, therefore I started looking into Utility AI.

Currently I'm watching the GDC lecture videos about Utility AI and trying to figure out how do I go about implementing it in Unreal and to apply to my sandbox-like simulation. 

By the way, are there any Utility AI code projects that could be plugged into UE4?

As my town will have many citizens (hundreds? thousands? the more, the better, as long as my PC can handle) and I want to track them all on a world map (just dots), I would like to make it work efficiently. Of course, I will turn off animations and meshes (with their collisions and physics) when an NPC gets offscreen. But what about AI? How do I switch to narrower set of parameters and actions to choose from when NPC is offscreen? And does it really matter in practice? Should I leave the AI evaluating all the possible action scores and apply some checking only inside the action itself (if NPC is offscreen, then I do simple waiting for some sensible time instead of doing the full simulation)?

These thoughts led me to some other questions and ideas that might be useful for optimization, but I'm not sure how they would work in practice. So, I hope somebody else has already thought about this and tried it out and can share the experience.

In essence, the idea is a new abstraction I call Situation. It could also be considered just some kind of a context, but that word is so overused, that's why "situation" was my choice. 

Basically, a Situation is something like a filter that contains a predefined (at design time) set of parameters and actions that are available, adequate and make sense at the particular Situation. For example, if an NPC enters a cafe, there is no need to continue evaluating the entire list of utility actions for being on a street or at a workplace. I don't want an NPC to decide that it should start running home as soon as possible (because of some not so carefully tweaked parameters) while waiting for an order in a cafe. Instead, I would want to make such action not available in that particular situation. Less actions to choose from = less parameters to tweak to prevent an NPC from doing something totally weird, right?

I guess, this could also be visualized as a tree of utilities. Or it could turn into a hybrid of utility AI (for high level actions, like "Where should I go next?") and behavior trees ("What sequence of predictable, adequate actions I should attempt to perform while being in this situation?"). But I would like to avoid mixing multiple systems just to keep it less confusing. Or am I totally wrong here and I shouldn't attempt to use Utility AI for cases when an NPC should be very predictable, almost following a well-known scenario?

Next, I was wondering, how an NPC would enter/exit the situations. How do we, humans, limit ourselves to some subset of activities to avoid doing something stupid "just because we can" or "I really wanted to do that at that very moment, even if that was highly inappropriate"? I guess, we do that based on our reaction and reminding about the environment we are in. "Hush, you are in a church now" - a mother reminds again and again to a child who starts to become too active.

The rough idea is as follows.

Unreal Engine has good environment query system and I can leverage that. Although, for performance reasons, I'll try to do it in reverse to human sense. If a human being sees a cafe and enters it, he/she is doing the query: "Am I in a cafe now?" In my case, it might be the cafe itself (through a trigger volume) triggering an event on the NPC: "You are in a cafe now." and NPC has the logic: "I should limit my activities to something I can normally do in a cafe and completely forget actions that are not sensible in a cafe."

And when the NPC exits the cafe, it again receives a trigger volume "exit" event, which in turn removes the filtered restrictions and allows to execute evaluation of the full set of actions.

If we assume that an NPC can be only in one situation at once, it looks like a simple stack with push/pop. Enter the cafe? Push the list of cafe actions and run utility AI evaluations on them. Exit the cafe? Pop the action list and now you are where you were before (with possibly some updated state parameters - you spent some money in the cafe and you reduced your hunger).

But is it good enough? Can there be a combination of situations where I need a set of actions for multiple situations at once? In this case my idea breaks down because a stack is not enough anymore. So, trying to combine multiple situations can get messy really fast and I'd better go with evaluating the entire list of utility functions instead of trying to combine all those multiple situations. Still, I could use this approach in cases when I 100% know that I need a limited set of actions.

What do you think about this rambling? Am I overcomplicating things (actually, because of trying to simplify them through not evaluating entire set of utility actions all the time)?

Advertisement

Oh geez... this is going to take me a while. Before I start, have you seen my GDC lecture with Mike Lewis about what we did at ArenaNet with my IAUS?

http://www.gdcvault.com/play/1021848/Building-a-Better-Centaur-AI

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

Oh, thanks, I somehow missed that one out.

Now looking at the Decision Maker Packages section, it seems totally relevant to what I was talking about, and it even mentions "situational packages" on the slide. Except that in the video it is more about pushing additional decisions to the stack of currently available decisions (and popping it off when not needed) instead of limiting the full list. But at the end it achieves the same purpose - optimization through limitation of available decisions. Which means that my reasoning about that "situational stuff" was not that bad as I thought.

So, there's just one crucial piece to implement - decisions for pushing/popping new decisions (almost getting recursive here), when reacting to a situation. And how to wire it all into Unreal Engine...

The other thing you mentioned is how to handle LOD for stuff off-screen. Easiest way is to pipe in a check to see if they are on screen or within a certain radius of the player to a boolean consideration of a behavior you don't want to run in that case (e.g. an emote animation). If they are not, then that behavior gets multiplied by a 0 consideration score and switches off the behavior entirely. That way, you can limit what is being processed to relevant stuff (like movement to a different location).

As for speed of use with hundreds or thousands of agents...  let's just say it's not an issue if you do the priority "early out" scoring the way we illustrate there. 

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

As for "wiring it into the Unreal Engine", your decision AI system should be a black box that has nothing to do with what engine you are on. The only thing that needs to touch the game engine is inputs and outputs. But you have to do that regardless of what environment you are in.

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

I guess I secretly hoped for some lazy option - like a GitHub project in C++ with full documentation and examples, that can be dropped into Unreal Engine (or any other engine). A quick GitHub search found only C# projects of good quality (and some of them more or less tied to Unity). C++ - not so much luck.

Anyway, I could port something from C# to C++, unless the original code is too "C#-specific" and architecturally complex. https://github.com/apoch/curvature seems really good starting point.

I've got both my IAUS and Imap system in C++ and C# because of my work with different clients, but it isn't in shape to put up as "middleware".

BTW, Apoch's Curvature is based on my IAUS and the work we did when I was at ArenaNet.

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

Thanks, so, I guess Apoch's Curvature is the best I can get at this moment. I started experimenting with it, works nicely; still lots to learn to comprehend its possibilities and integrate into Unreal.

I'm trying to get to the point where I can sell and/or licensce my IAUS and Imap system (e.g. on Unity Asset Store). I've had plenty of people and companies ask me about it.

The GDC accident has set me back quite a bit though. ?

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

This topic is closed to new replies.

Advertisement