Behavior Composition

Monkey Forums/Monkey Programming/Behavior Composition

zoqfotpik(Posted 2013) [#1]
I want to design a system where object behavior can be composited at runtime.

Let's say I have a list of behaviors, like:
* Chase blue objects
* Flee from red objects
* Respond to gravity
* Home toward the player

What would be a good way of combining these behaviors? Can I have a list that these are added to? Would the behaviors themselves be objects?

In Blitzmax I would probably do this with function pointers. Would it be done in Monkey with interfaces?

One problem I can see is that you might run into a data access issue.

If I am doing this, should I set up a dataports system?


AdamRedwoods(Posted 2013) [#2]
a simple Select/Case in a UpdateBehavior() function would suffice, no need to get complicated, especially if behavior can change quickly.

what i would do, is create a class for Behavior, and create methods for each type of behavior. behaviors are first run from the Select/Case. the class contains current x,y vector and future x,y vector. first set future x,y as current x,y. then each behavior enabled takes the current x,y and adds differential from current into future x,y. the final behavior can check for collisions.

you could even add in a percentage weight (0.0 to 1.0) for each behavior before it adds back in to future x,y (which is essentially LERP).


zoqfotpik(Posted 2013) [#3]
Just so you know, I'm trying to set up a metalanguage for game creation to drastically simplify creation of new object types. Select would certainly work but I was hoping to use a more object oriented approach where it would run through all behaviors in a list for each object.


Goodlookinguy(Posted 2013) [#4]
You might want to look into the observer and mediator design patterns. They might be what you're looking for. If not, no harm done in learning about them.


Gerry Quinn(Posted 2013) [#5]
I've done something like this in a roguelike. In it a creature selects one of several possible 'Behaviour' objects (such as 'Engage nearest enemy in melee', 'Cast a spell', 'Move to a suitable square and fire at an enemy' - based on the creature's abilities and disposition as well as a Markov chain.

Anyway, the point is that it can select any of several objects derived from 'Behaviour', which then handles its actions on that turn.

Behaviour objects have read access to the internal state of the Creature; when a Behaviour object is invoked it returns a 'Move' object which is an instruction for a creature action. The creature then presents this to the GameLevel (the physics model/arbiter, if you like), which performs it if it is valid.

Note that this is a bit longwinded and probably better suited to a roguelike than an arcade game. (My motto with roguelikes is 'code defensively and hang the speed'. If you are checking in three separate places whether a creature is trying to walk through a wall, and do something safe instead if so, that is fine.)

And in truth, you could do all this well enough with Select..Case too.


zoqfotpik(Posted 2013) [#6]
Well, select/case it is, I will worry about fine points of architecture later when it's impossible to fix.

GLG: Will do. I am interested in design patterns.


mteo77(Posted 2013) [#7]
Hello.
I had a similar issue, and the 2 options were basically using interfaces or the good old case select.
I didn't play much with interfaces, but i can see benefits from using them; at the end i choose select case because it was so much faster for me to implement..


Shinkiro1(Posted 2013) [#8]
That's a perfect use case for the strategy pattern:

Interface Behaviour
  Method Update:Void()
End

Class ChaseBlueBehaviour Implements Behaviour
  Method Update:Void()
    'implementation
  End
End

Class FleeFromRedBehaviour Implements Behaviour
  Method Update:Void()
    'implementation
  End
End



Class MyObject
  Field currentBehaviour:Behaviour
End



Then when you want to swap out a behaviour simply assign currentBehaviour a new Behaviour you want.


Goodlookinguy(Posted 2013) [#9]
Since design patterns have been discussed here, I found this design patterns reference card PDF: http://www.mcdonaldland.info/2007/11/28/40/ that might help when needed.

Believe me when I say that combining them together can yield amazingly maintainable code. I will keep in mind though, that sometimes they can inhibit progress. In which case, procedural code all the way.