First-Person Shooters and Geodesic Ballistics

Dare to ponder..

Have you ever noticed how nearly all first-person shooters assume that the earth is made up of interchangeable flat tiles?

This is in part due to the obvious simplicity of doing your collision calculations in linear space instead of dealing with all this curvature bullshit.

Except One Thing..

Many of these games simulate bullet drop, giving projectiles a parabolic trajectory.

So to open this discussion up, the thesis of this post is as follows:

We should have no reason to fear computing collisions with respect to the curved space as we already do it, and it does not introduce any unmanageable complexities.

I am being general on purpose.  Obviously there are exceptions, but to those exceptions my response is an engineer needs to be conscientious of an application’s principle problems and their solutions.  Understanding how to navigate those waters with pragmatism is a topic of protracted discussion and is outside the scope of this post.

But guess what’s inside the scope of this post?  Lots of physics and application-level geometry!

I know what you’re thinking.  “Finally.”

Brief Physics Aside:

Okay so what are we talking about here?

Well lets say you wanted to make a game that used the curvature of the earth as part of its simulation.  So to answer your question, we are talking about geodesics.

According to wiki, Geodesics is a generalization of the notion of a “straight line” to “curved spaces“.

The term “geodesic” comes from geodesy, the science of measuring the size and shape of Earth; in the original sense, a geodesic was the shortest route between two points on the Earth’s surface, namely, a segment of a great circle.

A related concept is the idea of Great-Circle Distance.  Historically, this has been around and been super useful for a long time.  Useful for things like, successfully navigating and sailing a boat between points that exist along the surface of an ellipsoid planet.  Or other things, like figuring out where an enemy missile is going to be at a given time so you can figure out how to defend yourself against it.  Its been around, and has been researched pretty thoroughly.  Here’s a guide from the ’70’s on solving inverse-geodesics by hand.

The point is, these kinds of computations are not a problem for a computer.

They’re not even hard for a human being to do once you know what the hell you are trying to achieve.

Abstracted properly, you could wrap a world based around a linear-space model with curved-space model and not incur any kind of irreconcilable overhead, be computational or representational or whatever.

Lets Set a Quick Hypothetical Stage

Alright lets imagine hurling two objects in the exact same direction with the exact same amount of force, resulting in two trajectories that share the same orientation (with respect, lets say, the center of the earth) at the moment of release.

Some minor notes on language and context:
  • Even though we often refer to this simulated space as a world, it would be be more precise to say that we are talking about the composition and nature of the simulated universe.
  • We define (and implement) this in the scope of the entire universe at-large, specifying the universal constants and processes that compose the universe and all things contained within, but all of these rules work exactly how you would expect if we zoom all the way in and examine the way physics works on an individual planet.

The Non-Relativistic Model:

Non-Relativistic Model
The Non-Relativistic Model. Here’s what we think is happening, based on what we see and how we rationalize the world around us

The Relativistic Model:

The Relativistic Model
The Relativistic Model. And now here’s what is actually happening as described by (and supported by) Einstein, the theory of General Relativity, and pretty much all of quantum physics.


Which of these seems more intuitive and, which of these seems like its trying to shatter your frail perception of reality?

Well now that you have shattered reality, its time to begin our work.

There are many reasons why this may be useful, some too subtle to explain here in any depth while others are too arcane and require further discussion to even approach, but there is a whole separate discussion brewing with regards to what this model could be used for.

We will have to save that for discussion later.

Alright, Focus.

Fine.  I will assume that this may be useful to someone, somewhere.

So then, tell me.  First about the “how we do?”, and then maybe we talk about “why we do?”.  Please.

Sweet. Then let’s get into it, and by the way your curious ant polite demeanor has been noted and will be duly commended.

Alright, here’s the recipe:

Enjoy this my friends, for it is straight off the dome-piece.

Recipe for Geodesic Ballistics & Collisions:

1 – Guns & Bullet Physics: A library for describing and calculating the specific physics  for using X gun with Y cartridge under set of circumstances Z, where Z is some array of parameters that we care about in order to determine the “bullet stuff”.  Many exist, but here’s a pretty great one.

2 – Geodesics & Collision:  A library for converting linear space and coordinates into geodesic space (and coordinates).  My favorite is GeoPy.  The way you choose to implement this depends on which features you want to simulate (or even care about) in your application– the 3d world.

Here are some possible examples of how to apply this.

1 – With Linear Art and 3D Assets

If we want to apply this to a game that assumes linear space-time (pretty much all of them), then we will need a way to convert the necessary physical properties so that they can be used with our ballistic physics engine and our geodesic collision engine.

  • In practice this could mean converting all coordinates values (and any associated vectors) into geodesic space.
  • We could start with our regular (linear-space) values and then use solve for the inverse-geodesic, which means we need to figure out how this is supposed to work if it had happened in curved-space. 
  • There are a bunch of ways to do this, most of them are specific to the constraints of the problem you are trying to solve.

2 – With Geodesic Art and 3D Assets

If we already have assets that were designed to be used in curved space, then we don’t even need to worry about converting we can just compute collisions using the native geodesic values.  The trade-offs are that, in order to produce compatible 3d assets:

  • You would need to establish a set of rules to follow during production in order for your team of artists to be able to produce world assets from scratch that aren’t based on the real world, but that still depict accurate geodesics.
  • Alternatively, you could produce linear-space world tiles, and then computationally transform those 3d assets into the geodesic world equivalents.  This is a little tougher to do and may require some supervision since artifacts may be produced during that transformation.
  • The obvious benefit is the potential agility and production power that comes along with being able to script elements of your content-creation pipeline.
  • For example if we designed the world as sphere and then sliced it up into tiles, so that the world is not a single huge object, but a collection of a component objects– which is essential for protecting application performance.


It would take too much time to build an entire example here, but here’s some code chunks for different parts of this recipe.

Solving for Euclidean (Straight Line) Distance

We have two points in our 3-dimensional space, point A and point B.

# our coordinate points
a = (1, 2, 3) # equal to ax,ay,az
b = (4, 5, 6) # equal to bx,by,bz

Using Euclid’s Formula, which is just an extension of the Pythagorean Theorem, we probably want to do something like this.  Right?

dist = sqrt((a-xb)^2 + (ya-yb)^2 + (za-zb)^2)

Well, yes.  But actually, no.  There’s a ton of ways to compute this, and with linear algebra this becomes even more simple to evaluate.

In practice we are just going to do this:

# lets get euclidean distance
from scipy.spatial import distance
a = (1, 2, 3) # 1-dim vector equal to ax,ay,az
b = (4, 5, 6) # vector equal to bx,by,bz

dst = distance.euclidean(a, b) # and now solve it


Solving for Geodesic (Curved Line) Distance

Same thing as before, except we will ignore altitudes for now.

from geopy.distance import geodesic
p1 = (31.8300167,35.0662833) # (lat, lon)
p2 = (31.8300000,35.0708167) # (lat, lon)
distance = geodesic(p1, p2)  #  solve the geodesic
print distance.miles         #  report the value


Actually we aren’t ignoring altitude, but we don’t need to specify the Z-components of our coordinates explicitly since we can figure that out automatically using the X and Y coordinates and topological map data.  Fortunately, our library handles this for us.

Additional Reading:

Curvature and Space

Final Thoughts

Since a geodesic collision model more closely resembles the way in which space-time works in the actual universe, it should not be all that surprising that correctly applying a geodesic model rewards the application with an objective increase in the overall realism of our simulation; simply put it pays off having a more robust understanding of how objects move and how/when they will collide.

Precision of this order is not very noticeable over short distances (say 5-100 feet) , but over longer distances (ie, over 5000 feet) geodesic models of space become an absolute necessity for any application that needs to work well in the real-world.  Additionally, this change is MUCH more noticeable when you are computing areas or volumes instead of just distances.

And if you think I am wrong here, come on into discord and tell me that I am wrong, but be prepared for me to explain to you that, even though I may not be right– you are definitely still capable of being wrong.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>