AI Relations (Editing): Difference between revisions

From The DarkMod Wiki
Jump to navigationJump to search
No edit summary
Line 5: Line 5:
Different AI types are defined by their '''''team''''' property. Put simply, AI on one team will generally be friendly to each other and antagonistic to AI on some other teams and tolerate yet others. Some AI teams are passive and will flee; others will attack. These are the values for the '''''team''''' property and their team type:
Different AI types are defined by their '''''team''''' property. Put simply, AI on one team will generally be friendly to each other and antagonistic to AI on some other teams and tolerate yet others. Some AI teams are passive and will flee; others will attack. These are the values for the '''''team''''' property and their team type:


* 0 = player
* '''0 = player'''
* 1 = servants, builders, thieves, beggars, commoners, elementals, zombie(short)
* 1 = servants, builders, thieves, beggars, commoners, elementals, zombie(short)
* 2 = city guards, indoor guards, inventors/engineers
* 2 = city guards, indoor guards, inventors/engineers
Line 12: Line 12:
* 5 = creatures (spiders, belchers, rats,) steambots
* 5 = creatures (spiders, belchers, rats,) steambots
* 6 = pagans
* 6 = pagans
== Default Relationships ==
Even if you're starting your map from scratch, the game will always load a set of default relationships from the entityDef '''atdm:team_relations_default'''. By default, all teams are friendly to itself (team 2 is friendly to team 2).
You can view this set by opening the <tt>tdm_team_relations.def</tt> file, but '''do not alter''' these values. See the next section about how to specify custom team relations.


== Inputting Team Relationship Info in the Editor ==
== Inputting Team Relationship Info in the Editor ==
To specify relationships for your own map, create an entity '''atdm:team_relations''' in your map. (A small rectangular entity will show up.) Override certain relationships by adding spawnargs to this entity in the following way:


# Add all the AI you're going to add, sort out what teams you want each to be on, setting the "team" key to the appropriate integer value on the AI entities. (eg, team 0 = player, team 1 = indoor guards/servants, team 2 = city guards, team 3 = city civilians, team 4 = undead )
"rel 0,2" "1"
# Define the relationship matrix on the Worldspawn. (To edit the worldspawn, select a wall and hit "n". That should bring up the key/value pairs on the worldspawn.)


To define the relationship matrix, add keys and values in the following way:
The left-hand key holds a pair of numbers defining the team numbers the relationship refers to, the right-hand value holds the type of relationship. Read this spawnarg like this:
''Team '''0''' considers Team '''2''' as '''friendly'''.''
As you might suspect, the right-hand value has the following convention:
* Negative (value < 0): '''hostile'''
* 0 is '''neutral'''
* Positive (value > 0): '''values'''


  key: "rel 0,1" value: "1"
{{Important|headline=Important|text=The above spawnarg does '''not''' imply that team 2 regards team 0 as friendly too. This has to be specified explicitly, defining the asymmetric matrix element.}}
To define the relationship for the reverse (team 2 => team 0), add a spawnarg like this:
  "rel 2,0" "1"
Note that it is indeed possible to define a different relationship for 0 => 2 than for 2 => 0. Also, it's possible to define the relationship for the team itself, like
"rel 2,2" "-1"
This lets members of team 2 consider all members of the same team as hostile.


That means team 0's relationship with team 1 has the value 1. (Positive values ar e friendly, negative values are enemy, 0 is neutral.)
One small note about the '''atdm:team_relations''' entity: this entity will pass its spawnargs to the relationship manager at spawn time and remove itself immediately afterwards, so that you don't have an unnecessary entity floating around your map.


If you have say 3 teams, you have to set at least the "upper triangle" of the matrix. If an element in the lower triangle is not found, it assumes it is the same as the upper traingle (ie, if you only supply 0,1 , 1,0 is assumed to be the same - symmetric relations).
== Why set the diagonals? ==
It might seem weird to define a team's relationship with itself by setting "rel 1,1" to something, but later on we might want to have a "rogue team," like beasts that attack everyone, even other members of the "beast" team (eg, a cannibalistic predator or something). Also, the team's relationship with itself can be thought of as "morale," and we can maybe check this number to see how likely they are to come to each other's aid in combat and stuff like that.


If you do not supply a value for the diagonal relationship (0,0 or 1,1), a default value is used. Right now I set this default to "5", but that can of course change.
Just to emphasize, you don't HAVE to set the diagonals, they will be set to some default value (5) if a new team is added to the relationship matrix. If you want team X "every man for himself" and attack its own members, set "rel X,X" explicitly to a negative value.


What I mean by upper and lower triangle is: 0,1 1,2 etc are part of the upper triangle (column > row), 1,0 2,1 are part of the lower triangle (row > column). So you have to put in 0,1 but if you want 1,0 to be the same, you don't have to put it in. (ie, team 1's relationship with team 0 is the same as team 0's relationship with team 1, if you don't specifically put in a different value for 1,0 than you put in for 0,1)
== Changing Relationships during the Game ==
To let relationships change during runtime, you can use triggers or scripts. There is a trigger entity called '''target_tdm_setrelations''' which can hold the same type of relationship spawnargs as described above. To activate these settings, just trigger this entity. Note that you can even trigger this entity multiple times, so you can re-use it, if you ever wanted to.


== Why set the diagonals? ==
If you're switching teams to friendly, remember to define both directions of the relationship on these types of entities ("0,2" as well as "2,0").
It might seem weird to define a team's relationship with itself by setting "rel 1,1" to something, but later on we might want to have a "rogue team," like beasts that attack everyone, even other members of the "beast" team (eg, a cannibalistic predator or something). Also, the teams' relationship with itself can be thought of as "morale," and we can maybe check this number to see how likely they are to come to each other's aid in combat and stuff like that.
 
== What happens if a Team is not mentioned at all? ==
If an AI is present in the map (or maybe is spawned by script later during the game), whose team is not mentioned in the matrix (like, say, team 60), the relationship code will handle this gracefully and consider this team as hostile to all the other teams. Still, members of team 60 are friendly to all other members of team 60 by default.


Just to emphasize, you don't HAVE to set the diagonals, they will be set to some default value (5) if you don't. If you want team X "every man for himself" and attack its own members, set "rel X,X" to a negative value.
== Debugging Relatinships ==
Use the following console command to dump the current values of the relationship matrix to the console:
tdm_ai_rel_print
This will produce a rather long list, so you might want to use the <tt>condump</tt> command to write the console output to a file for later studying.


If no relationship matrix is present, or if the mapper makes an error when inputting it and you see a "[AI Relations] logical error..." or "[AI Relations] Syntax error..." message when you play the map:
Also, watch out for console warnings during map start, which might indicate syntax errors of your spawnargs. Finally, it's also possible to use the log file. Activate the AI log class to see any messages coming from the relationship code.
A value of -1 will always be returned by relationship matrix checks, meaning all AI are enemies. (this slightly screws up existing D3 maps if they have no relationship matrix, since some AI are enemies that aren't supposed to be. I'm still working on fixing that)


[[Category:AI]]
[[Category:AI]]
[[Category:Editing]]
[[Category:Editing]]

Revision as of 07:39, 13 March 2009

Originally written by Ishtvan on http://forums.thedarkmod.com/topic/1636

AI Types (Teams)

Different AI types are defined by their team property. Put simply, AI on one team will generally be friendly to each other and antagonistic to AI on some other teams and tolerate yet others. Some AI teams are passive and will flee; others will attack. These are the values for the team property and their team type:

  • 0 = player
  • 1 = servants, builders, thieves, beggars, commoners, elementals, zombie(short)
  • 2 = city guards, indoor guards, inventors/engineers
  • 3 = nobility, thugs
  • 4 = undead (zombies, revenants)
  • 5 = creatures (spiders, belchers, rats,) steambots
  • 6 = pagans

Default Relationships

Even if you're starting your map from scratch, the game will always load a set of default relationships from the entityDef atdm:team_relations_default. By default, all teams are friendly to itself (team 2 is friendly to team 2).

You can view this set by opening the tdm_team_relations.def file, but do not alter these values. See the next section about how to specify custom team relations.

Inputting Team Relationship Info in the Editor

To specify relationships for your own map, create an entity atdm:team_relations in your map. (A small rectangular entity will show up.) Override certain relationships by adding spawnargs to this entity in the following way:

"rel 0,2" "1"

The left-hand key holds a pair of numbers defining the team numbers the relationship refers to, the right-hand value holds the type of relationship. Read this spawnarg like this:

Team 0 considers Team 2 as friendly. 

As you might suspect, the right-hand value has the following convention:

  • Negative (value < 0): hostile
  • 0 is neutral
  • Positive (value > 0): values

Important

The above spawnarg does not imply that team 2 regards team 0 as friendly too. This has to be specified explicitly, defining the asymmetric matrix element.

To define the relationship for the reverse (team 2 => team 0), add a spawnarg like this:

"rel 2,0" "1"

Note that it is indeed possible to define a different relationship for 0 => 2 than for 2 => 0. Also, it's possible to define the relationship for the team itself, like

"rel 2,2" "-1"

This lets members of team 2 consider all members of the same team as hostile.

One small note about the atdm:team_relations entity: this entity will pass its spawnargs to the relationship manager at spawn time and remove itself immediately afterwards, so that you don't have an unnecessary entity floating around your map.

Why set the diagonals?

It might seem weird to define a team's relationship with itself by setting "rel 1,1" to something, but later on we might want to have a "rogue team," like beasts that attack everyone, even other members of the "beast" team (eg, a cannibalistic predator or something). Also, the team's relationship with itself can be thought of as "morale," and we can maybe check this number to see how likely they are to come to each other's aid in combat and stuff like that.

Just to emphasize, you don't HAVE to set the diagonals, they will be set to some default value (5) if a new team is added to the relationship matrix. If you want team X "every man for himself" and attack its own members, set "rel X,X" explicitly to a negative value.

Changing Relationships during the Game

To let relationships change during runtime, you can use triggers or scripts. There is a trigger entity called target_tdm_setrelations which can hold the same type of relationship spawnargs as described above. To activate these settings, just trigger this entity. Note that you can even trigger this entity multiple times, so you can re-use it, if you ever wanted to.

If you're switching teams to friendly, remember to define both directions of the relationship on these types of entities ("0,2" as well as "2,0").

What happens if a Team is not mentioned at all?

If an AI is present in the map (or maybe is spawned by script later during the game), whose team is not mentioned in the matrix (like, say, team 60), the relationship code will handle this gracefully and consider this team as hostile to all the other teams. Still, members of team 60 are friendly to all other members of team 60 by default.

Debugging Relatinships

Use the following console command to dump the current values of the relationship matrix to the console:

tdm_ai_rel_print

This will produce a rather long list, so you might want to use the condump command to write the console output to a file for later studying.

Also, watch out for console warnings during map start, which might indicate syntax errors of your spawnargs. Finally, it's also possible to use the log file. Activate the AI log class to see any messages coming from the relationship code.