Reducing overkill
Moderator: Moderators
Reducing overkill
I was thinking about making improvements to the targetting logic to prevent or at least reduce overkill.
I'll take GINTA as an example: Currently if you have 10 AA infantry (each of which can shoot only once in GINTA) in an area and a gunship passes by all ten will fire their missiles. One would have been enough to kill the gunship and because all ten fired theirs that's 9 missiles fired too many and an opening made for other gunships to fly through. In real life only one of them would shoot and the next one would wait until it's clear that the shot will miss to fire the next. Even if they don't have limited ammo that's smart behaviour because they give their position away by shooting.
I'd fix this by giving each unit an incoming ordinance variable that keeps track of how much damage is headed its way. Each projectile will remember its own value and add and subtract from the target's counter at launch and impact. A projectile would need a timer by when it should be considered a miss, I'd say projected flight time + 25% as a default, once that time passes the projectile subtracts its value from the target's counter and remembers that it has missed (so no subtracting twice).
A weapon that does not have a target issued by the player will consider anything with an ordinance counter > remaining HP an invalid target and won't try to shoot at it, if that was its current (not player defined) target the weapon will pick another target and if no valid target is available will wait until one appears.
Perhaps if the second logic has multiple targets of equal priority it picks the one with the lowest remaining HP...
Also targetting priority when looking for a new target will be changed from max cost to
min weaponDamage - (currentHP - incomingOrdinance) | if a target with (currentHP-incomingOrdinance < weaponDamage) is available
max weaponDamage*cost/maxHP | otherwise
i.e. look for something you can finish off with the least overkill, if not available pick the thing that you can do the most expensive damage to (which just assumes that targets with less HP/cost are more important to shoot while high HP/cost are bullet bait)
For this there would be a few new weapon tags:
ignoreOverkill: Will shoot even overkilled targets, defaults to 1 for AircraftBombs (since they cannot easily retarget), 0 otherwise
overkillMult: Multiplier for the damage that gets added to a target's incoming ordinance counter, useful for weapons that are slow to hit, inaccurate or perhaps unit personality (overconfidence in one's shots, perhaps). Should have a low default for AircraftBombs, possibly 0.
overkillTimeout: The time before it's assumed the projectile won't hit anyway. Default would be the projectile's ttl or something like that.
Paralyzers would be exempt from this logic.
What I'm worried about is properly tracking when a projectile is gone, would suck to have units consider something dead just because its ordinance counter wasn't properly reduced.
Likely remaining issues that I don't consider easily fixable are:
- Ordinance is only counted after the shot, not while aiming. Would be less effective with slow aimers (e.g. a bunch of BBs vs. targets scattered across the map) but since we don't even know if a weapon will ever finish aiming I don't think we can predict that it will fire just because it has a target.
- Even shots a player cannot see are considered for the ordinance count but for simplicity's sake I'd just ignore that, you'll see the shot soon enough.
- Nukes and other large AOE weapons aren't counted for all units in the AOE but that would require tracking units entering and leaving the AOE while the projectile is in the air which would probably eat too much CPU.
The improved behaviour should be default IMO, it's an improvement to more-or-less AI code and we wouldn't make pathfinder improvements default to off, would we?
I'll take GINTA as an example: Currently if you have 10 AA infantry (each of which can shoot only once in GINTA) in an area and a gunship passes by all ten will fire their missiles. One would have been enough to kill the gunship and because all ten fired theirs that's 9 missiles fired too many and an opening made for other gunships to fly through. In real life only one of them would shoot and the next one would wait until it's clear that the shot will miss to fire the next. Even if they don't have limited ammo that's smart behaviour because they give their position away by shooting.
I'd fix this by giving each unit an incoming ordinance variable that keeps track of how much damage is headed its way. Each projectile will remember its own value and add and subtract from the target's counter at launch and impact. A projectile would need a timer by when it should be considered a miss, I'd say projected flight time + 25% as a default, once that time passes the projectile subtracts its value from the target's counter and remembers that it has missed (so no subtracting twice).
A weapon that does not have a target issued by the player will consider anything with an ordinance counter > remaining HP an invalid target and won't try to shoot at it, if that was its current (not player defined) target the weapon will pick another target and if no valid target is available will wait until one appears.
Perhaps if the second logic has multiple targets of equal priority it picks the one with the lowest remaining HP...
Also targetting priority when looking for a new target will be changed from max cost to
min weaponDamage - (currentHP - incomingOrdinance) | if a target with (currentHP-incomingOrdinance < weaponDamage) is available
max weaponDamage*cost/maxHP | otherwise
i.e. look for something you can finish off with the least overkill, if not available pick the thing that you can do the most expensive damage to (which just assumes that targets with less HP/cost are more important to shoot while high HP/cost are bullet bait)
For this there would be a few new weapon tags:
ignoreOverkill: Will shoot even overkilled targets, defaults to 1 for AircraftBombs (since they cannot easily retarget), 0 otherwise
overkillMult: Multiplier for the damage that gets added to a target's incoming ordinance counter, useful for weapons that are slow to hit, inaccurate or perhaps unit personality (overconfidence in one's shots, perhaps). Should have a low default for AircraftBombs, possibly 0.
overkillTimeout: The time before it's assumed the projectile won't hit anyway. Default would be the projectile's ttl or something like that.
Paralyzers would be exempt from this logic.
What I'm worried about is properly tracking when a projectile is gone, would suck to have units consider something dead just because its ordinance counter wasn't properly reduced.
Likely remaining issues that I don't consider easily fixable are:
- Ordinance is only counted after the shot, not while aiming. Would be less effective with slow aimers (e.g. a bunch of BBs vs. targets scattered across the map) but since we don't even know if a weapon will ever finish aiming I don't think we can predict that it will fire just because it has a target.
- Even shots a player cannot see are considered for the ordinance count but for simplicity's sake I'd just ignore that, you'll see the shot soon enough.
- Nukes and other large AOE weapons aren't counted for all units in the AOE but that would require tracking units entering and leaving the AOE while the projectile is in the air which would probably eat too much CPU.
The improved behaviour should be default IMO, it's an improvement to more-or-less AI code and we wouldn't make pathfinder improvements default to off, would we?
- TechnoTone
- Posts: 165
- Joined: 23 Aug 2005, 22:02
Cool. This addresses what I was asking for here. I had considered the same method of doing so too (tracking a sum of incoming damage for each unit) but didn't know how feasible that would be.
Suggestions for paralyzer weapons, instead of just nothing:
default overkillMult is set so that paralysis units will not pick a target that is more than 90% of the way to the maximum paralysis time. So if a unit has an attack that can paralyze for up to 10 seconds, it won't pick units that will already be frozen for over nine seconds. [1/(1+0.0225f*damages.paralyzeDamageTime)]
default overkillMult is set so that paralysis units will not pick a target that is more than 90% of the way to the maximum paralysis time. So if a unit has an attack that can paralyze for up to 10 seconds, it won't pick units that will already be frozen for over nine seconds. [1/(1+0.0225f*damages.paralyzeDamageTime)]
I can see this being a slight problem for rapid-fire, inaccurate weapons, especially ones that do not aim quickly or in the case where there are no other targets to shoot at.
If a larger proportion or majority of shots are missing their targets, you might get the weapon doing a stop-start fire, shooting at an enemy, ignoring it, shooting again when the shot is missed, ignoring it etc.
Take for example a tremor trying to hit a mex. It will shoot one shot (enough to kill the mex), stop, shoot another when it misses, etc. Of course you'd want to make a tremor attack ground usually anyway, but you can see how this might apply in similar situations. I think the Raven would do this too as it uses a scripted reload, not a burst fire.
If the chance to hit a target is low and the projectile travel time long (especially since slow-travelling projectiles are often less accurate vs moving targets) you want to overkill it significantly.
Im summary, as a 'default behaviour', it might not be the best idea. I suppose modders can always ignoreOverkill on the things that might be badly effected by this, but even say, a stumpy trying to hit a jeffy might be effected by this.
If a larger proportion or majority of shots are missing their targets, you might get the weapon doing a stop-start fire, shooting at an enemy, ignoring it, shooting again when the shot is missed, ignoring it etc.
Take for example a tremor trying to hit a mex. It will shoot one shot (enough to kill the mex), stop, shoot another when it misses, etc. Of course you'd want to make a tremor attack ground usually anyway, but you can see how this might apply in similar situations. I think the Raven would do this too as it uses a scripted reload, not a burst fire.
If the chance to hit a target is low and the projectile travel time long (especially since slow-travelling projectiles are often less accurate vs moving targets) you want to overkill it significantly.
Im summary, as a 'default behaviour', it might not be the best idea. I suppose modders can always ignoreOverkill on the things that might be badly effected by this, but even say, a stumpy trying to hit a jeffy might be effected by this.
- Mr.Frumious
- Posts: 139
- Joined: 06 Jul 2006, 17:47
Don't like it. This could cause even greater confusion in targetting behaviour. For example, consider artillery units - let's say we have a fast-attack unit. First, the artillery fires at it. While the arty is airborne, it is entering firing range of main defenses. The defenses don't fire, because they think the arty is going to destroy it. So, in TA terms, your HLT gets pwned by a Gator that happened to dodge some Guardian fire, because the HLT was waiting for the shot to hit.
I'd rather just see a "target-delay" variable on units, and a little randomness applied to targetting selection. That is, after a unit is sighted, it waits X delay before selecting a target. Once that delay expires, it reviews all the units in the viscinity - there may be many. It then selects the best target - but thanks to the randomness, if there are many units that are in with a similar value in the calculation for the award of "best target", it picks one of those at random.
And then it opens fire.
I'd rather just see a "target-delay" variable on units, and a little randomness applied to targetting selection. That is, after a unit is sighted, it waits X delay before selecting a target. Once that delay expires, it reviews all the units in the viscinity - there may be many. It then selects the best target - but thanks to the randomness, if there are many units that are in with a similar value in the calculation for the award of "best target", it picks one of those at random.
And then it opens fire.
Of course you shouldn't take ballistic or inaccurate weapons into account.
I'd make the killspeed a factor. If a unit needs less than, say, 5 seconds to kill an enemy unit it shouldn't receive help if there are other targets to spread out/or no help at all (to prevent wasting ammo for example). However if the enemy unit can kill yours faster than that, it should get all the help available.
I'd make the killspeed a factor. If a unit needs less than, say, 5 seconds to kill an enemy unit it shouldn't receive help if there are other targets to spread out/or no help at all (to prevent wasting ammo for example). However if the enemy unit can kill yours faster than that, it should get all the help available.
This cannot ever work very well, though, because it ignores the percentage of shots that miss, and does not take into account various forms of regeneration (shields, let alone the Knight from NB, or stuff that can do that in PURE).
I mean, there's no one, master formula that says that X weapon will hit Y times, even- that's dependent on a huge variety of factors, starting with relative vectors and velocities of the units. So, any calculation of "overkill" is going to be a very rough estimate, at best- and wholly inadequate, at worst.
Instead of wasting time pursuing something that's not really practical, KDR, what we need instead is a COB-called function that requires a Unit to pick another target, or wait, based on some condition (probably a randomizer, but with other COB callouts now available, and LUA, it could conceivably be more complex, and do detailed targeting behaviors).
That's a much better solution- if you have 1 plane attacking, and 10 missile launchers, you want all 10 to attack. If you have 1 attacking, and 5 on a follow-on, you'd like at least a few (determined by the game designer, when coding the COB) to fire, but some of the others might have a longer time-delay before they would be allowed to finish and fire.
Heck... I'll try just doing this with current COB code, and see what transpires. I have some minor issues of balance with this in PURE, and it'd be interesting to see what happens if I introduce a 0-3 second pause before AimWeapon code can run the animations...
I suspect it'll work OK, and it'll achieve the desired result. Basically though, I think what you're trying to do is probably not very practical as a general solution.
I mean, there's no one, master formula that says that X weapon will hit Y times, even- that's dependent on a huge variety of factors, starting with relative vectors and velocities of the units. So, any calculation of "overkill" is going to be a very rough estimate, at best- and wholly inadequate, at worst.
Instead of wasting time pursuing something that's not really practical, KDR, what we need instead is a COB-called function that requires a Unit to pick another target, or wait, based on some condition (probably a randomizer, but with other COB callouts now available, and LUA, it could conceivably be more complex, and do detailed targeting behaviors).
That's a much better solution- if you have 1 plane attacking, and 10 missile launchers, you want all 10 to attack. If you have 1 attacking, and 5 on a follow-on, you'd like at least a few (determined by the game designer, when coding the COB) to fire, but some of the others might have a longer time-delay before they would be allowed to finish and fire.
Heck... I'll try just doing this with current COB code, and see what transpires. I have some minor issues of balance with this in PURE, and it'd be interesting to see what happens if I introduce a 0-3 second pause before AimWeapon code can run the animations...
I suspect it'll work OK, and it'll achieve the desired result. Basically though, I think what you're trying to do is probably not very practical as a general solution.
Looks like we now have just that. BlockShotX() function was added in one of the recent commits, and it does just that (makes a unit choose another target). I haven't used it yet though, so I'm not sure if there are other effects to it.Argh wrote:...what we need instead is a COB-called function that requires a Unit to pick another target