Eve Online pathfinder
Sunday, November 30th, 2008As I wanted to kill some time, I helped BombStrike with his project for Eve Online, a “massive multiplayer online roleplaying space game”.
The part I helped with is about being able to find a “route” from one point to another.
My first attempt was just for fun, a stored procedure for MySQL which did the lookup with the help of 3 temporary tables. This worked quite well, but had serious troubles resolving really long paths (avg. of 7 seconds for a 24 hops search).
So, I finally decided to create a dedicated database format for Eve Online, which would be optimized for lookups.
With this new database, a 95 hops lookup takes an average of 2.25ms. This is fairly acceptable, I’d say.
For those who are interested, the generated database (it took ~3 hours to build it), and some data files are available for download. You can also download the initial MySQL database dump.
The index file is fairly simple, it contains only solar system ids and locations in the main file (4 bytes for little endian solar system id, and 4 bytes for location in main file).
The main data file is a bit more complex. For each solar system we have:
- Solar System ID (4 bytes)
- Solar System Security (4 bytes int, explained soon)
- Number of known solar system when adding this one
- Solar system name length (1 byte)
- Solar system name (variable length)
- Solar system links to other solar systems (size of 9*number of known solar system when adding this one). This list contains:
- Next hop to reach this solar system (4 bytes)
- Number of hops remaining to reach it (1 byte)
- Security level of this route (4 bytes, explained soon)
The security level in Eve Online is a float between -1 and 1. Storing float or double values is a pain, so I converted them to integer with a simple operation: int_value = (float_value + 1) *1000000000.
This way the int_value will be between 0 and 2000000000, and (almost) efficiently use space available on signed 32bits integers.
Creation of the initial file is also pretty simple.
First, we create the various solar systems, based on data from the database.
Next, we insert what we call “level 1″ links (basically, those are all the direct links).
Finally, we enter a for loop starting a 2 and finishing at 255 which will ask to populate links. There the way this is done is easy.
For each solar systems:
- We collect all links which takes one less hop than the current value of the loop (for example for the third iteration, we take all “2 hops” links)
- We “advertise” them to solar systems directly connected to our solar system, saying the “next hop” is us (for example this would lead a solar system directly connected to the current one adding the current solar system as a “3 hops” target for the advertised solar system).
Explaining all that is not easy, I hope I didn’t get anyone lost here.
Anyway have fun with this piece of (maybe) useful code!