I finally stumbled upon an area of the code for the game that would benefit greatly from a bit of proper planning. As previously discussed, the world is made up of clusters, each of which is stored in its own file. As not previously discussed, my original plan was to unceremoniously dump the files into a single directory.
For most worlds this poorly planned approach would cover you pretty well. For example, a world that was as tall as Minecraft’s world is (256 blocks), and covers 4096 blocks in each direction on the surface (a pretty big world actually), we’re only talking about 2048 cluster files. Most file systems can handle that without any issues at all. What happens when a group of avid explorer types start wandering around with the goal of expanding the known world?
What happens if over the span of weeks they explore the world to 16,384 or so in all 4 directions (32,768 blocks across), and they dig holes and build towers that result in a world that is twice as tall as in Minecraft. Now we are talking about 262,144 files in the world’s data directory. For most modern file systems, this won’t result in anything blowing up, but the performance will typically drop off pretty badly. That’s not really a good thing for a game designed from the ground up to make pretty heavy use of the storage system.
A simple pattern of X_Y_Z.qkc (QubeKwest Cluster) will work nicely, but how do I arrange those files so that the 79,228,162,514,264,337,593,543,950,336 possible cluster files don’t melt file systems way before you get to that number? What I came up with is using the nibbles of X, Y, and Z to build a directory structure.
A random file name holding a cluster might be:
01234567_89abcdef_f0e1d2c3.qkc
If I take each of the nibbles in turn from the X, Y and Z coordinates and combined them, I would end up with the following 3 character values: 08f, 190, 2ae, 3b1, 4cd, 5d2, 6ec, and 7f3. Next, if I ignore the last group of characters, I would end up with 7 values. When I string them all together as a 7 layer nested directory, what I get is:
08f/190/2ae/3b1/4cd/5d2/6ec
Because each of those values is 12 bits, that means I now have a directory structure where no single directory will ever have more than 4096 files or directories in it. This should make everyone’s file system happy and prevent slow down. I decided that even though the file name only actually needs to have the last nibbles in the name, I would use the whole coordinate anyway. This means that our sample cluster file now has the complete path of:
worlds/WORLDNAME/data/08f/190/2ae/3b1/4cd/5d2/6ec/01234567_89abcdef_f0e1d2c3.qkc
In case that doesn’t make it clear, each world has the same directory structure. In the example above, the name of the world the user created is WORLDNAME. I’ll need a way to ensure worlds have names that aren’t too long, and don’t include any characters that are invalid as directory names, but that’s a problem for a different day.