I am attempting to create a "behavior tree" using C#.
For anyone who doesn't know, a behavior tree is basically a framework that you can construct an AI around. There are Sequencers, Selectors, Decorators, composite actions, and other things.
I have found a single library that has implimented a "behavior tree" in C#, located here (http://code.google.com/p/treesharp/) but I cannot understand how to actually use it since there is no example code I can draw from. Could anyone here perhaps make some simple example code that shows how to actually use this framework.. or perhaps you know of another way to impliment a behavior tree in C#?
Thanks so much!
I just looked at that implementation and I find myself wondering why so much code is needed for something relatively simple.
From what you say, you want a simple way of composing behaviours. A behaviour here, I presume, is a mapping from a state to zero or more actions by an agent. You can model this very easily using C# lambdas. For example:
Action Selector(Func<bool> cond, Action ifTrue, Action ifFalse) {
return () => { if cond() then ifTrue() else ifFalse() };
}
Action Sequencer(Action a, Action b) {
return () => { a(); b(); }
}
The leaves of your tree are simple Actions that do something appropriate to the state. You "run" a tree simply by executing it.
If you want to get fancy, you can parameterise this scheme to make the state explicit.
Hope this helps.
---- Addendum ----
Jason asked for an example of how you could use this approach, so here's a simple "AI" patrolling guard example (I assume WorldState corresponds to a description of the environment at the time the behaviour tree is evaluated):
Func<bool> ifPlayerIsInSight = () => ...true iff WorldState shows guard can see player...;
Action shootAtPlayer = () => { ...aim guard's weapon at player and fire... };
Func<bool> ifUnderFire = () => ...true iff WorldState shows guard hears player gunfire...;
Action takeCover = () => { ...guard runs for nearest shelter... };
Action walkBackAndForthGuardingDoorway = () => { ...default guard patrol behaviour... };
Action patrollingGuardBehaviour =
Selector(ifPlayerIsInSight, shootAtPlayer,
Selector(ifUnderFire, takeCover,
walkBackAndForthGuardingDoorway));
To make the guard do something, just call patrollingGuardBehaviour()
. Note that the various subactions and tests can be implemented as methods with the right signatures rather than inline as lambdas. You can add other combinators to Selector
and Sequencer
, e.g., for parallel activity.