Utility theory and normalization

theunsigned

New member
Good day,

I have been reading as much as I can about utility theory (http://www.gameaipro.com/GameAIPro/...ecisions_into_Your_Existing_Behavior_Tree.pdf and some other summaries) as well as normalization (https://www.statology.org/normalize-data-between-0-and-100/ and others) but I'm struggling to understand how to apply it. I do not have a strong background in math but I'm loving it as I learn and I would describe myself as a low-intermediate C# coder.

Here's my use-case:

I have a Stats class that has a stat scriptable object, value (min and max), sensitivity (min and max), and threshold (min and max). I made a list of these Stats in my NPC controller, which has a Utility Selector Behavior Designer Tree for Energy, Socialization, and Individual Growth. I cobbled together a strange formula to select which Stat to attend to in a Stat Evaluator and plugged in the three different stats to evaluate; the current formula is this: 1-(.01*( stat value - (stat threshold +(stat sensitivity*2)))) -- this is then evaluated along the animation curve

The challenge is that I want each evaluator to factor in different things. I could do this in the controller and have it contribute to the related Stat's value or make unique evaluators for each one. Either way, I need to better understand the normalization process that is described at the bottom of page 131 in the chapter on Utility Theory linked to above.

The author describes normalizing the heal and delay values and adds a power factor in example 10.4 but I'm not sure if that's a power on top of the power applied in the previous example (10.3) or something else entirely and I'm not clear on how to normalize a single value between 0-100. The formulas I have found depend on the range of a data set. but the chapter describes normalizing each value before plugging it into the formula (10.4). Is this the case or is the utility value normalized based on the range of the heal and delay values?

In my example, let's take Socialization, I'd like to factor in the number of friends an NPC has compared to their ideal number of friends, time since last contact compared to ideal time between contacts, etc. as well as how long it will take to go to their friends or hangout spots to determine if it's worth leaving their homes, where they can eat, sleep, and tend to their basic Energy needs. I think some of these calculations may be better done in the NPC Controller script and the evaluator can just read the Stat value but I would really like to better understand this so I can improve my use of Behavior Designer.

Thank you very much for such a great tool and prompting me to expand my knowledge!
 
From the behavior tree's perspective it doesn't matter what float value you return, but you are right in that to achieve some balance you are going to want to normalize it first. Now, in terms of how to normalize, that is really a tough question and I'm not able to tell without a look at the project. I would not normalize it twice though - if you have already normalized it once in one class I would just use that within your tree.

I know that I wasn't able to answer your specific questions, but hopefully that gave you some idea on how to approach it :)
 
Thank you very much, that is very helpful advice.

I think the main point I'm stuck on is how to normalize a single value since everything I read talks about normalizing a value in a range of values. Initially, I thought that if I make a formula that compares the Stat value to its threshold (how far over it or below it) and factors in how quickly it'll deplete based on its sensitivity (times two for a buffer), and collapse it between 0 and 1, then subtract that from 1 to evaluate on a left-to-right curve, then that's normalizing but I'm not sure that's normalizing. I also realize I could just invert the curve to avoid the subtraction and make 0 the imperative utility.

The chapter on utility theory is super helpful and the website it's from it also great; but if there are any other resources you know of, I'd be grateful for a link.

Thank you again! Behavior Designer is one of the best assets I've ever purchased. It's a bit of a learning curve but once it clicks, it becomes truly fun to use. All the best to you and your team :)
 
I just realized how the behavior tree may be used to solve this and provide better results in my case: instead of trying to calculate all the variables in the evaluator, break it down into smaller chunks and layers of evaluation. For example: have a general energy value but, underneath it, evaluate for things like "hunger", "sleep", etc. and have those impact the energy value independently, outside the evaluator. I'll read up on how to do that.

I always have to remind myself to break down the steps as much as possible... and I'm trained in applied behavior analysis.. haha
 
Thank you again! Behavior Designer is one of the best assets I've ever purchased. It's a bit of a learning curve but once it clicks, it becomes truly fun to use.
I'm really happy to hear that - thanks for mentioning it :) Are you able to leave a review on the Asset Store? We'd really appreciate it :)

For example: have a general energy value but, underneath it, evaluate for things like "hunger", "sleep", etc. and have those impact the energy value independently, outside the evaluator. I'll read up on how to do that.
Yes, that sounds like it should work well. So if you have five categories you can make it easy by having each category return a 0-1 value and then normalize by dividing by 5 at the end.
 
Thank you again, I will happily post a positive review!

I ended up changing things as I described but I also completely changed my evaluator to take a percentage of the difference between the maxvalue minus threshold and the maxvalue minus score, then evaluated that along the curve. It seems to be working much better and I can easily expand with by assigning different scriptable objects and using shared variable.

I'm completely confused about some weird seek behaviors I'm running into but I'll post that in a separate thread. Thank you again!
 
Top