Perceptual Equations

Location: Data/XML/AI/PerceptualEquations

Perceptual equations are how the AI "sees" the game. They are algebraic/logic functions that return a value (or nil if they cannot evaluate).

The syntax consists of:

**<Perceptual\_Function\_Name>**

The tag for the function name. Must be unique.

**Operators**

+ the OR operator
\* the AND operator
- reduce the equation value, NOT operator
/ division
# generate a random value between two numbers e.g. (1 # 2)
() evaluate this first
> greater than operator. DO NOT USE < IT IS XML RESERVED
{ } Used to add parameters to tokens

**Tokens**

These will be broken into sections for clarity. The full list is in Data/XML/AI/Enum/PerceptionTokenType.XML

Tokens go as:

Variable.Literal.Final\_Literal {Parameters}

and can return any number, but often are normalized to the range 0-1

### Important Tokens

Script\_ScriptName.Evaluate evaluates the script ScriptName that is placed in the Data/Scripts/Evaluators folder. These scripts need a function called Evaluate that returns the value to the perception.

Function\_FunctionName.Evaluate evaluates the perceptual equation FunctionName and returns its value.

REMEMBER: perceptual equations and evaluator scripts only work from inside a MEG file!

**Main variables:**

These are the top-level of a token, and must be related to either the Goal application or the variable(s) sent from a Lua script's EvaluatePerception (more on that later).

e.g. if the goal application is Friendly\_Only then Variable\_Self would evaluate to the Player trying the goal.

<Variable\_Self> </Variable\_Self> PlayerObject evaluating perception

<Variable\_Location> </Variable\_Location> Unused

<Variable\_Target> </Variable\_Target> Target object evaluating perception e.g. planet

<Variable\_Enemy> </Variable\_Enemy> ALL enemies based on PlayerObject evaluating perception

<Variable\_Human> </Variable\_Human> Human playerobject

To see more tokens, see the Token sections at the end of the guide.

### Perceptual Equations: Working Examples

Let's take some examples from Petroglyph and deconstruct them in plain language. Petroglyph has done this themselves in some comments in the XML, so look around yourself!

````
        <Should_Conquer_Opponent_Planet>
		(
			1.25
			Function_Is_Good_Invasion_Target.Evaluate
			Variable_Target.IsHumanControlled
			((Variable_Self.HasUnit {Parameter_Type = "DEATH_STAR"} == 0.0)
			(Function_Want_To_Fire_DS.Evaluate == 0.0))
		)
		Function_First_Attack_Allowed.Evaluate
		(1.0 - Function_Should_Perform_Unrestricted_Grab_Space.Evaluate)
	</Should_Conquer_Opponent_Planet>

````
This is the equation that controls the Goal Conquer\_Opponent\_Planet. This is for when the AI wants to fight you!

Here we begin with a constant scaling factor of 1.25, followed by Function\_Is\_Good\_Invasion\_Target.Evaluate. This tells the game to evaluate ANOTHER equation, called "Is\_Good\_Invasion\_Target" and return its value.

So we have:

Scaled by 1.25

AND

Is a good target to invade

AND

Is human controlled (note that the Variable\_Target here is the enemy planet, and this token returns 0 or 1)

AND

I don't have the Death Star, nor do I want to fire it at this planet

AND

I'm allowed to attack

AND

I shouldn't try to take the space over this planet quickly

Here the 1 - [equation] acts like a NOT operator.

**Example 2: Need Research Facility**

````
        <Need_Research_Facility>
		Variable_Self.IsFaction {Parameter_Faction = "Empire"}
		(1 - Variable_Target.HasStructure {Parameter_Type = "E_Ground_Research_Facility"})
		Function_Has_Enough_Bases_For_Tech.Evaluate
		(Variable_Target.MaxStarbaseLevel == 5)
		(
			20 * (1 - (Variable_Self.StructureCount {Parameter_Type = "E_Ground_Research_Facility", Parameter_Only_Consider_Complete = 1.0} / 2))
			10 * Function_Empire_Should_Upgrade_Tech.Evaluate *
			(1 - Variable_Self.HasStructure {Parameter_Type = "E_Ground_Research_Facility", Parameter_Count = 1})
			3 * Function_Defense_Level.Evaluate
			3 * Function_Needs_Groundbase_Upgrade.Evaluate
		)
	</Need_Research_Facility>

````
This equation tells the Empire that it needs a research facility at a particular planet.

Am I the Empire?

AND

I DON'T have a research facility present (note the parameter\_type limiting HasStructure)

AND

I have enough bases that I should tech up

AND

The planet (the target) can support a level 5 starbase

AND

(
Reduce desire if I have more than 2 research facilities [1]

OR

Do I want to upgrade tech AND I have NO single research facility (here parameter count means that HasStructure returns 1 if there is only 1 Research Facility)

OR

Is the planet well defended?

OR

Does the planet need a groundbase upgrade?)

[1] Count how many complete research facilities I own (Parameter\_Only\_Consider\_Complete = 1.0 means that only completed objects are counted), divide by 2, and then reduce the value if I have more than 2 (using "1 -" as a NOT again)