Larger Coordinates - Corwin McKnight

Larger Coordinates

Any game that has a large world needs to have some way of dealing with the amount of distance between objects. For smaller games, a float (32-bit precision) is just fine, but larger games may need a double (64-bit precision) for the amount of distance. Using a double is sometimes impractical, due to slow math performance and 8 bytes of usage (which can ruin cachability of a structure if there needs to be a lot.)

Unfortunately, IEE754 floating point numbers are the best of both worlds when it comes to precision and distance, as a fixed-point solution would require too many bits (64+). This means that a solution for extending representable world distances requires extra storage. Limiting ourselvews to 64-bits, there needs to a solution that keeps performant code, evens out the floating point inaccuricies / loss of precision, and extends the number range using around 64-bits.

The game I'm currently working on has positions on the scale of our galaxy, and for simulation reasons needs the precision to be relatively constant. This is more then a float/fixed system can handle, and a double with as many elements as I would have would be ludicrous.

Many games, such as Minecraft, use something called a chunk to take care of this. However, their specific implementation only works with integers, and still has precision issues.

My solution

My solution is to use a pair of numbers, called the chunk and the offset.

A chunk is a chunkSize block of offset coordinates. Once offset exceeds chunkSize, offset is wrapped around offset = offset - chunkSize and chunk increases by one.

When subtracting, if offset goes below zero, the opposite happens: chunk is subtracted by one and offset = offset + chunkSize.

Expanding this to multiple axis just involves a chunkX, chunkY, offsetX, and offsetY, and simply doing the vector math per term.

Emergent properties of this system

There are several useful features of a system like this that I have documented:

Precision

The precision of a coordinate represented by this system is never higher then what is set for the maximum chunkSize.

In my game, I set a small chunkSize at 1024, which means that the values are never larger then 2^(10-23) (0.000122070312).

Representable numbers

The largest representable number is chunkSize + (INT_MAX * chunkSize), which is beyond the maximum representable number of an 32-bit integer. If longs are used instead of integers, the representable space would be much larger.

Locality

This scheme allows for quick locality determination, without the use of a division or modulo operation. Local is defined to be within 1 chunk (within a 3x3 grid of chunks in a 2D system).

Simply compare whether for chunk values A and B: abs(A - B) <= 1

This locality means that at maximum, actual positions are within 2 * chunkSize of eacother.

No negative offsets

Since an offset wraps around to chunkSize when going below zero, negative offsets never occur.

Conclusion

For a game like I'm making, this coordinate system is really useful. As the world is large, vast, and distant, it's nice to have a coordinate system that enables that with some useful features.

© Corwin McKnight 2023