0
\$\begingroup\$

I have recently been looking into physics engines and low level computing. At some point id like to make my own engine down the road.

Something I can't seem to find an aswer for is how physics based games with large worlds beat floating point error. I use space engineers as an example because of it's large scale. While also having multiplayer.

I have thought of 2 soultions my self but haven't be able to fully understand the ideas behind them or if they would even work.

  1. Move coordinate system with player so the player is always at 0,0.

  2. I have also noticed fixed point numbers as well but they have much smaller possible ranges.

\$\endgroup\$
1

3 Answers 3

1
\$\begingroup\$

One other option that you haven't mentioned is to use double instead of float for positions and position transforms. This doubles the memory required to store them, but gives you much more precision without adding too much additional code complexity. Unreal Engine 5 has done that, for example.

This also seems to be what Space Engineers has done, although they have done some extra things on top of that because their physics engine doesn't handle doubles. They have a separate local coordinate system for the physics.

\$\endgroup\$
1
  • \$\begingroup\$ Never put much thought into how much better doubles would be \$\endgroup\$
    – TizWarp
    Commented Sep 1 at 1:19
1
\$\begingroup\$

A game only has to simulate real world physics, meaning that if the simulation is somewhat accurate such that a player doesn't notice it or it doesn't really interfere with the enjoyment of the game it doesn't have to be perfect. I have played a lot of KSP (and only minutes of Space Engineers) so I will use KSP as an example of the optimizations that could be taken.

KSP defines four basic states:

  • Stationary on the ground.
  • Moving across the ground.
  • Flying / in the atmosphere
  • In the vacuum of space.

Generally speaking if something is stationary, on the ground and a long distance from the/a player it doesn't require physics processing - it can be assumed that when a player comes back in range the object will still be where it was.

As such it's position can be given in different co-ordinate systems the simplest/most accurate may be a rotating Cartesian (XYZ) coordinate system relative to the center of the planet, i.e the reference frame rotates synchronously with the planet, so all distances can be calculated accurately and no frame to frame adjustment need to be made for any stationary objects.

Typically objects in space around a single body are on an orbit (technically a conic section) as such you can define the curve of the orbit - using something like Keplerian coordinates then calculate the position given the current time since the game started - the inaccuracy will be related to the precision of the Keplerian coordinates themselves.

If an orbiting ship drops into the atmosphere you will need to apply aerodynamic drag to it, hence an approach may be to switch the way that calculations are performed to instead track velocity through the air and height above the ground.

Finally when the ship gets close to the ground you probably need to switch to absolute positions so that you can rendezvous with objects on the ground.

In KSP this final transition appears to happen around 2.4 KM - I am not sure if this is an AABB or just a spherical check. Anyway the point is that KSP does very few calculations for most objects and only really cares about the precision that the player would see/notice.


Finally KSP simplifies universal physics:

  • The sun is stationary.
  • The planets and large moons all orbit on rails - their exact position is always known given the amount of time since the start of the game.
  • Only one large body affects spacecraft (the closest one) be that: the Sun, a planet or a moon.
  • Hence spacecraft orbits are defined relative to that body.
  • All large bodies, except the Sun define a SOI (Sphere of influence) when a spacecraft exceeds this, the body affecting them gravitationally changes to the next outmost body Moon -> Planet -> Sun.

TL;DR - At any given time exact positions of most objects in the universe are irrelevant a rough position is good enough.

Only objects (including the ground) that are very close (2.4 KM in KSP's case) need to be calculated accurately.

\$\endgroup\$
1
\$\begingroup\$

I can't speak for Space Engineers, but this is a problem I have solved in the engine I'm working on.

Doubles would work for all but the most massive scales.

For my engine which goes beyond what doubles would handle well, I've got a hybrid system. I use 64 bit integers (effectively fixed point) on the CPU (gives 64 bits of resolution, rather than the 52-53 bits provided by doubles), and convert some of that to a local system using floats for GPU use (I want to run on mobile, so I can't assume that doubles are available).

Using integers, I have to be careful about what operations I perform because of range issues - for instance, if I want to square a value (say as part of a distance calculation), I have three choices:

  1. use 64 bit x 64 bit -> 128 bit multiplication (which both ARM8 and x86-64 support) then take the top 64 bits of the result,

  2. take the top 32 bits of each value and do a 32 bit x 32 bit -> 64 bit multiplication which is slightly faster but loses a lot of accuracy.

  3. convert them both to double, do the multiplication, then possibly convert back. Less accurate than 1, more accurate than 2, slower than both if I need to convert back, so only really useful if I wanted the result as a float or a double anyway.

I mostly use the first of these options.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .