Modern Warfare Mod 3 brings World in Conflict from the Cold War into the Modern Age. It also ups the ante on realism and authenticity in every role – Infantry, Armor, Support and Air, while trying our best to keep everything relatively balanced for fun and interesting gameplay.
A frequently asked question is how to compensate your gun's aiming point based upon your target's movement (leading your target), so that your bullet will hit your target instead of ending up in a miss. We'll go over a number of target leading strategies using WiC's python ShooterBase() module to show you some of the methods we use.
Posted by blahdy on Jan 2nd, 2011
Intermediate Server Side Coding.
This tutorial assumes you have some basic working knowledge of python language, basic understanding of modding in World in Conflict and some understanding of basic linear algebra (high school level).
The most basic way to lead a moving target is very simple.
Our bullet is not a laser -- it takes time for it to reach the target. So since it takes some amount of time to reach the target, we need to wait that much amount of time before firing. Calculating the amount of time our bullet will take to reach the target can be done by using basic physics law of t = d / v, where time = distance to travel / bullet speed or velocity. The distance to travel is the length of the vector between you and the target.
Once you solve the time, you just need to apply this time against the target's velocity vector to get its predicted world-relative vector position after the amount of your specified time has elapsed. Thankfully, ShooterBase() python module provides you a neat function called GetPredictedTargetPosition( aTimeToCalculate ). You can use this function to plug in your calculated time value to receive the world-relative vector position of the target after your time has elapased. That is where you want to aim your gun.
This leading method is used by all of WiC's standard Straight Shooter projectiles -- so every unit employing straight shooter in vanilla, unmodded WiC uses this method to lead.
Very simple, fast and easy to understand.
The problem with this method is that it does not take into account for the fact that the target is *moving*. We are using the distance between our position and the target's position. But this distance is changing every frame because the target is moving. You will not be able to intercept any target that moves at moderate to fast speed with this method.
Examples in Use:
All vanilla WiC straight shooters use this method. Most tanks and ground units in MW Mod also use this method. A good side effect of this simple method is that from an RTS game standpoint, it creates a sense of realism in that even with good fire control system, not every shot is going to make a hit against a moving target. But against most slow targets, you will hit it ok as long as your bullet's speed is fast enough to contact the target's hitbox in time.
This method is very commonly used by MW Mod. The great benefit of this method is that it is relatively simple to implement and yet impressively accurate in most situations.
Quadratic equations are also commonly used in computing trajectories of projectiles in motion. You'll also find it in use by several games when producing firing solutions for AI bots against moving character target or unit in the game.
Instead of digging into the math and boring you with details, let's just get straight to the code. You can learn more about the math aspect by searching for Quadratic Equation on Google and Wikipedia.
The following is snippet of PredictorFCS python code used by MW Mod when generating quadratic fire solutions:
Remember the time of collision we had solved for in the above "simplest way to lead your target" method by dividing distance by bullet speed? This function also calculates for that time and returns the value of time. If the target cannot be hit, then you have no fire solution and the function will return -1 instead. Simply plug in the number returned by the above function into WiC ShooterBase's GetPredictedTargetPosition( time ) to get world position on where you need to aim your gun to hit your target.
The benefit of this method is that it is very accurate, even when the distance between you and the target is changing by every frame. It is also computationally very cheap so you can conduct this calculation on massive number of targets simultaneously at once to generate quick fire solutions for multiple targets.
Quadratic equation is commonly used in MW Mod on all major fire control applications as well as radar systems used to track enemy units. The reason behind its prevalent use in the mod is simply because it is computationally cheap and easy to implement for various applications, while providing acceptably accurate target leads.
The TWS function builds list of up to 100 targets and updates the list every 0.1 second with new predicted moving positions. Because of the TWS principle, the radar script needs to know where the target is predicted to move to, in order to figure out where to look next in the sky for its next radar sweep. This makes sure that the radar constantly maintains tracking of its target.
This also means that the target aircraft would not receive a radar lock or missile launch warning, simply because the radar unit is "sweeping" the sky in search mode, and using quadratic equation to figure out where to look in the sky again for the next search sweep, without significantly increasing the number of radar scans issued against the aircraft (which would trigger missile launch/SAM lock warnings).
When you are targeting fast moving target that is traveling almost as fast as you are, such as ballistic missiles, you start to run into issue of resolution. The data you receive and perceive about your target, such as target's moving velocity, direction, pitch, yaw, etc is changing rapidly every frame. And the data-set you are using to predict target's movement point is already too late, especially when target has a very small cross section and hitbox, where even a smallest inaccuracy would result in a total miss.
This becomes a bit of challenge when you are trying to shoot a ballistic missile with another missile, with perfect one-shot accuracy. It will be unacceptable for the intercepting missile to miss then fly around for 2nd try like a typical game homing shooter, because by then, ballistic missile will hit its mark.
To accurately intercept fast moving and maneuvering targets with a single sniper hit, we convert vectors into polar coordinates and solve for angles in a triangle using trigonometric law of sines. We'll just get straight to the code:
The position of target, the predicted point of interception and our current position all make up to form up a triangle. The law of sines can be used to compute the polar angles required to point ourselves to intercept the moving target. The sides of triangle are made up of speed of our missile and speed of our target. They are not actual lengths, but that doesn't matter -- what matters is the ratio of the sides. This technique is basically a triangulation.
The above code returns the polar angles required for us to make our shot against the target, but unfortunately, this actually does not work in practice. As our missile projectile is flying to intercept the target, the target is also flying as fast as we are. This creates a situation where the angles of the aforementioned triangle are changing very rapidly every frame -- especially when our missile and the target are aiming to collide head-on. The angle closure rate is too high.
To mitigate the high angle closing rate, we would need to implement some form of feedback loop to predict the rate of angle closure and simulate interception ahead of time. A rather simpler method we ended up trying is to use the fact that two objects are on a collision course when their direct line of sight (LOS) does not change direction. We measure the rate at which LOS angle is changing every frame (LOS rate) and verify whether we are sufficiently aiming our missile velocity vector proportional to the LOS rate, and in the same direction. This in effect is a form of Proportional Navigation.
The third option we use to further mitigate high angle closures against high speed targets is to spawn and maneuver the interceptor so that it is perpendicularly oriented toward the target, usually on top of it due to ballistic trajectory of SAM. By hitting the target from perpendicular axis, the angle closure rate is substantially reduced, compared to a high speed head-on collision.
PAC-3 missiles in the mod use trigonometric firing solution combined with proportional navigation to make their kills during end-game shots (terminal guidance).
You can see the trigonometric law of sines and proportional navigation pricinples in action in the video below. Notice how the intercepts look like they are forming up a triangle.