# Goal Oriented Action Planning

Made by Bram Verhulst, 2GD11

## What is Goal Oriented Action Planning?

Goal Oriented Action Planning (Goap for short) is a form of AI decision-making that was developed by Jeff Orkin at MIT.

Its an alternative to more conventional AI behaviour machines like the State machine. GOAP is another way of approaching this problem of making AI work in games.

Unlike A Finite State Machine and Behaviour Trees, GOAP decouples actions and goals to achieve its "Goal".

The biggest downside of GOAP is that it is slower to compute then FSM or BT's, But the upside is that it allows to be more flexible when it comes to adding or changing existing behaviours.

## How does it work?

### Goals

An Agent gets a goal (or several) and knows what actions it can perform to get to a certain goal.

A goal is a state that the agent is trying to achieve. For example:

- To be at home
- To get to the waiting room
- To Get better

### Actions

Every action in a GOAP has PreConditions and Effects.
In order to perform a action all the "conditions" need to met.

![ActionExample](assets/ActionExample.png)

Think of these as "What does the agent need to be able to do this action?"

And "What happens to the world when I do this action"

All of these conditions and effects should lead to a Planner that can string all of these together so the agent can get to its goal.

![ActionTree](assets/ActionTreeExample.png)

### Planner

This is the real "Brain" of the AI. The planner takes 3 pieces of information

- Goals
- Actions
- Current Worldstate

The planner with this information can then try to make a graph of possible plans.

- Plans may only be possible if certain conditions are met.
  
  - Example: Doctor can only get patient if he is charged and a patient is waiting.

- When the action is done, the world should change according to the Effects

  - Example: When the Doctor takes a patient, the patient changes the amount of waiting patients in the world

A valid plan gets constructed back to front.

### What if we have 2 valid plans??

Are we doomed?

No, of course not. We just add a cost to each action and take that into account for these plans.

We use can then use A* to find the plan with the lowest "cost"

In my example most action require the agent to move somewhere.

## implementation: __GOAP CyberHospital__

I made a hospital from the future, Where sick patients come in and a Robot doctor treats them.

Let me explain what they both do.

### Doctor

The doctor is quite simple in behaviour. Their main goal is to "TreatPatient". But they also have a limited battery and need to charge often.

Their goals are repeating so they keep treating patients.

After some random amount of time their battery will deplete, This state is the precondition for the "Charge" action.

I set it up in a way where if there are still more patients then the other doctors can handle it will wait to charge until it can. Thus prioritising helping patients over charging.

In my implementation I show the first nurses action on the top left.

### Patient

The patient spawns in outside the hospital.

He has 3 main goals

- IsWaiting (Get to the waiting room)
- IsTreated (Get to a bed and get treated)
- IsHome (Get to the home location)

So easy right? The patient enters, goes to the reception, checks in and goes to the waiting room.

In this gif I have no doctors that come get the patients, you can see how they all checkin and goto the waiting area.

![NoDoctors](./Assets/NoDoctors.gif)

Wait, how does the doctor get the patient from the room? Does the patient know when the doctor gets them? Not really.

The way we fix this is by making the world hold a global state of Patients, Beds, Chargers, etc.

This is stored internally as a Queue of Patients, when a patient enters the waiting room I add him to the queue. When a doctor looks for a patient I just pop him from the queue.

This allows the patient as well to know when a doctor gets him.
This is how I also show this on the UI on the top left.

- Waiting is decremented when the patient is retrieved from the waiting room
- FreeBeds is decremented because the doctor and patient will be using it.

When the patient gets treated he can now start on his final goal which has a precondition of "IsCured" (Eg. when he is treated by a doctor).

Home in my case is just somewhere outside the map where I remove him from the world.

Here you can see the final result of the doctors and patients working together.

![Final](https://brammie15.dev/Final.gif)

## Conclusion

Looking back on this research I wish I had more time to get deeper into this.
Its an interesting topic in AI I don't see often used in games.
I would guess the reason is because the planner is quite intensive to calculate.

## References

- Intro to GOAP
  - For a quick introduction
  - [Intro to Goal Oriented Action Planning (GOAP)](https://youtu.be/LhnlNKWh7oc?si=R5zwpf5OPyEYHRVS)

- Building the AI of F.E.A.R. with Goal Oriented Action Planning - AI and Games
  - Most of the understanding of GOAP
  - [Building the AI of F.E.A.R](https://youtu.be/PaOLBOuyswI?si=cwH2paeVlTySvhkD)

Thank you for reading this, have an amazing day!
