Basic Dogfight Mode (1): Basic Yaw/Pitch Adjustments

The simplest way you can do DFM is... honestly not that difficult, as long as you know some basic vector math.

Previous Post:
Basic Dogfight Mode (0): Overview - Memories of Melon Pan

In Assault Horizon, there was that circle in your HUD, and if your chase target got outside that circle, your ship would yaw and pitch to put your target back in that circle. Conceptually, you could extend a cylinder from your ship and check if your target is inside that cylinder... but I went for something a little simpler - just a cone.

We've got two thresholds here, the first of which is the near threshold Tn. If the angle to your target is greater than this threshold, then you can slightly nudge your ship around so that it turns towards your chase target.

However, if that angle becomes too large, then your ship will lose the chase target and disengage DFM. This is the far threshold, Tf, and if the angle to your target exceeds this threshold, instead of bumping your flight path, you can just clear the chase target variable and disengage DFM that way.

So now, we have to figure out the direction to the chase target relative to our chasing ship, but it's not enough to subtract the positions of each ship from each other. You'll just get the direction from one to the other in world space, or you'll learn that if your ship moved X units horizontally and Y units vertically, you'd be where the chase target is.

That's not what we want - if the ship we're after is dead ahead, we want to know to move (0, 0) from our current heading, and not (25, 25, 25) from our position in world space. We can start with finding the direction in world space, but to convert it to object space, we'll need a transformation.

dw = normalize(Xt - Xs)
d = dw * transpose(Rs)


α = acos(dot(f, d))


For the variables:

  • dw, direction vector in world space
  • Xt, position of the target
  • Xs, position of your ship
  • d, direction vector relative to your ship in object space
  • Rs, rotation matrix of your ship
  • α, the angle between your heading and the direction to target
  • f, the forward vector (0, 0, -1)



Where normalize(v) is the vector v in normalized form, and
where transpose(m) is the transpose of the matrix m.

You're dealing with a directional vector dw here, which is the direction from your ship to your target... but the catch is that your ship can be rotated to point in some weird direction. But if we multiply all these things by the transpose of your ship's rotation matrix, what happens to the direction to your target in world space or your ship's current heading? The former is swiveled around to truly be relative to your ship's point of view. The latter is swiveled around to point straight forward in world space, which is why we can use the forward vector to find α.

Trust me when I say this is as complex as it gets. Don't worry, I'll get to more interesting stuff when I get to the other things I tried, but for now this is Hello World for DFM.

From here, things can go the way you think they'd go. If the angle to your target is between the two thresholds, you need to take over the player's input with some automatic yaw and pitch inputs to face your ship towards your target. If your target is off to the left, then yaw left. If it's below you, then pitch down to meet it.

If α < Tn, then let player input control ship.
If Tn <= α < Tf, then yaw and pitch ship towards the chase target.
If α >= Tf, then disengage DFM.


For the variables:

  • α, the angle between your heading and the direction to target
  • Tn, the near angular threshold
  • Tf, the far angular threshold

... Which means we're now we're ready to yaw and pitch our ship to keep it on our target.

If d.x < 0, then yaw left some arbitrary amount N.
If d.x > 0, then yaw right some arbitrary amount N.
If d.y < 0, then pitch down some arbitrary amount N.
If d.y > 0, then pitch up some arbitrary amount N.


For the variables:

  • d, the direction to your target as a unit vector

Well how's that for disappointing? At it's most basic, you can just choose some number to yaw and pitch by, and that should get you by. In practice however, it might look a little jerky, since you either yaw/pitch by N or nothing at all. There's a few refinements you can make, but I'll save that for a later post.

You might think I'm done explaining this very basic way of doing DFM, but I haven't mentioned speed control yet. You have to maintain a certain distance from your target when you're in DFM, right? Well...

Let's keep things basic for now. Sorry, but that means they aren't getting any more exciting. Let's define a distance equilibrium De - this is the ideal distance we want to stay at. We can define a function that calculates what our speed should be based on how far we are from that equilibrium distance. If we want to maintain a distance of 100, speed up if we're further away than that distance, and slow down if we're closer. Your speed function can be simple or complex, but just to illustrate...

S = Sc + ((D - De) / w)


For the variables:

  • S, final calculated speed
  • Sc, cruising speed
  • D, distance to the chase target
  • De, distance equilibrium
  • w, an arbitrary weight

If you really want to keep things simple, this is how your speed function could look - speed gain or loss is linearly proportional to the distance between you and your target.

Choose whatever you want for Sc, De and w, just get numbers that make things look... not too bad. And when you're done calculating, you should probably limit your speed to some range, not letting it dip below some minimum speed, or fly over some maximum speed.

And the final thing to do - if your target gets too far from you, disengage DFM since you've technically lost your target. I'm mentioning it here just so that I say everything that's involved, but I really don't think I need to elaborate more on that.

Not a very exciting way to tail enemy planes, now is it? When I first thought about this, I totally agreed with how plain this was and tried doing something different for my first attempt. I ended up with something pretty wacky and it was an overall bust, but I was able to take what I learned from that ill-fated attempt and adapt it to what I did here, making it a little more intellectually stimulating.

Next Post:
Basic Dogfight Mode (2): Pure Positional Spring Theory - Memories of Melon Pan