Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Procedural psuedo infinite world generator

Discussion in 'Scripting' started by Sciwiz12, Jul 10, 2015.

  1. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    Let me provide a brief background. I'm new to all of this but I knew I was new so I went back and learned the fundamentals of programming, how to write code in c#, how to code in unity, and a bit about fractals and noise. That said, while I suppose I could figure out how to generate height maps more or less using, for instance, a perlin noise function; I am having difficulty figuring out how to represent the arrangement of my environment types.


    I imagine something like this, where only one of those pixels for instance represents an entire forest, or desert. Additionally only one would be generated at once, but the noise function would still dictate which environment type will be generated next in an orderly and sensible fashion. Here's my issue, I don't know conceptually how to turn the above into this:

    upload_2015-7-9_22-33-23.jpeg

    I mean, I know (at least in theory) how to create the above independently of surrounding environment types. Conceptually I could create the rules for generating the environment above and store those procedures under a hill and valley subclass of a biome superclass or whatever. Obviously it's not easy but I at least can conceptualize it pretty easily more or less, or if I can't it's a product of the fact that this is not my priority just yet.

    I feel like I'm still not being clear enough so I'm going to try to reiterate and summarize. I can theoretically create this:

    and I can independently create this

    upload_2015-7-9_22-33-23.jpeg
    but I'm not sure how to turn A into B. I'm not sure how to take that grid layout and plug that data in so that each pixel is an environment type, and the noise function is able to calculate the upcoming environment types in a sensible fashion.
     
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I have an old project that did this. I'll post the general algorithm when I get back to my Unity PC.
     
  3. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    Firstly, yay! Secondly, thank you! Finally: Would'st thou mind discussing these concepts with me and your understanding of them? I understand that it may require some back and forth but I would genuinely like to understand the concepts as well as employ them and while I'm sure I could extrapolate the approach from the code, it always helps to see how other people conceptualize problems and their solutions.
     
  4. traderain

    traderain

    Joined:
    Jul 7, 2014
    Posts:
    108
    Could you post the code here or somewhere? I would be interested in it too. Thanks :)
     
  5. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    This may be convoluted, but I think I'm starting to conceptualize a bit better after some deeper consideration. I imagine a world made of terrains/biomes and each biome is made of 1 meter x 1 meter square chunks. Whatever functions I use need to utilize the x and z coordinates as parameters otherwise persistence will more than likely be lost. Each biome is determined to be a square that is x chunks by x chunks in size. When the game is initializing the initial seed will generate around the player and will be x chunks by x chunks of a particular biome type. The chunks generated around the player will be considerably less than the number of chunks that constitute the size of one particular terrain type.

    To give an example, let's say that a biome will be 9 chunks x 9 chunks though in reality it will be substantially bigger. The player will start in the middle and at any given time will be in a square of 3 chunks by 3 chunks. As the player moves in a particular direction, there will be either a chunk count that increments in a given direction as new chunks are loaded in, or the formula will simply transition the environment at 9x, -9x, 9z, and -9z. Beyond that boundary, any chunks loaded are loaded for the next environment type. Alternatively the chunks might decrement rather than increment, such that boundaries are automatically 0 and start counting up as the player approaches the center of a biome before decrementing again.

    Just as the chunks decrement, so too might the biomes either increment or decrement with a count that resets after a particular limit threshold has been reached. In this way you can ensure that the next biome type loaded is more or less likely to be of the same type, so for organizational purposes a single biome can be a square, but an arrangement of biomes can be of varied shapes. The limit to an increment of biomes before resetting can be based off of a perlin noise algorithm to make the arrangement of biomes more organic and varied.

    My only fear with the system I have just described is that I may lose persistence of height maps and flora among other things once I exit and return to a biome unless the arrangement of distribution of those values within each terrain is decided based on a noise function that uses x and z coordinates as a seed. Within each environment type the distribution can be more or less frequent and the intensity of values greater or lesser specific to the environment type, but the values will still be seeded based on coordinates.

    Alternatively, height maps and distribution of flora and environment features can be global with the origin of the coordinate plane used to derive a seed value at which point each environment acts as a trigger to manipulate the resulting values only for chunks within their defined areas. In that way new environment types only act as triggers to alter values which are otherwise uniform globally.
     
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The actual code is a mess. And I do have the hope of putting it up for sale at some point, but I can run you through the logic. Splitting generating the biomes and generating the terrain into two different tasks is a great idea.

    Here is the details for the terrain generation. Let me know if you want to hear how I generate biomes. First up its important to know that each Terrain has a TerrainData. Much of the relevant information you want is on the TerrainData.
    1. Create a new TerrainData. Set the size of the terrain.
    2. Create and apply a height map. A hightmap can be generated straight from the noise values. A heightmap is simply a 2D array of floats. Values range from 0 to 1. You'll need to set the heightmap resolution as well.
    3. Create and apply a splat map. A splat map represents the textures to be applied to the area. A splat map is a 3D array. The first two dimensions are your regular x and z coordinates, the third is the splat map layer. Again values range from 0 to 1. You will also need to create and apply splat prototypes (technically this should be done first).
    4. Create and apply trees. You'll need to do the tree prototypes first as well.
    5. Create and apply details. (You guessed it, you also need prototypes for this).
     
  7. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    This is my first exposure to the term splat-maps, but it's pretty intuitive considering. Also the prototypes make sense considering it's easier (I imagine) to produce varied instances of a prototype than to generate a tree entirely from code.

    I would love to hear the logic behind how you generate biomes. Terrain data, I looked at it once before I learned everything about Object Oriented programming and coding in C#, but I haven't really looked at the API much since then. Maybe now I can re-examine it with a fresh set of eyes and get some useful knowledge out of it.

    How do you handle transition from one biome to another? I was musing over how to do it above but I am curious to know how you do it.
     
  8. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    Also I am thinking of selling my own variation as well, with the difference being I want to design a tool/window similar to the inspector but it specifically handles procedural terrain generation and allows for easy customization of terrain types. That's not initially why I wanted to do this but I figured I would throw that out there in case it gives you any ideas about how you'd like to market your stuff.
     
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    To generate the biomes I'm currently using overlapping layers of Perlin noise. Each layer determines some factor of the biome, say height or temperature or humidity. This factors get combined together to determine the biome.

    The multiple layers help to break up the obvious Perlin look of the terrain.
     
  10. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    Oh wow, that's brilliant. I conceptualized each biome as an independent entity but you're organically creating biomes as a natural consequence of overlapping conditions.
     
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Yup. I've got a fair bit of biology in my formal training. That's close enough to how it works in nature.

    It also helps to make the biomes sensible. Do it right, and the biomes will be able to flow naturally into each other. You also can get natural tree lines on peaks, and avoid odd things like a tropical rainforest bordering an artic desert.
     
  12. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    Right, I imagine that with each prototype for plants you set the condition in the script that will procedurally generate plants so that they are only instanced in places with the right conditions. For instance you will set the constructors so that no trees are instantiated above certain points on the height map, and no plants are instantiated in regions where the temperature is too low to support life.
     
  13. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Your method works. I did it slightly backwards. I defined trees that would turn up in each biome, and once I determined the biome at each point I used noise to determine if a tree should be placed there. Then more noise to offset and scale the tree to break up the grid pattern.
     
  14. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    Well, I definitely appreciate it! I feel like I have a lot of work to do now that I've finally traversed that hump, and now I have to apply my understanding to my design. That said, thanks. Can I message you if I encounter any other issues?
     
  15. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Sure.
     
  16. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Could you possibly keep it an open discussion in this thread? It'd be good for others who are following this discussion.
     
  17. Sciwiz12

    Sciwiz12

    Joined:
    Sep 25, 2014
    Posts:
    32
    Sure, I guess... Why not
     
    larku likes this.