A desert in a sandbox

I have written a few times on world generation [1, 2]. A particular interest of mine is the ability to really use the infinite world that it is possible to create with algorithms to create something more than the imagination that is put into it.

Ideas which generate something which is more than the sum of it’s parts are the holy grail of ideas. General relativity was this in physics, with relatively little experimental input, a huge amount of predictive power was created.

This is the case for games where the terrain is generated procedurally. The developer of the game does not need to design each bit of the world for it to emerge as a huge, possibly infinite world.

The problem with these worlds such as Minecraft is that although they are very large in size, they are limited in kind. Minecraft for example uses the concept of biomes. Each has to be developed and tested individually by the developers, making the systems take longer to build and all the surprises are manufactured. This is fine if you have some number of developers and a lot of players, the sum of the discovery of the players is much larger than the input from the developers, but to the developers themselves, there are no surprises. Any surprises in store for the devs are simply bugs.

As a developer, I enjoy the first of these two, the ability to build something that then surprises you. Something that is much majestic that what you put in. This in a way is the magic I see in the application of Perlin noise (I did a blog post explaining Perlin noise in detail).

This post, then, serves as the presentation of the sandbox, I have made that, I hope, will facilitate the exploration of my ideas on how to create worlds which are as varied in kind, from the same input, as terrain produced from Perlin noise is in geography.

Building a voxel sandbox

The first thing I tried was an expansion of this tutorial which I had attempted to follow after a particularly effective dopamine detox back in February. The tutorial explains how to build a voxel-based system in the three.js library. Basically a Minecraft looking thing in the browser. There are a few reasons why this is harder than just asking the computer to render lots of cubes. For a start I wanted to be able to run it on my Chromebook which means that the rendering capacity is very limited, second, the number of cubes for even the smallest of worlds is huge. As is explained in the tutorial I was following, by just rendering the outer cubes, you can reduce the amount of information the rendering agent has to keep track of by a large factor O(n^2) O(n^3).

Sticking to the desire to create an infinite world I would need to create a system that could dynamically load chunks around the camera so that the world would be created under the moving observer.

That lead to the following demo, which I’m quite happy with, its always nice to get a visual output from the code.

Building a viewer for world terrains

The next thing I wanted to do was to build a 2D tool that would allow me to quickly explore world generation algorithms. This I expanded off the code I wrote for the Perlin noise post.

Resulting generated world (or a section of it)

Expanding that I created a viewer that would aggregate components together to produce the world above. However the code was getting a little too long for jsFidle and I moved it to a mini-flask server which would aggregate my JS files, allowing me to put the Perlin noise for example in a differnt file. I've created a repo to contain the code here.

To build the world I layer a selection of perlin noise layers, differentiated by their scale and in some cases and offset. The layers are as follows:

  • Ocean-Land - This defines where the oceans are and would in a 3d world define how high the land was above sea level.
  • Mountains - This defines where the mointains should be, it uses a function to push it's values closer to 0 or 1 so that the mointains occurse in vains.
  • Local variation - This defines some variation in the terrain height on a local level, creating hills and inclines.
  • Drainage - Using this as a feature was inspired by the Terrian generation model that Dwarf Fortress uses, it allows for both well drained rainforests as well as swamps and marshes.
  • Temperature - A defining feature of most of the bioms, it has falls away with height in hope that the highest points would become snow topped.
  • Rainfall/Precipitation - This falls of with the distance from the ocean, modeling that the oceans be the source of rain.

Better models could be made for the way the rain falls based on prevailing wind direction, which would allow for mointains to create rain shadows. The idea behind this model world was that you can find the value of any point independently, without needing to consult neiboring points. In a model such as this, the rain can't really fall off with distance from the ocean, but that can be approximated using the Ocean-Land value. This has the effect that if the ocean land value rises sharply, in such a way as to take a high value close to an ocean, the rain would fall off as if distant from the ocean. It is also the case that small Ocean-Land values that arn't small enough to result in water being rendered, would have high precipitation, despite perhaps being a long way from the ocean.

The colours in the image might need some explaining. The blue regions, perhaps obviously, as the ocean. The greener the colour blue, the warmer the ocean temperature. This differenciates, in a continous manor, arctic oceans from tropical ones. The wide white regions, are arctic bioms where the surface has iced over, white can also represent ocean ice, however this is set to a much colder temperature and so is rarer. There might be some white atop mointains and this is where the temperature there has dropped enough for snow to form.

The greens represent areas with vegitation, dark green represents rainforest, lighter green a more temperate forest. It would be nice to add areas that represent savana and grasslands but for the time being I'm defining these two shades of green to be rainforest and temperate forest. The dark browns represent all of swamps, mangroves and marshes. I'm sure these could again be differentiated with a little more effort, although it would be perhaps more meaninful when transfered back over to the 3d blocks than into simply more colours viewed from above.

The yellow/orange/gray areas are the deserts. Yellow being hot desert and gray being cold dessert. The variation within those is drainage, going back over this that doesn't make a lot of sense but it makes for a slightly nicer image. The light brown areas represent places where the elevation is too high for vegetation to grow, but not quite at the snow line.

It would be nice to move the world map over to the block representation and add the blocks for water and trees. I think it would make for quite an interesting world to explore. Moving onto that world I think it would be interesting to add levels of mineral deposits to areas, more iron would lead to a more outback coloured dessert more silica a saharan one. There is a little more left to do in the 2D representation, I would like to add some of the city placement models I have spoken about. I have also tried to form a way of generating the rivers without doing a local look around but I'm not sure that is at all possible. The hydrology is always a difficult element to world generation.


Popular posts from this blog

An exploration in number systems

Structural engineering with cardboard