MountainGoap 0.1.1
See the version list below for details.
dotnet add package MountainGoap --version 0.1.1
NuGet\Install-Package MountainGoap -Version 0.1.1
<PackageReference Include="MountainGoap" Version="0.1.1" />
paket add MountainGoap --version 0.1.1
#r "nuget: MountainGoap, 0.1.1"
// Install MountainGoap as a Cake Addin #addin nuget:?package=MountainGoap&version=0.1.1 // Install MountainGoap as a Cake Tool #tool nuget:?package=MountainGoap&version=0.1.1
Mountain GOAP
Generic C# GOAP (Goal Oriented Action Planning) library.
Quickstart
Using the code directly
Clone the repo and copy the code in the MountainGoap folder to your repo. All classes provided can be found in the MountainGoap namespace.
Using distributable
TO DO
Using as a Unity package
TO DO
Concepts & API
Agents
Agents are indivdual entities that act within your game or simulated world. The simplest example of instantiating an agent is this:
Agent agent = new Agent();
In practice, you will want to pass the agent constructor various things it needs to make a functional agent. Read on to understand what kinds of objects you should pass your agents.
When you want your agent to act, just call the following:
agent.Step();
What kind of timeframe is represented by a "step" will vary based on your engine. In a turn based game, a step might be one turn. In a realtime engine like Unity, you might call agent.Step()
on every Update()
cycle.
Agent state
The agent stores a dictionary of objects called its state. This state can include anything, but simple values work best with goals and actions. If you need to reference complex game state, however, this is not a problem -- "sensors," covered below, can be used to translate complex values like map states into simpler ones, like booleans. More on that below.
State can be passed into the agent constructor, like so:
Agent agent = new Agent(
state: new Dictionary<string, object> {
{ "nearOtherAgent", false },
{ "otherAgents", new List<Agent>() }
}
);
Goals
Goals dictate the state values that the agent is trying to achieve. Goals have relatively simple constructors, taking just a dictionary of keys and values the agent wants to see in its state and a weight that indicates how important the goal is. The higher the weight, the more important the goal.
Goals can be passed into the agent constructor, like so:
Goal goal = new Goal(
desiredState: new Dictionary<string, object> {
{ "nearOtherAgent", true }
},
weight: 2f
);
Agent agent = new Agent(
goals: new List<Goal> {
goal
}
);
Actions
Actions dictate arbitrary code the agent can execute to affect the world and achieve its goals. Each action, when it runs, will execute the code passed to it, which is called the action executor. Actions can also have preconditions, state values required before the agent is allowed to execute the action, and postconditions, which are values the state is expected to hold if the action is successful. Finally, each action has a cost, which is used in calculating the best plan for the agent.
Actions return an ExecutionStatus
enum to say if they succeeded or not. If they succeed, the postconditions will automatically be set to the values passed to the action constructor.
Actions can be passed into the agent constructor, like so:
Action giveHugAction = new Action(
executor: (Agent agent, Action action) => {
Console.WriteLine("hugged someone");
return ExecutionStatus.Succeeded
},
preconditions: new Dictionary<string, object> {
{ "nearOtherAgent", true }
},
postConditions: new Dictionary<string, object> {
{ "wasHugged", true }
},
cost: 0.5f
);
Agent agent = new Agent(
actions: new List<Action> {
giveHugAction
}
);
Sensors
Sensors allow an agent to distill information into their state, often derived from other state values. Sensors execute on every Step()
call, and use a sensor handler to execute code. Sensors can be passed into the agent constructor, like so:
Sensor agentProximitySensor = new Sensor(
(Agent agent) => {
if (AgentNearOtherAgent(agent)) agent.State["nearOtherAgent"] = true;
else agent.State["nearOtherAgent"] = false;
}
);
Agent agent = new Agent(
sensors: new List<Sensor> {
agentProximitySensor
}
);
Future Feature - Permutation Selectors
Finally, actions can be constructed with permutation selectors, which will instantiate multiple copies of the action with different parameters for purposes such as target selection. The library comes with some default permutation selectors, or you can write your own as callbacks. For instance, if you want an action to be evaluated separately with each member of a list as a potential parameter, you would construct the action as so:
Action myAction = new Action(
permutationSelectors: new Dictionary<string, PermutationSelectorCallback> {
{ "target1", PermutationSelectorGenerators.SelectFromCollectionInState<Agent>("otherAgents") },
{ "target2", PermutationSelectorGenerators.SelectFromCollectionInState<Agent>("otherAgents") }
},
executor: (Agent agent, Action action) => {
Console.WriteLine(action.GetParameter("target1").ToString());
Console.WriteLine(action.GetParameter("target2").ToString());
}
);
The code above will create an action that when evaluated for execution in an agent plan will be considered once for every pair combination of elements in the "otherAgents" collection of the agent state, one for target1
, and one for target2
. Note that while this feature has many potential uses down the road, it is not particularly helpful in agent planning until the utility of an action can be calculated via a custom callback function that can be based on action parameters.
Examples
Project Structure
TO DO
Roadmap
- Distributables
- Custom action cost override based on parameters
- Examples - general and Unity
- Tests
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.1.1 | 1,184 | 5/25/2024 |
1.0.1 | 123 | 5/23/2024 |
1.0.0 | 115 | 5/22/2024 |
0.16.0 | 118 | 5/22/2024 |
0.14.0 | 528 | 1/3/2024 |
0.13.0 | 129 | 1/3/2024 |
0.12.0 | 151 | 1/2/2024 |
0.11.4 | 138 | 12/23/2023 |
0.11.3 | 151 | 12/18/2023 |
0.10.0 | 265 | 9/17/2023 |
0.9.1 | 117 | 9/17/2023 |
0.9.0 | 122 | 9/13/2023 |
0.8.0 | 131 | 9/11/2023 |
0.7.1 | 126 | 9/7/2023 |
0.7.0 | 166 | 6/5/2023 |
0.6.8 | 131 | 6/2/2023 |
0.6.7 | 129 | 6/1/2023 |
0.6.5 | 156 | 4/17/2023 |
0.6.3 | 558 | 3/18/2023 |
0.6.2 | 211 | 3/16/2023 |
0.6.1 | 198 | 3/15/2023 |
0.5.0 | 336 | 10/30/2022 |
0.4.1 | 334 | 10/30/2022 |
0.3.2 | 379 | 10/10/2022 |
0.3.1 | 376 | 10/10/2022 |
0.2.0 | 392 | 10/10/2022 |
0.1.6 | 382 | 10/8/2022 |
0.1.5 | 376 | 10/8/2022 |
0.1.4 | 378 | 10/8/2022 |
0.1.1 | 377 | 10/6/2022 |
Initial release.