Saturday, April 05, 2008

The making of LEAF - Part 1 - Creating Villagers

Creating Character Motivations

The starting point for my implementation of AI characters in LEAF, is to think of the reasons why my AI characters are going to want to do anything interesting. This leads me to think about how I define thier motivations and how I encode them for use by the AI.

How do you define motivations? Well, my starting point was Abraham Maslow's "Heirarchy of needs".





I'll let you read up more about Maslow from his wikipedia entry http://en.wikipedia.org/wiki/Maslow, but suffice to say, I think he was about right in his description of human motivations (ok, from a naieve programmer rather than a pyschologist perspective at least). Luckily, we can apply a lot of what he describes in his heirarchy to our AI problem. Lets look over the heirarchy and learn what we can encode.

Physiological:

This seems like a rich set of needs to encode. I think we can dismiss breathing because of all the needs, it is the one that is automatic (mostly). So that leaves us with drinking, eating, sleeping, excreting. Interestingly one diagram I found had sex in this category too, but I think for this game, we arent going to use that as a basic physiological need.

Clearly those are pretty important to our existance as humans and as such should likely be modelled as part of our AI villagers. Lets continue:

Safety:

Now this is a tricky one. I think my view on this, is that security needs are required if there is conflict. In my design, I'm after something more gentle as gameplay, so I'm going to discount security initially. I may have to revisit this one if I later decide the game is too boring without more conflict.

Love/Belonging :

Now this is an interesting one in game terms. Thinking about the core gameplay I'm trying to get, where villagers have families, care about each other, it seems that THIS category is going to play a large part in the AI code. The typical breakdown is friendship, family, sex. But of course its about emotional connection. I think we have to at least model friendships, family, sex, perhaps even work/social groupings.

Esteem:

Respect, recognition. Again, this might actually be good motivation for our villagers to want to achieve things. Say become the village leader, or to create a better village. One to pay attention to, but I think initially it will be a struggle to come up with behaviors that support these.

Self-actualisation:

Well, this is the top of Maslow's pyramid of needs. He thought the needs where heirarchical, where as others have suggested that they arent. I must admit the heirarchy sounds interesting as a way of determining priority when different needs conflict. But modelling "personal growth and fullfillment" as one version of this heirarchy puts it, is probably out of scope for a game AI. Especially one about dumb comedy AI like this. There is one version of the heirarchy I found that has "Creativity" at this level. This does sound like a useful need to model, as it might offer some interesting opportunities for gameplay deeper into the game.

One thing to note from the literature, is that Maslow isnt suggesting everyone has this same heirarchy where we have strict ordering of needs. He acknowledges that different people place different importances on different levels of need, indeed some may forego phsysiological needs in order to gain respect for instance. It does suggest that perhaps we shouldnt treat these as a heirarchy.

So there we have it. We have the following needs identified:

Drink
Eat
Sleep
Excrete
Friendship
Family
Sex
Social
Work
Respect
Recognition
Creativity

So now comes the representation in code. Step back and ask yourself, what is it these "Needs" have to represent for the code to work?


  • The current "value" for how satisfied this need is

  • The "importance" the particular AI places on this needs (so we can have data driven "personality" types)

  • The minimum threshold below which this need really needs attention

  • The minimum threshold above which we feel this need is satisfied

  • The rate of decay of this need (so for example, how fast does a satisfied need decay)



So we are going to represent these things in code. One thing I like to do in these circumstances, is to create a data type (as we have multiple values based around a single need). So I create an abstract "NEED" data type as a struct:

struct NEED
{
float currentvalue;
float importance;
float minthreshold;
float minsatisfied;

float rateofdecay;
};

The next thing is we need to do, is store the different needs somehow. Now we could do this using individual NEED type variables:

NEED needDrink;
NEED needEat;
NEED needSleep;
...


But I think this will become cumbersome and whats more we cant iterate over the needs easily. So what I prefer, is to create an array of NEED's and then index the need type with an enum:

enum
{

eDrink = 0,
eEat,
eSleep,
eExcrete,
...
eMaxNeed
}


And then simply implement the need array:

NEED needs[eMaxNeed];

So we access a need with:

float fValue = needs[eDrink].currentvalue;

Plus this way, we can iterate the needs data with a for loop and do things like plot the values in the user interface for the game.

So there we have it. The starting point for our agent's needs. We have some data. The next step, is to introduce a framework for the AI so that we can act on the data and satisfy the needs. Next time... "The Garden of Eden".

.Z.