Hello and welcome back. In this post I will be sharing with you the progress I have made on the scripts that will be used for the GOAP based A.I system that I am currently creating. If you haven't seen my previous post about the A.I system, I would highly recommend reading it as I talk about the structure I plan to use for the system, as well as a brief start on the scripts that I will be talking about in more detail in this post.
Creating Scripts
As mentioned at the end of the previous post, I wanted to start creating the scripts I had planned which is where I will start.
WorldData
The easiest script to create is the WorldData script I will be using. This wouldn't be the case for most games, as there is normally a lot of data being stored about the game world that the A.I and players alike would need access to. This is not the case for my test scenes and the only data that the A.I will need to begin with is their relation to one another (Allies, Neutral, Enemies, etc).
To start off, I made sure that the world data was a Singleton so the A.I had the correct version of the data. To do this, I used a simple method that assigned itself as a variable of the script if there wasn't already a version assigned.
Once the script was declared as a Singleton, all that was left to do was declare the variables to hold the data that the script would manage.
IAction
The next script to create was a little more complex. This time I needed to create an interface for the actions. This would be inherited on each action which means that every action created would have the correct variables, methods and information needed to be used with the GOAP system action planner that I will be creating later.
Using the plan I created in the last post I populated the interface with variable and method names ready to be implemented into the action scripts when I start creating actions for the agents to perform.
Now that I have a basis for an action and a script that will be storing the world data. I started planning and creating a script that will be the backbone of the system; The action planner. This script will be a little more complex as it will need to control not only the creation of the plan, but reference scripts that haven't been implemented yet, namely the Agent script.
ActionPlanner
This is one of, if not, the most important script for the system as it is responsible for comparing the agents and world status' against the agent's end goal whilst also planning a set of actions the agent needs to complete in order to reach its end goal.
References | Methods/Variables | | |
Agent | method: execute plan | method: build plan | method: available actions |
| method: can perform action | method: simulate action completion | |
Alongside these variables and methods, the action planner script will need a private subclass that will be used to house data from the actions briefly whilst creating the action plan. This class will act as a simulation of the action so the planner can enact the results of the actions without performing them. This will be used to build a tree network of actions all linked in order of what to perform to reach the desired goal.
Class Name | Variables | | |
Node | var: parent node | var: weight | var: state |
| var: action | Constructor | |
Now that I have planned out the different methods I will need for the script, I proceeded to implement the structure of the methods. There is a couple of errors within the script currently as I haven't created a couple of scripts necessary to make the whole planning system functional which will be the next task to complete.
Currently, the script is only declarations of the methods and have no real body to them. This will need to be completed after I have created more scripts that will be used within the planner, such as an Agent and actions to create a plan with.
IAgent
Now that I am getting further into the implementation of the action planning part of the A.I system, I am in need of a agent script, or in my case an interface, that each agent will inherit from. This script will also be used within the action planning system to retrieve the agent's current state as well as available actions, alongside other information needed.
To start off, I once again planned out what the interface would need to provide the Agent scripts.
Methods/Variables | | | |
var: planner | var: available actions | var: current plan | var: agent data |
var: goal | var: animator | var: state | method: collate actions |
Debug Methods | | | |
method: plan created | method: plan failed | method: plan complete | method: plan aborted |
I have decided to create a few debug methods within the IAgent interface which will provide me with information on the current state of the agent and the action plan associated with them. These methods will help with:
Seeing if the agent has successfully completed its plan
Seeing if/when the agent has had to abort the plan because of a change of situation
Seeing if the agent (the planner) has been successful or failed at creating a viable action plan
A more in depth game would require more variables or even an enumeration in the agent's interface to store extra information about the agent. As a few examples, this information could include:
Health
Level
Experience worth
Equipment
In later scenarios I will be requiring additional information such as this but for now, as there is no planned combat presence in the test scenario, I will not be needing it at this time.
An Agent and Action
The last thing I need to do is create scripts for an agent and a simple action. The action I will be creating to begin with is the simple Idle action, which will be the default state and action an agent is in before a viable plan is created to complete their goal. As for the agent, a simple passive civilian will be created for testing purposes before moving on to more advanced agents such as labourers.
Between the two scripts, it isn't as important for me as to which one is created first as I am using an interface foundation however, other implementation methods might require a specific order, especially if there are specific references between the agent and the actions. Personally, I will be creating the agent script first as this is a little less complicated then creating an action.
Agent Smith
Using the agent interface that I have just created, I will create a simple A.I agent that will not have a specific goal set as there will be no actions that will satisfy a specific goal. As there is no goal it should perform the default (idle) action. The action planner should create the simplest of plans for the agent to follow; stand idle. Once the idle action timer has passed, the planner should then create a new plan.
In the image above, you may notice that there is not a goal set in the Start() method. For more advanced agents such as the labourers, there will be a goal assigned to match their jobs, however for testing purposes, my civilian will not have a goal set as I want them to do nothing (idle).
Idle Actions
The last script to create is that of the idle action. Using the action interface I have previously created, declaring the correct information and methods for the action will be quite simple however the body of some of the methods will require more attention.
I won't be showing the detailed code of the actions but the general structure of the action scripts can be seen below. What is shown is the required methods and variables inherited and implemented from the action interface I have created.
That is it for this post. I still need to create the methods on the Action Planner script as currently they are only the declarations. After that it will be action testing, making sure that my implementation of the actions is working as intended, and then move forward with creating more actions and different agents.
As always, if you would like to stay up to date, be sure to check back regularly to see if there is any news or updates regarding this project!
Comments