Pre-release - APIs are more likely to change during the pre-release period.
A fresh take on Goal oriented action planning.
In GOAP, actions have preconditions, effects, and a cost. Boilerplate? Have a look.
public Cost ChopLog(){
if(!hasAxe) return false; // Precondtion
hasFirewood = true; // Effect
return 4; // Cost
}
Use A* or, if no cost function available, BFS.
- Engine agnostic models - test without pain.
- .NET Core compatible
- Unity integration with UPM support
- Demo project to help you get started
- [COMING SOON] integration with the BT Framework of Awesome, Active Logic 🚀
Clone the repository and add the package to your project as normal.
For Unity 3D:
- Add
xgoap/package.json
via package manager > + > add package from disk. - Alternatively, add
"com.activ.goap": "https://github.com/active-logic/xgoap.git"
to Packages/manifest.json
Planning requires a model and a goal; if available, also provide a heuristic. I will borrow Brent Owens' woodcutter example.
A woodcutter has the GetAxe, ChopLog and CollectBranches actions. Here is our implementation of the woodcutter planning model:
using Activ.GOAP;
public class WoodChopper : Agent, Clonable<WoodChopper>{
public bool hasAxe, hasFirewood;
Option[] opt; // Caching reduces array alloc overheads
public Option[] Options()
=> opt = opt ?? new Option[]{ ChopLog, GetAxe, CollectBranches };
public Cost GetAxe(){
if(hasAxe) return false;
hasAxe = true;
return 2;
}
public Cost ChopLog() => hasAxe ? (Cost)(hasFirewood = true, 4f) : (Cost)false;
public Cost CollectBranches() => (hasFirewood = true, 8);
// Clonable<WoodChopper>
public WoodChopper Allocate() => new WoodChopper();
public WoodChopper Clone(WoodChopper x){
x.hasAxe = hasAxe;
x.hasFirewood = hasFirewood;
return x;
}
// Override for correctness (don't compare refs) and faster hashes
override public bool Equals(object other) => other is WoodChopper that
&& hasAxe == that.hasAxe && hasFirewood == that.hasFirewood;
override public int GetHashCode() => (hasAxe ? 1 : 0)
+ (hasFirewood ? 2 : 0);
}
Run the model and get the next planned action:
var chopper = new WoodChopper();
var solver = new Solver<WoodChopper>();
var next = solver.Next(chopper, goal: (x => x.hasFirewood, null));
Parametric actions are supported; they are concise and type safe. Check the Baker example.
Quick and simple Unity integration via GameAI.cs - for details, read here.
Ready to GOAP? Follow the guide.
If you'd like to get involved, consider opening (or fixing) an issue. Your support is appreciated!