Agent Definitions: Difference between revisions

From Off Grid Wiki
Jump to navigation Jump to search
No edit summary
mNo edit summary
Line 230: Line 230:
An Interest may be a Device, or may simply be a particular part of a level that an AI needs to get to in order to perform an Action. An Interest is created by adding an InterestPoint to a GameObject (or making a new GameObject with an InterestPoint added). Be sure to orient the GameObject such that the Z axis is pointing in the direction the AI should use the InterestPoint from.
An Interest may be a Device, or may simply be a particular part of a level that an AI needs to get to in order to perform an Action. An Interest is created by adding an InterestPoint to a GameObject (or making a new GameObject with an InterestPoint added). Be sure to orient the GameObject such that the Z axis is pointing in the direction the AI should use the InterestPoint from.
==== canUse ====
==== canUse ====
This is a using Action. The Agent will attempt to reach the nearest Interest that they know to be working, and try to use it. If it's in an Amok state, this may fail.
This is a using Action. The Agent will attempt to reach the nearest Interest that they know to be working, and try to use it. If it's in an Amok state, this may fail. The table is pretty similar to a standard [[#Action|Action]].
{| class="wikitable"
!colspan="2" | canUse Table
|-   
! Name !! Description
|-
| ''interest'' || The name of the InterestPoint this Action will take place at.
|-
| ''effect'' || The effect [[#GOAP State|GOAP State]]. This will be applied to the World State when this Action is performed.
|-
| ''required'' || The required [[#GOAP State|GOAP State]]. The World State must include this state in order for the Action to be used.
|-
| ''personalityEffect'' || Optional. The [[#Statistics|effect]] on personality stats that performing this Action has.
|-
| ''personalityRequirement'' || Optional. For this Action to be performed, this [[#Personality|requirement]] must be satisfied.
|}
 
==== canFix ====
==== canFix ====
This will eventually be a fixing Action. (TODO!)
This will eventually be a fixing Action. (TODO!)


[[Category:Modding]]
[[Category:Modding]]

Revision as of 12:52, 6 December 2018

Agent Definitions

Each AI's behaviour is defined by its Agent definition.

Concepts

GOAP State

The World State and Goal states are made up of GOAP States. GOAP stands for "Goal-Oriented Action Planning". Each state comprises a unique string ID, and a boolean (true/false) value. The state as a whole is made up of multiple state items.

GOAP State Item
Name Description
state The unique name of the state.
value The true/false value.

A state is made up of 1-n items. This can be represented either as

{
	{ state = "amused", value = false },
	{ state = "tired", value = false },
}

or, for a state with a single item in, as

{ state = "amused", value = false }

...which saves some slightly untidy extra braces. Note that in the former example, the items are just an anonymous list, the keys are implicit. GOAP State is a type that will appear throughout this guide and it is always parsed in the same way.

Personality

Each AI (TBC: Human AI?) should have a personality profile. This describes the AI's likes, loves, family, dog... anything you like. This is one of the main mechanisms for differentiating behaviour between agents - thus allowing a player's actions to affect multiple agents in multiple ways, and allows for complex behaviour. The mechanism for doing this is the Personality Requirement.

Personality Requirement
Name Type Description
subject string The primary tag that this requirement is seeking.
value string Optional. The value that has a tag matching subject.
other string Optional. Another tag, or list of tags, that the value must match with for this requirement to be satisfied.
inverse boolean Defaults to false. Setting to true swaps the result of the requirement - so a match means the requirement fails, and the lack of a match means the requirement passes.

Here's a snippet of a Personality Profile.

{ data = { "HipHop", "Pop"}, tags = { "music", "likes" } },
{ data = { "Rock"}, tags = { "music", "dislikes" } },
{ data = { "Classical", "HipHop"}, tags = { "music", "relaxes" } },
{ data = { "LiverpoolReds" }, tags = { "sport", "likes", "celebrates" } },

So, this AI considers that HipHop & Pop are both music, and they like it. They consider Rock to be music, but they dislike it. They consider Classical and HipHop to be music that relaxes them. They consider LiverpoolReds to be related to sport, they like it, and they celebrate it.

The only mandatory part of a requirement is the subject. The subject is merely a tag, but it's the tag we look for first, and it's the tag that can be specified by API call ChangeSubject. Let's write a requirement that will pass using only the subject.

personalityRequirement = { subject = "music" },

This requirement, wherever it's used, will pass if the subject of "music" is set to "HipHop", "Pop", "Rock", or "Classical". So for instance, we might trigger a Dance Action if music is set to any of these. But that might not make a huge amount of sense for this AI, because they're not so keen on Rock music. So let's add an extra tag that we need for this requirement to be satisfied.

personalityRequirement = { subject = "music", other = "likes" },

This means the requirement will no longer pass for "Classical" or "Rock", because they aren't tagged as "likes" in their profile. That makes more sense! But... do we want the AI to perform the same dance to "HipHop" and "Rock"? Possibly not. This is where the value attribute is useful.

personalityRequirement = { value = "Rock", subject = "music", other = "likes" },

This requirement only passes for agents who like Rock music.

Finally, what's inverse for? Essentially, it's for checking for the absence of something. Consider the requirement

personalityRequirement = { value = "ManchesterBlues", subject = "celebrates", inverse = true },

Well spotted - "ManchesterBlues" is not present in our profile snippet. This means that, without the inverse flag, this requirement would fail. But with it, it passes! So, supposing we had a radio which set the subject as "celebrates", and the value as "ManchesterBlues", we could get this AI to sob gently to himself, while the one stood next to him is overcome with joy.

Statistics

Each statistic is a tracked, saved, numerical value that represents a particular aspect of the AI. The value is clamped between 0 and 1. Each stat has two lists, above and below, of names and thresholds. These will become world states that become true when the value becomes greater or equal/lesser or equal (respectively) to the threshold value. Statistics can be adjusted by actions, responses, and reactions. In doing so the world state may change, and new goals become achievable.

Personality Effects will be referred to throughout this, so let's dig into them here.

Personality Effect
Name Type Description
stat string The unique name of the stat.
adjust number The value to be added to the current value of this stat. Use a negative number to reduce it!

One of the simpler tables in the Agent Definition. Simply put, when this effect happens, the named stat will have adjust added to it. The stat will then be clamped in the range 0 - 1, and the world states that rely on it will be recalculated.

File Format

The definition is a single table, named Agent, containing several tables that define different aspects of an Agent.

World State

The World State is a description of everything an AI knows about, in the context of planning. It is simply a GOAP State.

Goals

A Goal is a state that an Agent desires to be in. The planner will seek to use the Actions at its disposal to come up with a plan (set of Actions) that it can run to adjust the current World State so that it includes the Goal state. At its heart is a GOAP State, but it has some extra wizardry too.

Personality Effect
Name Type Description
goal table A GOAP State.
interrupts boolean Defaults to false. When set to true, this Goal will interrupt any of lower priority if it becomes achievable. For instance, chasing the player is more important than eating a snack.
priority number The higher the priority a goal is, the more important it is. As a result it will be attempted before lower priority goals.
onCompletion table Optional. This is a GOAP State that will be applied to the World State when this goal is successful. Useful for cyclic tasks (e.g. patrolling).

Stats

List of Statistics.

Statistic Table
Name Type Description
name string Unique name for this statistic.
default number Default value for this statistic.
above table List of states that will become true when above or equal to the specified threshold (see next table).
below table List of states that will become true when below or equal to the specified threshold (see next table).
Statistic-State Table
Name Type Description
id string The name of the world state to be created.
threshold number Threshold for this statistic. Behaviour depends upon whether this state is in the above or below table.

So, what might this look like?

{
	name = "happiness",
	default = 0.5,
	above = { 
			{ id = "elated", threshold = 1.00 }
			{ id = "cheerful", threshold = 0.8 }
		}
},

This stat is called happiness. It starts at 0.5. It has two world states, "elated", which becomes true at maximum happiness (1.0), and "cheerful", which happens when it's merely 0.8.

{
			name = "energy",
			default = 0.5,
			above = { id = "energized", threshold = 1.0 },
			below = { id = "tired", threshold = 0.0 }
		},

Notice that this one has a single entry in both above and below, missing out the nested brackets.

Actions

An Actions is something that the AI does. In order to do it, it must have a particular world state. After having done it, it will change its world state.

Action Table
Name Description
name The name of the Action, which should be unique.
gesture Optional. The gesture to play when performing this Action.
effect The effect GOAP State. This will be applied to the World State when this Action is performed. See XXXX
required The required GOAP State. The World State must include this state in order for the Action to be used.
personalityEffect Optional. The effect on personality stats that performing this Action has.
targetAgent Default false. If true, the Agent requires that there be another agent nearby for this Action to be performed.
targetPlayer Default false. If true, the Agent requires that the player be nearby for this Action to be performed.
targetRequirement Optional. The required personality profile this AI needs for this Action to run.

Responses

A response is a method of adjusting an AI's personality stats when another AI performs an Action on them.

Response Table
Name Description
Action The name of the Action, which should be unique.
personalityEffect The effect on personality stats that being the victim of this Action has.

Reactions

A reaction is a method of adjusting an AI's personality stats when they do something, based on their personality profile. These effects will be performed when ReactTo is called, if the requirement is satisfied.

Reaction Table
Name Description
personalityRequirement The requirement, which, when reacted to, will bring about the effect.
personalityEffect The effect on personality stats that occurs.

Let's look at a quick example of how to use this.

{
		personalityEffect = { stat = "energy", adjust = -0.5 },
		personalityRequirement = { subject = "music", other = "relaxes" },
	}

Here we have an effect that requires a personality entry that is tagged both as "music", and "relaxes". How does this get used? Well, for the purpose of this example, let's assume this AI has stepped into earshot of a radio, which has its own script. As a result, the following is called

AI.ReactTo(theAI, "music", "Classical")

What does this do? This says that the AI (which will be referred to by the variable theAI, a string referencing the AI's ID) should "React To" some external influence of tag "music", with the value of "Classical". If this requirement holds, the effect applies.

So the AI with this personality will have the effect applied, in this situation...

{ data = { "Classical", "HipHop"}, tags = { "music", "relaxes" } },

...and this AI won't.

{ data = { "Dance"}, tags = { "music", "relaxes" } },

Interests

An Interest may be a Device, or may simply be a particular part of a level that an AI needs to get to in order to perform an Action. An Interest is created by adding an InterestPoint to a GameObject (or making a new GameObject with an InterestPoint added). Be sure to orient the GameObject such that the Z axis is pointing in the direction the AI should use the InterestPoint from.

canUse

This is a using Action. The Agent will attempt to reach the nearest Interest that they know to be working, and try to use it. If it's in an Amok state, this may fail. The table is pretty similar to a standard Action.

canUse Table
Name Description
interest The name of the InterestPoint this Action will take place at.
effect The effect GOAP State. This will be applied to the World State when this Action is performed.
required The required GOAP State. The World State must include this state in order for the Action to be used.
personalityEffect Optional. The effect on personality stats that performing this Action has.
personalityRequirement Optional. For this Action to be performed, this requirement must be satisfied.

canFix

This will eventually be a fixing Action. (TODO!)