From AI Wiki
One thing you must have noticed by now is how easy it is in the IamFramework to combine several simple behaviors in order to create an Iam with a complex total behavior. All you need to do is create a list of behavior beans and pass them in the behaviorList property of the IamBot bean. Most of the time it seems to just magically work.
Except when it doesn't. And then it can be a frustrating experience trying to make your Iam behave in the way you intended. Time to explain a little more how these behaviors actually work together in your Iam.
First of all, it's important to understand that all events that an Iam receives are passed on to all the behaviors it contains. So each behavior always has full control over deciding how to respond to certain events or input. But what happens when two behaviors have conflicting interest? What if one behavior wants to go to the right, where another wants to turn left? Time to introduce the com.avatar_reality.blue_mars.iam.framework.behavior.DecisionUnitInterface. As is common in the IamFramework, you are free to implement this interface and configure your Iam to use your own implementation. By default it uses com.avatar_reality.blue_mars.iam.framework.behavior.DefaultDecisionUnit. What is important to understand is that when you call say(text) or walk(location) in your behavior, you are not actually telling your Iam to say something or to walk somewhere. What happens instead is that this gets translated to an ActionProposal and then passed on to the decision-unit. The decision-unit gets to decide whether this proposal actually gets executed or not. It is completely up to the actual implementation of the decision-unit how it makes this decision. It would even be possible to simply execute any proposal it gets, with all the potential conflicts that may result.
So this is not exactly what DefaultDecisionUnit does. A behavior can make a call called 'requestActionSequence(ActionSequence)'. This method return true or false whether the decision-unit accepted the request or not. The class com.avatar_reality.blue_mars.iam.framework.behavior.ActionSequence is a simple class with some properties you can set. Quite a few properties actually. The important part to understand about ActionSequence is that it has a priority (default set to zero), a duration in seconds how long the sequence lasts (default is zero, which means forever) and two sets of booleans. One set describes what types of actions the behavior wants to perform during the duration, the 'hasXXX' set. And the other sets describes what types of actions are allowed to be performed in the meantime by other behaviors, the 'allowsXXX' set.
Again, it's up to the actual implementation of the decision-unit to decide what to do with an ActionSequence request. But what the default implementation does is it looks at the sets and sees whether previous registered ActionSequences. For example, say you pass an ActionSequence that has hasMoveAction true and allowsMoveAction false. It looks at the existing ActionSequences and checks if anyone of them also has allowsMoveAction set to false. If it has, then it checks the priorities of each of the sequences. It then keeps the one with the highest priority, provided it isn't prohibited by yet another existing ActionSequence with even higher priority. One more important property of ActionSequence is allowsInterruptDuration. This means any action is automatically allowed if its duration is less than this. That way one behavior can be in control of the general behavior of an Iam but still allow short animations (like shifting in a chair) or short movements in the meantime, while disallowing movements far away or long dances.
So to recap, whenever a behavior wants to perform some action the decision-unit consults what ActionSequences are registered with it and whether they'd permit the proposed action. If you never register an ActionSequence, all action proposals will be automatically granted. Although it's easy to register an ActionSequence with the decision-unit, it has an almost overwhelming number of fields to set. For this there's the com.avatar_reality.blue_mars.iam.framework.behavior.ActionSequenceFactory. This has two methods that create default instances of ActionSequence with all the fields initialized. One creates a permissive action-sequence. All the 'hasXXX' fields are set to false whereas all the 'allowsXXX' fields are set to true. The other method creates an ActionSequence which does exactly the opposite, creating a prohibitive action-sequence. All the 'hasXXX' fields are set to true whereas all the 'allowsXXX' fields are set to false. These instances are useless as they are, but you can often use them by modifying just one or two of the fields to make them suit your needs rather than having to set all the fields yourself.