The idea is to implement a simple AI, about as complex as a tamagotchi, that allows game programmers to create basic No-Playing-Characters in form of creatures. Those creatures could e.g. be like a glob in globulation. A glob has the need to heal, to rest, etc. and it has strategies for meeting those needs. Also it has feelings. When you hurt a glob, it feels scared and has the need to survive, so a strategy could be running away.
Main AI Class
This class decides what the AI does. Not every need is as important as the other, so this part is going to decide what to do. It also provides functions to create needs, feelings and strategies.
An action is any function the game programmer implements to ineract with the AI (e.g. feeding, stroking, ...). It releases a feeling, by calling its '.release()'-Method.
Needs are represented as dictionaries, which have keys for state, priority, strategy, and trigger. We use dictionaries here, because it's faster.
- state is a boolean value, telling whether the AI currently should try to satisfy this need(True) or not(False). Defaulting to False.
- priority tells the main AI class how important this need is and helps it decide.
- strategy is either the name or an array of names of the strategy/strategies to be followed in order to meet a need.
- trigger is the name of the function to be executed when the state of a need changes. (e.g. for some expression)
Even though needs are stored inside dictionaries, the create function returns an object which helps the programmer to handle the need.
The function 'createNeed()' takes either 1, 2 or 3 arguments. This could look like this:
# this creates a need with the default priority value, and the strategy called 'relax' need_rest = soy.AI.createNeed('relax') # this creates a need with the priority 10, with the strategy called 'runAway' need_survive = soy.AI.createNeed('runAway', 10) # this creates a need with the priority 5, with the strategies called 'eatMeat' and 'eatFruit' and the trigger 'hungry' need_food = soy.AI.createNeed(('eatMeat', 'eatFruit'), 5, 'hungry')
Change the state of Needs
This may be only done by feelings, or after the execution of a strategy.
Feelings are also represented as dictionaries. Those dictionaries have the keys need, state and trigger.
- need is either the name or an array of names of the need(s) this feeling is connected to.
- state is either a boolean value or an array of bools for the state to which the need(s) should be set when this feeling is released.
- trigger is the name of the function to be executed when the feeling is released. (e.g. for some expression)
It's the same as with the needs here. An handle object is returned to make life easier for programmers.
The function 'createFeeling()' takes either 1, 2 or 3 arguments. This could look like this:
# this creates a feeling which is connected to the need need_rest, with the default state for the need, which is True. feel_exhausted = soy.AI.createFeeling(need_rest) # this creates a feeling which is connected to need_survive, with the state False for that need. feel_wanna_die = soy.AI.createFeeling(need_survive, False) # this creates a feeling which is connected to need_food and need_rest, with state True for need_food and False for need_rest and the trigger 'hungry'. feel_hungry = soy.AI.createFeeling((need_food, need_rest), (True, False), 'hungry')
Releasing a feeling is very simple:
This is usually done inside an action.
Strategies are simple functions created by the game programmer. They get evaluated by the main API class, when the need which is linked to that strategy has the state 'True'. After the execution of the strategy, the state of all connected needs are changed to False.
The root is either an action from the outside or the AI itself(e.g. after strategy 'run away', the feeling 'exhausted' is released). It most likely releases a feeling, which is connected to a need, which is again connected to a strategy. The main AI class decides then what strategies to follow, according to the priorities of those needs, which are currently to satisfy.
Since one strategy might be connected to several needs, a rating system for strategies could decide which strategy is the best for the current situation. This rating system is optional, and has to be activated by the AI user, because simpler AIs won't need this.
- how to make the main API class realizing about needs being met/unmet? Maybe use Events( http://live.gnome.org/Genie#Events)? (not sure because it's possibly for GObjects only)
- create diagrams for evaluation
- use delegate instead of names for functions?