5
\$\begingroup\$

I need a way to generate a world realistically. I want to generate worlds similar to dwarf fortress.

My current code for world generation is this:

    worldTiles = ['^',',','.','.']
    def generateWorld(self, x=40, y=20):
        world = []

        for i in range(y):
            row = []
            for z in range(x):
                row.append(random.choice(self.worldTiles))

            world.append(row)
        return world

with the worlds it generates being this:

world it generates

The world is ok, however what I want is biomes, not just completly random generation.

In case it helps, heres how the current generation works:

A variable called worldTiles has alls the tiles the world can have. This is used by the function. The function, creates an array, and appends a row to it. The row is then added to the world, as another array.

A example world might be:

  [
    ['^', ',', '^'],
    ['^', ',', '.'],
    ['^', ''., '.']
  ]
\$\endgroup\$
1
  • \$\begingroup\$ Have you tried searching online? I've found this tutorial, that seems to show how you can do that in Unity. Quite possibly you can use the same technique for ASCII characters. \$\endgroup\$ Commented Jan 21, 2020 at 14:59

3 Answers 3

4
\$\begingroup\$

A common technique for generating random worlds with large biomes is to use stock noise algorithms like perlin noise or simplex noise. Such algorithms generate noise patterns which generate a kind of "smoothed out randomness". Values don't change abruptly like they do in random white noise (like you are using right now). They change gradually with varying steepness. Another more "retro" approach to terrain generation is the diamond-square algorithm which is based on starting out with a linear gradient and then recursively adding subdividsions with slight random offsets.

I could explain these algorithms in detail, but it would be a lot easier to just use a library instead of implementing it on your own. Like this one or this one, for example.

A common technique to tweak the results to match specific requirements or aesthetics is to layer multiple instances of noise with different scales and amplitudes on top of each other. You can even layer different algorithms on top of each other. Like using Simplex Noise for the rough outlines of the world and then Diamond-Square to interpolate within chunks.

When you want to use noise patterns for biome generation, then a common technique is to generate different noise patterns for properties like humidity or temperature and then use a lookup table which decides the biome depending on the combination of values. For example:

  • high temperature and high humidity gets you a jungle tile
  • high temperature and medium humidity gets you a savanna tile
  • high temperature and low humidity gets you a desert tile.
  • medium temperature and high humidity gets you swamps
  • medium temperature and medium humidity gets you woodland
  • medium temperature and low humidity gets you steppe
  • low temperature gets you arctic

This is of course just a gross simplification of climate zones. If you want to get really deep into simulationism, then you might want to study some real-world climate science and let a system like the Köppen climate classes guide you.

\$\endgroup\$
1
  • \$\begingroup\$ The Koppen Climate classes is the needle in the haystack I was looking for, using a 1-layer Perlin noise is weak and unnatural, but using a multi-layer system implemented different types of climates classes and syncing them together is most definitely the move \$\endgroup\$
    – Jamisco
    Commented Jun 25, 2022 at 17:26
2
\$\begingroup\$

Don't add biomes, instead vary parameters around your world and pick the biome based on that.

For example you set a temperature and rainfall and you can use them to pick a biome; dry and how would be a desert, cold and dry would be taiga, cold and wet would be snow lands etc.

That way you avoid having a snow biome next to a hot desert without a buffer zone.

You can also create geological interactions to the landscapes like rivers that carve themselves out running to the oceans, mountains creating a rain shadow, etc.

\$\endgroup\$
0
\$\begingroup\$

What you're doing there with the random won't work with biomes. Biomes generate differently based on local climate - which on earth is determined by the physical location on the planet surface.

Even Perlin noise or other 'organized random' functions won't give you a biomes effect you are looking for. They only generate localized groupings. It's still random with no perceived overall pattern.

I haven't yet put anything to code because that would depend on the engine. I think what we need to do is program a 'framework' of sorts. This pattern would model a typical planet and allow us to designate a certain set of parameters for: north, south, mountain, desert etc... Those parameters could then be combined with Perlin noise to get a more natural feel.

So an overview of this might be:

  • Create the planet surface
  • Break up the surface into segments with a specific pattern
  • Assign each segment a set of parameters
  • Feed those parameters into a noise function
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .