Hexnibbler
Recruit
I observed that the agent individual AI often behave dangerously in battles.
There also is this tendency to "gather around" the same target. It can be easily seen when the enemies is routed or during a "charge".
Often, two similar blocks of similar infantry simultanously win a flank and lose the other due to formation not being aligned for some reason. And it allow to observe the same issue : massive amount of troops on both sides "grinding" their way to the middle to face the opposite team's group of soldiers that won his side of the clash.
I wrote a little mod to get a better idea of what is going on during battle with the targets.
So I have a custom "CustomBattleAgentLogic" class to make tests in custom battles. Overiding "public override void OnAgentHit(Agent affectedAgent, Agent affectorAgent, int damage, in MissionWeapon attackerWeapon)" and the "tick(float dt)".
I used 200vs200 imperial default infantry to gather various data.
The first batch of data was about "is the agent being struck (A) was himself targetting his attacker (B)?"
So I have 4 categories of answers :
A was targetting B and B was targetting A. This is "On Target".
A was not targetting B and B was targetting A. This if "Not Target" (or Off Target)
2 more cases : Collateral damage.
A was not targetting B and B was not targetting A either but hit him. This is "Not Target Coll" for collateral.
And the funny case of A was targetting B and B was not targetting A but struck him : On Target collateral.
any time a hit occured, I select his category and increase a counter for this category. Then I divide by the amount of hit of all category so far.
I collected data point over the course of a battle (which is reduce to a frontal clash of two similar formations) and plotted it. It's not a scientifically accurate work, but I found it interresting so I share :
(note, you can right click and "get image url" to have a full scale view of those links if you have trouble reading the digits)
Both upper represent "On Target", lower represent "Off Target", Left side is "Intentional", Right side if "collateral". And the 5th one is the total of all hit ovetime.
Adding all value for the 4 graphs sums up to 1.0 : the total quantity of hits.
Ticks were recorded at 16ms.
1) The proportion of "intentional" hits increase over time because overtime casualties makes collateral damage less likely. Similarly, the collateral (right) decrease overtime.
2) The proportion of "OnTarget" is very low and the proportion of "OffTarget" is very high.
At tick 500, the OnTarget are only 13% + 8% for the collateral and the OffTarget are 39%+40%.
This means 2 things : in 79% of the cases, the agent being hit wasn't targetting his attacker. And in 48% the attacker himself wasn't targetting his victim.
It is important to note that it is "accumulated" : what matters is the "trend". It shows that 80% of the hit SO FAR have been landed on target that weren't "targetting" whoever struck them, and in 48% it was by accident. While this 48% is big and raise questions, it simply shows the chaotic mess of the first moment of the "clash". It still is believable behvior : any player who has played "on foot" in those melee knows that you just "smash whoever is somewhere there" without knowing or targetting anyone in particular.
3) the fifth curve shows as expected that the slope decrease overtime : less and less hit because there are less and less valid targets.
I came up with another question : How many people are targetting whoever is being struck ?
I simply maintained a list of agent that was updated at each tick for each agent : if his target has changed, I update the list of his old and his new target so that I can count how many agent are in those lists.
When a hit occured, I checked its category and added the size of that list to a counteer for that category. So that I can have an estimate of how many agent were targetting the victim of the strike when it got hit. The layout is the same : OnTarget, OnTargetColl, OffTarget, OffTargetColl and Total.
First, there is a difference in shape between the "Intentional" and the "Collateral" : the intentional Off target especially looks like the "total" : it's big at first, then decrease and then rise a bit.
The collateral are relatively stable after the initial clash. Which makes sense : the less people targetting you, the more likely that being hit will be an accident. It stabilize overtime meaning those accident are less frequent at the end, which makes sense : the density of people lowers, which lowers the accidents rate.
Both "OnTarget" have lower enemy count than "OffTarget", which is to be expected : it is more likely to be hit by someone that is not your target if there are more people trying to hit you.
The value of the total is interresting too : it is confirms that in most cases, you are hit when you are targetted by more than 1 person. So it is consitent with the first set of plots where: AI Agent get hit by Agent that they do not target themselves. If 10 people fight 10 people ,but each strike was the result of a 5 vs 1, it means that at least 4 agents in each team attack someone that is already attacked while 4 agents are not being targetted at all. Note that the way it is counted doesn't imply that all agent "targetting" that victim were in any capacity of playing an active role. But it seems reasonable to assume they do based on empiric observation.
So I asked myself another question : how many attackers are targetting whoever managed to land a hit in this mess ?
I did a similar count, but this time instead of counting the "attacker" in the list of the victim, I counted those in the list of the attacker himself.
All plots have the same shape. Sharp at first, and decrease overtime.
the collateral one will stay above 1 and will be higher than the "intentional" (more likely to hit someone by accident if the density is higher, and if the density is higher it is more likely to be a target.)
The initial clashes expose whoever is in a position to land a hit to many enemies which explains the high values, but it decreases super fast.
The "OffTarget" are interresting : the intentional one shows a sharp decline of the quantity of attackers an attacker that landed a hit has.
at 500 it is around 1 and decreasing, meaning there is on average LESS than one attacker for the agent that landed a hit. At tick 1000 it is below and decreasing.
Another good info would be to record how many people that landed a hit were themselves struck. But I haven't done it. I think this already offer a confirmation and an explanation of what is going on in melee :
AI targets on a variation of "enemy closest to me". It might weight in various thing.
1) we know that those being hit are more often hit by an agent they were not targetting themselves.
2) we know that those being hit are more often the target of many ennemies, leaving others without a threat.
3) we know that most hit that are being landed comes from those who were "left alone" so to speak.
It confirms that AI agent lack a mechanic to better select their target which ultimately leads to behaviors that are bad for its own health and not "believable".
Agent behavior are nice (1v1 tournament they show they can be challenging), but all that is useless in the melee clashes because of that targetting issue and I find that a bit sad that an existing feature that is already good is being wasted because of this "small" issue (yeah I know AI is easy to fix until yuo have to actually fix it without breaking what was working otherwise :p, but still)
Sadly I couldn't find a way to overwrite the individual agent "TargetAgent" which I assume is the property used by the engine to direct the individual agents to a target.
I assume that a method such as SetTargetAgent is not an option (or not an easy one) for various technical reason (otherwise I would wonder why it isn't exposed)
There also is this tendency to "gather around" the same target. It can be easily seen when the enemies is routed or during a "charge".
Often, two similar blocks of similar infantry simultanously win a flank and lose the other due to formation not being aligned for some reason. And it allow to observe the same issue : massive amount of troops on both sides "grinding" their way to the middle to face the opposite team's group of soldiers that won his side of the clash.
I wrote a little mod to get a better idea of what is going on during battle with the targets.
So I have a custom "CustomBattleAgentLogic" class to make tests in custom battles. Overiding "public override void OnAgentHit(Agent affectedAgent, Agent affectorAgent, int damage, in MissionWeapon attackerWeapon)" and the "tick(float dt)".
I used 200vs200 imperial default infantry to gather various data.
The first batch of data was about "is the agent being struck (A) was himself targetting his attacker (B)?"
So I have 4 categories of answers :
A was targetting B and B was targetting A. This is "On Target".
A was not targetting B and B was targetting A. This if "Not Target" (or Off Target)
2 more cases : Collateral damage.
A was not targetting B and B was not targetting A either but hit him. This is "Not Target Coll" for collateral.
And the funny case of A was targetting B and B was not targetting A but struck him : On Target collateral.
any time a hit occured, I select his category and increase a counter for this category. Then I divide by the amount of hit of all category so far.
I collected data point over the course of a battle (which is reduce to a frontal clash of two similar formations) and plotted it. It's not a scientifically accurate work, but I found it interresting so I share :
(note, you can right click and "get image url" to have a full scale view of those links if you have trouble reading the digits)
Both upper represent "On Target", lower represent "Off Target", Left side is "Intentional", Right side if "collateral". And the 5th one is the total of all hit ovetime.
Adding all value for the 4 graphs sums up to 1.0 : the total quantity of hits.
Ticks were recorded at 16ms.
1) The proportion of "intentional" hits increase over time because overtime casualties makes collateral damage less likely. Similarly, the collateral (right) decrease overtime.
2) The proportion of "OnTarget" is very low and the proportion of "OffTarget" is very high.
At tick 500, the OnTarget are only 13% + 8% for the collateral and the OffTarget are 39%+40%.
This means 2 things : in 79% of the cases, the agent being hit wasn't targetting his attacker. And in 48% the attacker himself wasn't targetting his victim.
It is important to note that it is "accumulated" : what matters is the "trend". It shows that 80% of the hit SO FAR have been landed on target that weren't "targetting" whoever struck them, and in 48% it was by accident. While this 48% is big and raise questions, it simply shows the chaotic mess of the first moment of the "clash". It still is believable behvior : any player who has played "on foot" in those melee knows that you just "smash whoever is somewhere there" without knowing or targetting anyone in particular.
3) the fifth curve shows as expected that the slope decrease overtime : less and less hit because there are less and less valid targets.
I came up with another question : How many people are targetting whoever is being struck ?
I simply maintained a list of agent that was updated at each tick for each agent : if his target has changed, I update the list of his old and his new target so that I can count how many agent are in those lists.
When a hit occured, I checked its category and added the size of that list to a counteer for that category. So that I can have an estimate of how many agent were targetting the victim of the strike when it got hit. The layout is the same : OnTarget, OnTargetColl, OffTarget, OffTargetColl and Total.
First, there is a difference in shape between the "Intentional" and the "Collateral" : the intentional Off target especially looks like the "total" : it's big at first, then decrease and then rise a bit.
The collateral are relatively stable after the initial clash. Which makes sense : the less people targetting you, the more likely that being hit will be an accident. It stabilize overtime meaning those accident are less frequent at the end, which makes sense : the density of people lowers, which lowers the accidents rate.
Both "OnTarget" have lower enemy count than "OffTarget", which is to be expected : it is more likely to be hit by someone that is not your target if there are more people trying to hit you.
The value of the total is interresting too : it is confirms that in most cases, you are hit when you are targetted by more than 1 person. So it is consitent with the first set of plots where: AI Agent get hit by Agent that they do not target themselves. If 10 people fight 10 people ,but each strike was the result of a 5 vs 1, it means that at least 4 agents in each team attack someone that is already attacked while 4 agents are not being targetted at all. Note that the way it is counted doesn't imply that all agent "targetting" that victim were in any capacity of playing an active role. But it seems reasonable to assume they do based on empiric observation.
So I asked myself another question : how many attackers are targetting whoever managed to land a hit in this mess ?
I did a similar count, but this time instead of counting the "attacker" in the list of the victim, I counted those in the list of the attacker himself.
All plots have the same shape. Sharp at first, and decrease overtime.
the collateral one will stay above 1 and will be higher than the "intentional" (more likely to hit someone by accident if the density is higher, and if the density is higher it is more likely to be a target.)
The initial clashes expose whoever is in a position to land a hit to many enemies which explains the high values, but it decreases super fast.
The "OffTarget" are interresting : the intentional one shows a sharp decline of the quantity of attackers an attacker that landed a hit has.
at 500 it is around 1 and decreasing, meaning there is on average LESS than one attacker for the agent that landed a hit. At tick 1000 it is below and decreasing.
Another good info would be to record how many people that landed a hit were themselves struck. But I haven't done it. I think this already offer a confirmation and an explanation of what is going on in melee :
AI targets on a variation of "enemy closest to me". It might weight in various thing.
1) we know that those being hit are more often hit by an agent they were not targetting themselves.
2) we know that those being hit are more often the target of many ennemies, leaving others without a threat.
3) we know that most hit that are being landed comes from those who were "left alone" so to speak.
It confirms that AI agent lack a mechanic to better select their target which ultimately leads to behaviors that are bad for its own health and not "believable".
Agent behavior are nice (1v1 tournament they show they can be challenging), but all that is useless in the melee clashes because of that targetting issue and I find that a bit sad that an existing feature that is already good is being wasted because of this "small" issue (yeah I know AI is easy to fix until yuo have to actually fix it without breaking what was working otherwise :p, but still)
Sadly I couldn't find a way to overwrite the individual agent "TargetAgent" which I assume is the property used by the engine to direct the individual agents to a target.
I assume that a method such as SetTargetAgent is not an option (or not an easy one) for various technical reason (otherwise I would wonder why it isn't exposed)