2
\$\begingroup\$

I'm working on a procedurally generated game set in outer space. As in the real world, the game universe will be pretty much 99% empty, with planets/stars/solar systems etc... being very far apart.

For example at the beginning of the game, you will pretty much be stuck in the solar system you spawn in, as even flying from planet to planet will take a very long time. Flying from one solar system to another will be theoretically possible, however it would take days of IRL time without obtaining the in-game equivalent of a warp-drive.

I realize with all the thousands of planets/stars etc... they can't all be updated 60 times per second, and I can deal with that. Let me describe my problem.

Okay, so lets say 1 meter is 16 pixels.

Earth diameter      =  12,756,000 meters
Earth diameter      = 204,096,000 pixels
Earth circumference = 640,861,440 pixels

Okay, that's... still arguably manageable. Obviously there wouldn't be an earth.png, it could be procedurally rendered. But it gets worse:

Distance from earth to sun =   149,600,000,000 meters
Distance from earth to sun = 2,393,600,000,000 pixels

So if we define earth as our arbitrary origin, and we travel to the sun in our ship:

int main()
{
    //        Distance to sun:
    //        2393600000000
    float X = 2383695718491;
    std::cout << X << "\n";

    X += 6;
    std::cout << X << "\n";
}

This outputs:

2.3837e+012
2.3837e+012

That's the correct amount of zeroes, but now over 4 million pixels of precision is lost, and that's a big deal. And of course, the distance to the sun is tiny compared to the distance to the nearest star.

For the purpose of the game universe, I will decrease the distances just to make travel a little less boring, but this is still clearly impossible by only using x and y variables.

How should I handle these huge distances?

UPDATE: Just to clarify, I realize that earth is unimaginably huge and there's no way I'd be able to fill it with meaningful content. GTA V's map is about 100 square miles, and that's less than .00000005% percent of earth's surface. So my planets will definitely be significantly smaller than this, however the issue with huge distances remains.

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

The best way to get around these types of limitations is to move the world, rather than move the player and camera.

Strict Method

Keep your camera and player at (0,0) if you're using 2D or (0,0,0) is you're using 3D.

When you calculate the input to move your player, instead of moving them, move all the objects in the environment. When the objects get some appreciable distance away from the player, disable them.

You will need to have a system implemented that keeps track of the distance so you know when to activate an object and set its position/orientation in the world.

Hybrid Method

Similar to the above method, but instead of moving the environment and never moving the player. You move the player around the environment as normal, but after a certain distance from the origin you move everything based on an offset.

You would calculate this offset by the distance of the player from the origin, and then move all objects by this offset (so all relative distances stay the same). You activate/deactivate objects during this time as needed, similar to strict method.

Other Ways

If you're doing this by scratch and not forced by an API/Engine to use floats for keeping track of translation data, you could opt for a data type with more precision such as double or decimal (note that using the decimal datatype is considerably slower than float/double).

\$\endgroup\$
  • \$\begingroup\$ I like these ideas. My main concern would be: You will need to have a system implemented that keeps track of the distance so you know when to activate an object. Wouldn't I run into the same problem of losing precision? \$\endgroup\$ – Entity Nov 1 '14 at 18:52
  • 1
    \$\begingroup\$ Yes and no. Yes if you keep track of the distance as a native datatype (float/double/etc). No if you keep track of distances per some spatial container. You could break your space into very large chunks that point to 8 other chunks (assuming 2D here). When you get within a certain distance of the chunks boundary load in the nearby chunks and their objects. This way objects are always within the appropriate precision level, but you could have billions of chunks worth of objects. \$\endgroup\$ – steve Nov 1 '14 at 19:39
1
\$\begingroup\$

Kerbal Space Program used to have the same issue, and called it the Kraken.

They solved by moving the bubble around the player it has a radius of 2.5 kilometers outside of which all objects end up "on rails" where the orbit is fixed and large jumps ahead are easily calculated.

That can be done using the patched conics orbit model. Essentially it means that all objects are only in the sphere of influence of a single celestial body which reduces the problem to the solved 2 body problem.

\$\endgroup\$
  • \$\begingroup\$ What is "the a bubble"? \$\endgroup\$ – Entity Nov 1 '14 at 19:16
  • \$\begingroup\$ @TheAdamGaskins a typo \$\endgroup\$ – ratchet freak Nov 1 '14 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.