Skip to content

5 November 2024 - Terrain (core) is done!

<<< Previous Post Next Post >>>


  It has been just over a month since my last post but I have been busy.

  One of the things I have been doing is another huge change to how voxels work in lieu of data cost, memory efficiency, and disk usage. Put simply: I scrapped the game's terrain system and then made it again from scratch, using the knowledge from my previous attempt.

  This does impose some limits (which I have actually edited into the previous blog entries, so a bit of time travel witchery going on), but for good reason.

"Core"?

  The terrain system has two parts:

  • The core is the system that makes it work, the technique for how to build a world and store its data.
  • The generator is the system that actually builds worlds, generating landscapes procedurally based on a set of rules.

  The core is the part that I just got done, because without a working core, the generator fundamentally cannot exist.

So what changed?

  • Memory cost of terrain went down a lot (8GB for large world down to about 1.5GB)
    • Most of the memory cost was from me rather eagerly throwing huge values into the voxel structure. Single bytes make a difference.
    • This value is also distorted because I had a memory leak at one point with geometry generation.
  • Terrain now generates on workgroups.
    • Terrain was already multithreaded - and this is where a lot of the difficulty came from - but now it's also designed to generate in discrete dispatched pieces of work.
    • Fellow game devs might see similarity in this terminology, and yes, it does indeed mean that generation could be delegated to the GPU via compute shaders! An analogue class exists on the CPU that uses the processor's multiple threads to crudely emulate a compute shader, but this class simply provides the means to an end.1
  • Terrain geometry also now generates on another thread.
  • Interaction with the engine is kept to a minimum, and calls back to the main thread now only occur at the end of a chunk's generation to tell Godot to add the node to the scene tree, which is not a thread-safe operation.
  • The file format for terrain was optimized into regions.
    • This prevents widespread world corruption by limiting the size of corrupted data to 16x16x16 chunk regions.
    • A region file can be kept open by the system for a while, to optimize IO.

What happens now?

  Now, I am going to redesign the entity system. It was never actually working to begin with, I just set up its framework to get a feel for what I wanted, and to figure out how I might make it work (and I needed it to spawn in the player). Now that I have the world working, I can focus on adding things to that world.


  1. Despite the ability to generate on the GPU, and originally implementing it this way, there were some flaws with this. The first is that anyone who wanted to run on a dedicated server (if I do multiplayer) would find that they are unable to, for lack of a GPU. The second is that through clever use of SIMD instructions and fast noise algorithms (primarily based on fBm), I have actually managed to make the CPU generator work almost as fast as the GPU generator. The third is that getting structures and premade objects to the GPU would have been a nightmare to standardize and so I kind of dodged a bullet there.