Editing AAGRINDER terrain generation (technical)

From AAGRINDER wiki
Jump to navigationJump to search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 7: Line 7:
 
In AAGRINDER, I wanted the world to be generated in smaller sections (called ''chunks''), while it is explored. This way, one can keep exploring as far as they want, and it will always be possible to generate more terrain. At the same time, I wanted the world to be predetermined by the world seed. This means that even though we are allowing the player to explore chunks in any order, the resulting terrain must be identical regardless of the exploration order. Because of this, the world generator must be a program which generates a chunk at specific coordinates, without knowing which surrounding chunks already exist and what is in those surrounding chunks.
 
In AAGRINDER, I wanted the world to be generated in smaller sections (called ''chunks''), while it is explored. This way, one can keep exploring as far as they want, and it will always be possible to generate more terrain. At the same time, I wanted the world to be predetermined by the world seed. This means that even though we are allowing the player to explore chunks in any order, the resulting terrain must be identical regardless of the exploration order. Because of this, the world generator must be a program which generates a chunk at specific coordinates, without knowing which surrounding chunks already exist and what is in those surrounding chunks.
  
I also wanted the borders of chunks to always match up nicely with surrounding chunks, which makes the world look continuous and consistent. There are a few ways of achieving continuous world generation.
+
I also wanted the borders of chunks to always match up nicely with surrounding chunks, which makes the world look continuous and consistent. There are two ways of achieving that: the boring way, and the awesome way.
 
* The boring way of making chunk borders match is to make all chunk borders the same. So make them either all full of stone or all full of air. The world would look like a giant grid, it would be very obvious where the chunk borders are.
 
* The boring way of making chunk borders match is to make all chunk borders the same. So make them either all full of stone or all full of air. The world would look like a giant grid, it would be very obvious where the chunk borders are.
* A better alternative with better results is to generate floating islands which are randomly placed into the world. This can be done consistently and locally, even when the island appears on the chunk border. Sometimes two or more generated islands may overlap, in which case we can either drop all of them, or assign them deterministic priorities to decide which one will stay. This is how AAGRINDER worked back in 2018, but not any more.
+
* The better way of achieving matching chunk borders is by sampling noise. Here, noise is some mathematical function with which we can calculate a value for any specific position in the world. We of course know the world coordinates of each block in the chunk. The generated world will then reflect the qualities of the noise function that was used. We would use a type of coherent noise, such as [[wikipedia:perlin noise|Perlin noise]], to get interesting shapes. With that, matching chunk borders are guaranteed.
* The way to achieve a true continuous terrain (not only islands), is by sampling a noise function at each block in the chunk. The generated world will then reflect the qualities of the noise function that was used. We would use a type of coherent noise, such as [[wikipedia:perlin noise|Perlin noise]], to get interesting shapes. With that, matching chunk borders are guaranteed.
 
  
Unfortunately, it's not that simple. We don't want the final product to look exactly like Perlin noise, and we also want to add additional features to the terrain, such as trees. These features can be bigger than 1 block and can stretch from one chunk into another. Because of this, we need to generate some additional area around the current chunk, just to see if there are any trees there and if they maybe stretch into the space of the chunk we're supposed to generate. The amount of the extra generated edge around the chunk should be the same as the size of the largest possible tree.
+
Unfortunately, it's not that simple. We don't want the final product to look exactly like Perlin noise, and we also want to add additional features to the terrain, such as trees. These features can be bigger than 1 block and can stretch from one chunk into another. Because of this, we need to generate an additional area around the current chunk, just to see if there are any trees there and if they maybe stretch into the space of the chunk we're supposed to generate. The amount of the extra generated edge around the chunk should be the same as the size of the largest possible tree.
  
Unfortunately, it's not that simple. Trees can interact with each other, prevent each other from growing depending on which ones of them grow first, so you might get a chain of strange events which brings changes all the way from the edge of the generated area into the actual chunk. And suddenly, there's inconsistency at the border. By increasing the size of the extra generated edge, you can make this less likely, but before you know it, that extra edge is bigger than the chunk itself, and you are spending most of the precious processor time generating this imaginary terrain which is then thrown away. The true solution, which is implemented in AAGRINDER as of 25th May 2024, is to first pre-generate only the ground / general shape, before adding any larger decorations. This information is then shared between the different chunks while they are being finalized. This way, we can mostly avoid generating duplicate terrain around each chunk. Ideally, the in-between results would be cached for future use, so they never need to be re-generated. But this is not implemented yet.
+
Unfortunately, it's not that simple. Trees can interact with each other, prevent each other from growing depending on which ones of them grow first, so you might get a chain of strange events which brings changes all the way from the edge of the generated area into the actual chunk. And suddenly, there's inconsistency at the border. By increasing the size of the extra generated edge, you can make this less likely, but before you know it, that extra edge is bigger than the chunk itself, and you are spending most of the precious processor time generating this imaginary terrain which is then thrown away. The true solution, which is also used in Minecraft, would be to generate only the ground, and call it an ''unpopulated chunk''. Then, once the surrounding chunks have also been generated as unpopulated chunks, the chunk in question would be sent back to the generator, this time with all the information about the surrounding chunks. Trees can be added reliably in this step, along with structures and other bigger features.
  
AAGRINDER does not use the concept of unpopulated chunks. Instead, I do actually generate a very large border around the chunk. I hope the admins and the players won't mind if it takes 1 second to generate a chunk instead of 0.2. The server and the terrain generator are different programs in different languages, so caching intermediate results would be particularly difficult.
+
AAGRINDER does not use the concept of unpopulated chunks. Instead, I do actually generate a very large border around the chunk. I hope the admins and the players won't mind if it takes 1 second to generate a chunk instead of 0.2. The server and the terrain generator are different programs in different languages, so generating in multiple passes would be particularly difficult.
  
 
== Stone generation ==
 
== Stone generation ==

Please note that all contributions to AAGRINDER wiki are considered to be released under the Creative Commons Attribution-ShareAlike (see AAGRINDER wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)