Skip to content

Commit

Permalink
Changed any Goap* to ReGoap* to keep naming style.
Browse files Browse the repository at this point in the history
Changed every ReGoap class to use generics so we are not bound anymore to <string, object> states, but anything can be used.
Using Vector3? instead of Vector3 in the Unity example.
Related to #13

This commit breaks every implementation.
  • Loading branch information
luxkun committed Apr 1, 2017
1 parent baf64e9 commit 818dc5e
Show file tree
Hide file tree
Showing 53 changed files with 544 additions and 490 deletions.
56 changes: 29 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ This library is very generic, if you don't include the Unity folder you can use
2. [Get Started, long version](#get-started-long-version)
1. [Explaining GOAP](#explaining-goap)
2. [How to use ReGoap in Unity3D](#how-to-use-regoap-in-unity3d)
1. [How to implement your own GoapAction](#how-to-implement-your-own-goapaction)
2. [How to implement your own GoapGoal](#how-to-implement-your-own-goapgoal)
3. [How to implement your own GoapSensor](#how-to-implement-your-own-goapsensor)
1. [How to implement your own ReGoapAction](#how-to-implement-your-own-regoapaction)
2. [How to implement your own ReGoapGoal](#how-to-implement-your-own-regoapgoal)
3. [How to implement your own ReGoapSensor](#how-to-implement-your-own-regoapsensor)
3. [Debugging](#debugging)
4. [Pull Requests](#pull-requests)

Expand Down Expand Up @@ -65,7 +65,7 @@ Examples:

*IMPORTANT*: false preconditions are NOT supported
*IMPORTANT*: the action effects aren't written in the memory when the action is done, this is a wanted behaviour because in most of the games you will want to set these variables from the memory or from the sensors.
If you want you can override Exit in your GoapAction and set the effects to the memory, example following.
If you want you can override Exit in your ReGoapAction and set the effects to the memory, example following.


#### Goal
Expand Down Expand Up @@ -97,49 +97,51 @@ Command line:
git clone https://github.com/luxkun/ReGoap.git
```
2. Create a GameObject for your Agent
3. Add a GoapAgent component, choose a name (it is advised to create your own class that inherit GoapAgent, or implements IReGoapAgent)
4. Add a GoapMemory component, choose a name (it is advised to create your own class that inherit GoapMemory, or implements IReGoapMemory)
5. [optional | repeat as needed] Add your own sensor class that inherit GoapSensor or implements IReGoapSensor
6. [repeat as needed] Add your own class that inherit GoapAction or implements IReGoapAction (choose wisely what preconditions and effects should this action have) and implement the action logic by overriding the Run function, this function will be called by the GoapAgent.
7. [repeat as needed] Add your own class that inherit GoapGoal or implements IReGoapGoal (choose wisely what goal state the goal has)
8. Add ONE GoapPlannerManager to any GameObject (not the agent!), this will handle all the planning in multiple-threads.
3. Add a ReGoapAgent component, choose a name (you must create your own class that inherit ReGoapAgent, or implements IReGoapAgent)
4. Add a ReGoapMemory component, choose a name (you must create your own class that inherit ReGoapMemory, or implements IReGoapMemory)
5. [optional | repeat as needed] Add your own sensor class that inherit ReGoapSensor or implements IReGoapSensor
6. [repeat as needed] Add your own class that inherit ReGoapAction or implements IReGoapAction (choose wisely what preconditions and effects should this action have) and implement the action logic by overriding the Run function, this function will be called by the ReGoapAgent.
7. [repeat as needed] Add your own class that inherit ReGoapGoal or implements IReGoapGoal (choose wisely what goal state the goal has)
8. Add ONE ReGoapPlannerManager (you must create your own class that inherit ReGoapPlannerManager) to any GameObject (not the agent!), this will handle all the planning.
9. Play the game :-)

What's more? nothing really, the library will handle all the planning, choose the actions to complete a goal and run the first one until it's done, then the second one and so on, all you need to do is implement your own actions and goals.

In the next paragraphs I'll explain how to create your own classes (but for most of behaviours all you need to implement is GoapAction and GoapGoal).

#### How to implement your own GoapAction
#### How to implement your own ReGoapAction
Check out the actions in this example: https://github.com/luxkun/ReGoap/tree/master/ReGoap/Unity/FSMExample/Actions

Check out GoapAction implementation, to see what functions you can override: https://github.com/luxkun/ReGoap/blob/master/ReGoap/Unity/GoapAction.cs
Check out ReGoapAction implementation, to see what functions you can override: https://github.com/luxkun/ReGoap/blob/master/ReGoap/Unity/ReGoapAction.cs

You can also implement your own GoapAction by implementing IReGoapAction interface, not advised except you know what you are doing!
You must implement your own ReGoapAction by implementing IReGoapAction interface or inheriting ReGoapAction.
Choose wisely the generic types, they must be the same across all the classes of the agent.
Usually string, object is the most generic, also int/enum, object is as well generic but lighter.

For a simple implementation all you have to do is this:
```C#
public class MyGoapAction : GoapAction
public class MyGoapAction : ReGoapAction<string, object>
{
protected override void Awake()
{
base.Awake();
preconditions.Set("myPrecondition", myValue); // myValue can be anything, it's an object internally
preconditions.Set("myPrecondition", myValue);
effects.Set("myEffects", myValue);
}
public override void Run(IReGoapAction previous, IReGoapAction next, IReGoapActionSettings settings, ReGoapState goalState, Action<IReGoapAction> done, Action<IReGoapAction> fail)
public override void Run(IReGoapAction<string, object> previous, IReGoapAction<string, object> next, IReGoapActionSettings<string, object> settings, ReGoapState<string, object> goalState, Action<IReGoapAction<string, object>> done, Action<IReGoapAction<string, object>> fail)
{
base.Run(previous, next, goalState, done, fail);
// do your own game logic here
// when done, in this function or outside this function, call the done or fail callback, automatically saved to doneCallback and failCallback by GoapAction
doneCallback(this); // this will tell the GoapAgent that the action is succerfully done and go ahead in the action plan
// if the action has failed then run failCallback(this), the GoapAgent will automatically invalidate the whole plan and ask the GoapPlannerManager to create a new plan
// when done, in this function or outside this function, call the done or fail callback, automatically saved to doneCallback and failCallback by ReGoapAction
doneCallback(this); // this will tell the ReGoapAgent that the action is succerfully done and go ahead in the action plan
// if the action has failed then run failCallback(this), the ReGoapAgent will automatically invalidate the whole plan and ask the ReGoapPlannerManager to create a new plan
}
}
```

As written before the GoapAction does not, by default, write the effects on the memory, but the memory should check out if the effects are effectively done, if for any reason you want to set the effects at the end of the action you can add this code to your GoapAction implementation:
As written before the ReGoapAction does not, by default, write the effects on the memory, but the memory should check out if the effects are effectively done, if for any reason you want to set the effects at the end of the action you can add this code to your ReGoapAction implementation:
```C#
public override void Exit(IReGoapAction next)
public override void Exit(IReGoapAction<string, object> next)
{
base.Exit(next);

Expand All @@ -155,20 +157,20 @@ You can also have preconditions and effects that are dynamically changed based o
Check out FSMExample to see how to do this:
https://github.com/luxkun/ReGoap/blob/master/ReGoap/Unity/FSMExample/Actions/GenericGoToAction.cs

#### How to implement your own GoapGoal
#### How to implement your own ReGoapGoal
This is less tricky, most of the goal will only override the Awake function to add your own goal state (objectives).

Anyway check out GoapGoal, like everything you can implement your own class from scratch by implementing IReGoapGoal interface: https://github.com/luxkun/ReGoap/blob/master/ReGoap/Unity/GoapGoal.cs
Anyway check out ReGoapGoal, like everything you have to implement your own class from scratch by implementing IReGoapGoal interface or inheriting ReGoapGoal: https://github.com/luxkun/ReGoap/blob/master/ReGoap/Unity/ReGoapGoal.cs

Also check out the goals in this example: https://github.com/luxkun/ReGoap/tree/master/ReGoap/Unity/FSMExample/Goals

```C#
public class MyGoapGoal : GoapGoal
public class MyGoapGoal : ReGoapGoal<string, object>
{
protected override void Awake()
{
base.Awake();
goal.Set("myRequirement", myValue); // like any State myValue is an object, so can be anything
goal.Set("myRequirement", myValue);
}
}
```
Expand All @@ -178,10 +180,10 @@ Check out GoapSensor basic class here: https://github.com/luxkun/ReGoap/blob/mas

Check out examples here: https://github.com/luxkun/ReGoap/tree/master/ReGoap/Unity/FSMExample/Sensors

As always you can implement your own class by implementing IReGoapSensor interface.
As always you have to implement your own class by inheriting ReGoapSensor or implementing IReGoapSensor interface.

```C#
public class MySensor : GoapSensor
public class MySensor : ReGoapSensor<string, object>
{
void FixedUpdate()
{
Expand Down
22 changes: 11 additions & 11 deletions ReGoap/Core/IReGoapAction.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
using System;
using System.Collections.Generic;

public interface IReGoapAction
public interface IReGoapAction<T, W>
{
// this should return current's action calculated parameter, will be added to the run method
// userful for dynamic actions, for example a GoTo action can save some informations (wanted position)
// while being chosen from the planner, we save this information and give it back when we run the method
IReGoapActionSettings GetSettings(IReGoapAgent goapAgent, ReGoapState goalState);
void Run(IReGoapAction previousAction, IReGoapAction nextAction, IReGoapActionSettings settings, ReGoapState goalState, Action<IReGoapAction> done, Action<IReGoapAction> fail);
void Exit(IReGoapAction nextAction);
IReGoapActionSettings<T, W> GetSettings(IReGoapAgent<T, W> goapAgent, ReGoapState<T, W> goalState);
void Run(IReGoapAction<T, W> previousAction, IReGoapAction<T, W> nextAction, IReGoapActionSettings<T, W> settings, ReGoapState<T, W> goalState, Action<IReGoapAction<T, W>> done, Action<IReGoapAction<T, W>> fail);
void Exit(IReGoapAction<T, W> nextAction);
Dictionary<string, object> GetGenericValues();
string GetName();
bool IsActive();
void PostPlanCalculations(IReGoapAgent goapAgent);
void PostPlanCalculations(IReGoapAgent<T, W> goapAgent);
bool IsInterruptable();
void AskForInterruption();
// THREAD SAFE
ReGoapState GetPreconditions(ReGoapState goalState, IReGoapAction next = null);
ReGoapState GetEffects(ReGoapState goalState, IReGoapAction next = null);
bool CheckProceduralCondition(IReGoapAgent goapAgent, ReGoapState goalState, IReGoapAction nextAction = null);
float GetCost(ReGoapState goalState, IReGoapAction next = null);
ReGoapState<T, W> GetPreconditions(ReGoapState<T, W> goalState, IReGoapAction<T, W> next = null);
ReGoapState<T, W> GetEffects(ReGoapState<T, W> goalState, IReGoapAction<T, W> next = null);
bool CheckProceduralCondition(IReGoapAgent<T, W> goapAgent, ReGoapState<T, W> goalState, IReGoapAction<T, W> nextAction = null);
float GetCost(ReGoapState<T, W> goalState, IReGoapAction<T, W> next = null);
// DO NOT CHANGE RUNTIME ACTION VARIABLES, precalculation can be runned many times even while an action is running
void Precalculations(IReGoapAgent goapAgent, ReGoapState goalState);
void Precalculations(IReGoapAgent<T, W> goapAgent, ReGoapState<T, W> goalState);
}

public interface IReGoapActionSettings
public interface IReGoapActionSettings<T, W>
{
}
22 changes: 12 additions & 10 deletions ReGoap/Core/IReGoapAgent.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
using System.Collections.Generic;

public interface IReGoapAgent
public interface IReGoapAgent<T, W>
{
IReGoapMemory GetMemory();
IReGoapGoal GetCurrentGoal();
void WarnPossibleGoal(IReGoapGoal goal);
IReGoapMemory<T, W> GetMemory();
IReGoapGoal<T, W> GetCurrentGoal();
// called from a goal when the goal is available
void WarnPossibleGoal(IReGoapGoal<T, W> goal);
bool IsActive();
List<ReGoapActionState> GetStartingPlan();
T GetPlanValue<T>(string key);
void SetPlanValue<T>(string key, T value);
bool HasPlanValue(string target);
List<ReGoapActionState<T, W>> GetStartingPlan();
W GetPlanValue(T key);
void SetPlanValue(T key, W value);
bool HasPlanValue(T target);
// THREAD SAFE
List<IReGoapGoal> GetGoalsSet();
List<IReGoapAction> GetActionsSet();
List<IReGoapGoal<T, W>> GetGoalsSet();
List<IReGoapAction<T, W>> GetActionsSet();
ReGoapState<T, W> InstantiateNewState();
}
10 changes: 10 additions & 0 deletions ReGoap/Core/IReGoapAgentHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

// interface needed only in Unity to use GetComponent and such features for generic agents
public interface IReGoapAgentHelper
{
Type[] GetGenericArguments();
}
12 changes: 12 additions & 0 deletions ReGoap/Core/IReGoapAgentHelper.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions ReGoap/Core/IReGoapGoal.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
using System;
using System.Collections.Generic;

public interface IReGoapGoal
public interface IReGoapGoal<T, W>
{
void Run(Action<IReGoapGoal> callback);
void Run(Action<IReGoapGoal<T, W>> callback);
// THREAD SAFE METHODS (cannot use any unity library!)
Queue<ReGoapActionState> GetPlan();
Queue<ReGoapActionState<T, W>> GetPlan();
string GetName();
void Precalculations(IGoapPlanner goapPlanner);
void Precalculations(IGoapPlanner<T, W> goapPlanner);
bool IsGoalPossible();
ReGoapState GetGoalState();
ReGoapState<T, W> GetGoalState();
float GetPriority();
void SetPlan(Queue<ReGoapActionState> path);
void SetPlan(Queue<ReGoapActionState<T, W>> path);
float GetErrorDelay();
}
4 changes: 2 additions & 2 deletions ReGoap/Core/IReGoapMemory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
public interface IReGoapMemory
public interface IReGoapMemory<T, W>
{
ReGoapState GetWorldState();
ReGoapState<T, W> GetWorldState();
}
6 changes: 3 additions & 3 deletions ReGoap/Core/IReGoapSensor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
// you want to re-use different sensors in different agents
// the interface does not dictate how you should update the memory from the sensor
// - in a unity game probably you will want to update the memory in the sensor's Update/FixedUpdate
public interface IReGoapSensor
public interface IReGoapSensor<T, W>
{
void Init(IReGoapMemory memory);
IReGoapMemory GetMemory();
void Init(IReGoapMemory<T, W> memory);
IReGoapMemory<T, W> GetMemory();
void UpdateSensor();
}
8 changes: 4 additions & 4 deletions ReGoap/Core/ReGoapActionState.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
public class ReGoapActionState
public class ReGoapActionState<T, W>
{
public IReGoapAction Action;
public IReGoapActionSettings Settings;
public IReGoapAction<T, W> Action;
public IReGoapActionSettings<T, W> Settings;

public ReGoapActionState(IReGoapAction action, IReGoapActionSettings settings)
public ReGoapActionState(IReGoapAction<T, W> action, IReGoapActionSettings<T, W> settings)
{
Action = action;
Settings = settings;
Expand Down
Loading

0 comments on commit 818dc5e

Please sign in to comment.