Sunday, February 1, 2015

Terrain Generation Components

For my terrain generation code, there are many areas of interest -- here were the eight major questions I looked at:
  1. How do you define the size and shape of biomes?
  2. How do you define small, circular points of interest within a biome?
  3. How do you implement long, potentially twisting, linear features?
  4. How do you define (and save) geometry and scale?
  5. How do you define the surface?
  6. What about flora, both large (eg trees) and small (eg grass)?
  7. How do you define what's below the surface?
  8. What about water (and other fluids)?
My first goal was to find a good way to produce biome regions that were fairly large, while allowing some smaller-scale variation within a biome. For example, within a mountainous region, where are the peaks, ridges, and valleys? Will a forest have a pocket of unwooded grass (aka a meadow) within it? Can you place an oasis within the desert? For that, I settled on using a hex grid and subdividing it into a finer hex grid a couple times. Throw in a little noise and it makes for borders not too cubic, not too noisy (eg what you'd get from straight Perlin noise), and easy to subdivide.

So I'm using jittered, adjacent hexes to define the shape of biomes, and the hierarchy to define their size (question #1). The hierarchy also allows me to insert special features here and there (question #2). Right now I'm really only using this to add islands, but the tech is in place and I have an implementation for varying plains although not enough more engine tech to justify this.

But that just gives me the hexes I displayed in the previous post. Converting hexes to voxels requires defining the world surface (question #5), including its geometry (#4) and "scale". Scale is really a gameplay question, not a tech question; on the tech side, normally one cube will be one unit, so there you go.

One question I'm now facing is how to do linear features, such as mountain ridges, canyons, and rivers. I've also got to add grass, flowers, and trees (#6), usually done with billboarded quads for the small stuff and voxels for the larger stuff. Then there's the below-surface stuff (#7), if you plan on letting players dig into the ground -- this includes layers of rock; pools of lava; 'bedrock' or some other way of limiting how deep players dig; dungeons & caves; ore; and who knows what else. Finally, how do you 'do' water (question #8)?

The question I've dodged so far is linear features. This is really bugging me, because the approach I used to voxelize the hexes isn't amenable to adding linear features. Using noise functions for everything can produce interesting-looking terrain, but I want to take a more hands-on approach for some terrain elements, eg to use code to define where those ridges are and then proceed from there, rather than trying to cobble together some function that does it for me. I'm also trying to avoid using an iterative weathering or erosion process to do that. So, who knows.

For now, I'm proceeding to working on adding flora and finding better textures to use, as the debug texture I'm currently using has served its purpose and I'm now trying to make the engine look great. I've got a solid way to define & save geometry, so I'm comfortable punting the generation question for now and coming back to it later.