Utility AI (Discussion)

First there is article on Gamasutra for reference.
Are Behavior Trees a Thing of the Past? - Gamasutra
I think title is more than click bite, but content is good n my opinion.

I am planning to implement Utility AI based on weights, using ECS. But not making (at least at this point) any visual editor.

Just as from article example.

4063393--1272064--upload_2023-7-17_0-37-30.png

I have general concept how to approach it in terms of coding.
But here I am not asking about the specific algorithms. Rather doing more research in the topic.
While there is plenty to read and resources available on the net, that I can refer to, I would like simply ask, if you have any good additional references in your opinion, which may be worth to share and read.

However, if you have better alternative to Utility AI, or own point of view, please share as well.

Many thx in advance.

Edit: Unity forum has lost images (again). Had to reupload them.

2 Likes

Check out AI For Game Developers by David M Bourg (and another guy I’m too lazy to recall right now). Its got some good introductory stuff to things like Fuzzy Logic, pathfinding, and stuff. It was an easy read.

1 Like

Thx, I found his book on a multiple stores / websites.

AI for Game Developers
Creating Intelligent Behavior in Games
by David M Bourg, Glenn Seemann

Synopsis

Very last sentence says, what you just mentioned indeed.

For a working reference (obviously it has been written OOP):
http://apexgametools.com/learn/apex-utility-ai-documentation/apex-utility-ai-scripting-guide/

Mostly the same or similar like Jakob’s article, but maybe contain some extras:

I like the Utility AI-approach, although it’s very hard to do it good by a one-man-show like me. Mainly because of the separation of design and behavior. So either you hire a lot of Q&A, DIY Q&A a lot or risk that unwanted emergent behavior will creep up in the application.
Obviously it’s mainly because of the added complexity and abstraction. When you make a BT-approach it’s more clear when your agent will do what (usually). In exchange Utility can have very fun emergent behavior. But it’s a nightmare to test. On the other hand I have very limited experience since the one-man-show thing, obviously. So I may be doing it wrong.

3 Likes

Both links are very nice readings.
Second one has more like reinforced few of my concept, adding extra, regarding more type of curves.
Regarding first article, this is something I will come back and read again through. There are few keywords listed, of some I want to get more familiar with.

Yep, this is some of my potential concerns. But way I may try to approach it, is by limiting, of how many utilities graphs I can plot, to evaluate score at once. Then maybe create I create sub system with another Utility AI. Just kind of like Behaviour Tree leafs work. That would be kind of hybrid approach.
However, this concept is not yet decided.

While I like this concept generally, and I may implement it as well at some point, I am not convinced yet regarding expand-ability, in case of my moddable game. On other hand Utility-AI can indeed creep out strange behaviors, if untested graph is being added :wink: But BT feels to me more strict. This is my main reason, to hold me back against it atm, toward U-AI.

This is what I am aiming for. Even for the cost of testing disadvantage. In worse case scenario, I will be back to BT.

Definitely for limited time and knowledge, we can do only so much, in certain time span.
I did investigated BTs and U-AI last year already. And multiple sources I looked into, also indicated concerns and points, you just have raised.

1 Like

I’m doing utility AI in my game right now and I’ve found the book “AI for games” by Ian Millington & John Funge really useful.
http://lecturer.ukdw.ac.id/~mahas/dossier/gameng_AIFG.pdf

4 Likes

This is cool. Over 800 pages to enjoy reading :wink:

What I found interesting so far, is task time factor ( page 408) and “smell” concept at page 425.
Of course smell can be interpreted as distance to the target, or cover, to decide weather shoot, or hide.

Included good references to games. For example sims.

Overall I like it. Many thanks.

1 Like

Just got a thought, which I would leave it here, so I don’t forget.

Since I am focusing on modding aspect to implement Utility AI, I am consider develop spreadsheet as design stage, which will match relevant utility and behaviour. Then generate output data, in form of fields, or maybe Json, containing trend line functions, ready for import to Unity, where algorithms will take care for the rest and execution.

this was a real eye-opener. so utility-ai is a decision engine based on the evaluation of animation curves.

made a prototype.
first a script that creates curves and adds keyframes to it in runtime
if want to add a new value on a time that has already a keyframe it’s overwritten with the new value

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimCurveExample : MonoBehaviour {

    //ADDS NEW KEYFRAMES TO A CURVE
    //AND MODIFIES EXISTING KEYFRAMES
    public AnimationCurve curve;

    public KeyCode addK = KeyCode.Keypad0;
    [Range(0.0f, 1.0f)] public float time;
    [Range(-1.0f, 1.0f)] public float value;

    public int maxKeyFrames = 10;

    Keyframe[] ks;
    [HideInInspector] public int i = 1;//for new key 1-9
    int x;
    bool removed;

    void Start()
    {
            ks = new Keyframe[maxKeyFrames];

            curve = new AnimationCurve (new Keyframe (0, 0), new Keyframe (1, 1));
            curve.preWrapMode = WrapMode.Once;
            curve.postWrapMode = WrapMode.Once;
    }


    void Update()
    {
        if (Input.GetKeyDown (addK)) {

            removed = false;
            for (x = 0; x < ks.Length; x++) {
            
                if (ks[x].time == time) {
                    curve.RemoveKey (x);
                    ks [x] = new Keyframe (time, value);
                    curve.AddKey (ks [x]);
                    removed = true;
                    print("key removed " + x);
                    return;
                }
            }

            if (!removed && i<ks.Length-1) {
                ks [i] = new Keyframe (time, value);
                curve.AddKey (ks [i]);
                print("key added " + i);
                i += 1;
            }
        }
    }


}

.
and here’s a curves-evaluator example
drag timeExample variable to see highest

4072711–354949–curvesExample.unitypackage (6.19 KB)

5 Likes

This is simple and neat.
Many thanks for sharing.

I am glad that topic become useful otherwise.

I was planning to use behaviour trees at first, but they are so predictable that I’ve been looking into GOAP (Goal Oriented Action Planning), which is very similar, but for the player it’s harder to predict the behaviour (which in the end is very important, because if the player can predict all the AI actions, that remove some of the fun).

I haven’t (yet) looked in depth into the Utility AI, but it seems to me that it may be quite hard to balance for complex systems.
Each time you change a ‘weight’ in order to make the AI favor one choice in one case because it’s the obvious course of action, you take the risk of degrading other decisions the AI may take.
That’s the main reason I was interested in Behaviour Trees in the first place, it seems that they can stay manageable even in large and complex systems.

To be honest, I think there’s no golden solution for the AI.
I think that the most efficient way to approach AI in a game (if you need some complex one), is to use several tools.
I really doubt that one tool can fit for all situations, so in the end I guess I’ll end up with 4-5 different AI tools, maybe more.

For example, Behaviour Trees are perfect to handle reflex behaviours, they are predictable anyway so that’s not a problem, and Behaviour Trees are usually quite fast to compute and easy to configure/maintain.
And if you need some more complex behaviours, then Utility AI seem to be more interesting (even if it may be quite hard to balance/maintain).
And probably that none of these algorithm can be used if you need some learning feature in some part of the game, except maybe if you use a neural network to generate some inputs for the Utility AI, which would make it even harder to balance, but may provide some interesting results.

Utility AI is interesting concept. There is quite to read about it, as well as any other AIs.
It can be true, that weighting may introduce some balance difficulties. I have not fully designed solution as of yet, but thinking of ensuring of smaller Utility AIs controlling other Utilit AI / brains, or even behavior trees for smaller / obvious tasks. However, Utility AI can be also acting as simple switch just like BT. So one tool may potentially do multiple solutions.

For additional unpredictability, fuzziness may be added if needed.

You can have any type of AI to drive machine learning and vice versa. Question is, weather is needed, or is worth it. Is even harder to maintain, since you need retrain, if anything related is changing. I love Neural Networks, and I got use of it in my main project. But will not be my main brain driver, even I though about it a lot before. Rather I will use for controllers.

Not always, sometimes you need the player to know exactly how the AI works.(not in technical terms, but what effects what).
In the game I’m working on right now you have an arena where you send you team of tank-bots to fight other teams, you get to setup the AI and you NEED to know what he will do with minimal trial & error, a good example for this with out writing a speech about my game is “Gratuitous Space Battles”.

1 Like

Very interesting article. Behavior trees are good for many fairly simple cases, but having to define the logical transitions between a lot of nodes makes it still very tedious to set up. And the real limitation is that you end up with rigid behavior that doesn’t respond to new circumstances unless you explicitly add it to the tree.

The way I look at utility AI, it is like you are creating an electronic circuit with analog signals rather than digital ones. In behavior trees, everything has to be essentially converted to a digital (Yes/No) signal before you can take another step down the tree - and the fact that these are linked together in a hierarchy means that a lot of information is destroyed at the top without evaluating the effect that this might have further down the tree. Whereas with utility AI, the digital signal is only created locally right at the point of each decision, without changing the resolution of the information for some other decision.

I can see that utility AI might be a little difficult to control, because you cannot easily see how a particular addition will be evaluated by a combination of scorers. But even in games where the gameplay needs to be predictable, especially in terms of creating atmosphere - that is, controlling behavior that is visible but not essential to gameplay itself - I think it would do a great job of creating variety and spontaneity.

1 Like
  1. Create an editor to manage the connections with mouse + keyboard.
  2. Explore Fuzzy Logic for that yes/no binary behavior.

The fundamental nature of behaviour trees doesn’t have much at all to do with how potential options are evaluated at each node. Its nature comes from the hierarchy structure itself.

I suppose it’s not quite correct, however, for me to say that information is lost at each node in a behaviour tree - it’s just that to use the information again, it has to be re-introduced at a high complexity cost (via another connection). The strength of a rigid hierarchy is that at each point you are discarding information that came before, so as to arrive at a single decision, so adding connections everywhere, while possible, is not a benefit.

The great thing about utility AI is that there is no hierarchy - each of the decisions competes on its own merits. This means that a decision is never off the table because of a logical mistake or poorly designed connection in a hierarchical structure (and some kinds of connections are very difficult to design well). So much more variety and flexibility is available.

It does mean that sometimes a sub-optimal decision is made, but if it managed to out-score the other decisions it’s probably going to be one that makes a lot of sense from a particular point of view.

2 Likes

Just thinking about this, I wonder if an AI software would not benefit from having both utility functions and behaviour trees (or even finite state machines) together.

The utility functions would represent higher order thinking/learning, and the finite state machines represent instincts. The more that an AI finds itself doing a particular thing, it creates a finite state machine from the utility functions and relies on that more and more.

This would result in more predictability without totally losing flexibility - but of course the cost is in the time taken learning an instinct.

Utility ai is nice because it doesn’t dictate the larger design. IMO where most go wrong when first creating ai systems is to try and use rigid design patterns. Spend your time on creating good abstractions for all the underlying systems first. Then think through what data will drive the ai, map it out at a high level devoid of specific design patterns.

Most bad ai makes the same core mistake. It doesn’t reduce. It’s not working with good abstractions. Which makes it far more complex then it should be.

For example a good combat system is going to be built around a small set of effects. Reduced down to basic elements like direct damage, stun, root, speed increase, heal over time, etc… You might have 300 skills but they are all just combinations/variants of those core things.

So then your ai deals with those core things. Instead of a behavior tree dealing with all 300 skills, it’s relatively straight forward custom logic with some utility ai through in.

Behavior trees and state machines are good at complex logic. Maybe you do end up needing them for some things. But the main goal is really to reduce the complexity. At the very least start with puttting in a simple version of the ai covering the entire breadth just using simple custom logic. And then move to more rigid designs if you actually need them.

It’s rare that rigid patterns work everywhere. Different ai sub systems often have completely different flows.

That’s just my advice having iterated on how to do ai well over the last decade. I spent more time then I care to admit trying to force square pegs into round holes.

2 Likes

Maybe I have missed out, from further conversation, however, as we know, none solution is perfect fit for all. But we can make hybrid AI system, by combining both BT and Utility and other, as @Billy4184 mentioned.

Good thing about Utility AI is, having comparison mechanics. Just as Sims game urge bars example. Or having shooter game, checking distances, vs altitude, vs ammo, vs something else. (see my post #7). BT may not always be good in such cases. Or could become quickly messy otherwise.

We are using utility AI for our sim MMO game SEED (https://seed-project.io/) and its a really nice fit for us.

One pitfall we ran into was using ranking too much (basically priority grouping of actions) instead of the “Infinite Axis” model, where each action can have a variable number of scoring factors. If you have dynamic ranking it can often become hard to figure out what factors are changing the rank.

I really recommend digging into Dave Mark’s work, including his book and lectures most of which are listed here:
http://www.intrinsicalgorithm.com/works.php

3 Likes