Friday, March 22, 2019

Getting salty

Well, over the past week or two I've been developing a quite different method of generating lakes at the global level, to avoid a lot of the problems associated with the current method. It didn't work, so I'm just sticking with what I've got.

That means it's time for yet another kind of lake!

I want to add endorheic lakes to Undiscovered Worlds. These are lakes that have no outflow. Although they have rivers flowing into them, they do not overflow because they lose enough water through evaporation to remain more or less static. So these lakes are only found in hot, arid locations, and they tend to be very salty, because the minerals in the water cannot escape to the sea. Famous examples include the Great Salt Lake in the US and the Dead Sea, and arguably the Caspian Sea, although the latter is anomalous in various ways (it is, in a sense, half lake and half sea).

Lakes of this kind are more common than one might think; Wikipedia claims that about 18% of the world's land surface is within the watershed of endorheic lakes. So we definitely want them in our worlds.

Fortunately it's not tremendously hard to do - in theory. All I have to do is add some variables to the existing global lake generating routine so that it can generate lakes in desert regions too (previously, they were not allowed). Such lakes will (a) be relatively small, and (b) have no outflows, making them less problematic to generate. Moreover, we'll have a new global array which will hold information about unusual terrain features (I'll call it "specials"). A certain value on that array will indicate that the lake is salty.

A bit of grappling with the routine, and we get lakes like this:


I think that looks reasonable. (Notice the strong lake precipitation effect here - the winds are easterly at this point - the result is actually some rainforest to the west of the lake.)

Checking the river map for this region reveals:


And what a surprise - we have some problems.

First, there seems to be a river coming out of the lake to the west. How can such a river exist, when the lake-creating routine is supposed to ensure that all rivers on or next to the lake are flowing into it?

Second, and more seriously, there are some very weird things going on with other rivers in this region. To the north and northeast of the lake there are some points where rivers start flowing in tight, knot-like circles and don't go anywhere. This is something I've never seen before. What could possibly be causing this?

Well, regenerating everything without salt lakes removes those weird river knots, so it's certainly being caused by the lake. Moreover, doing it all again with the salt lakes, but allowing the river inflows and outflows to be calculated normally, also removes them:


So there's something wrong with the way I'm altering the river calculations with these lakes. I'm trying to be clever and adapting the river generation function so that, for salt lakes, it doesn't calculate an outflowing river in the first place, but evidently it's not working properly. An alternative is to allow the function to calculate it, just as for a normal lake, but then simply delete the outflow afterwards. Unfortunately, that simply doesn't work. After a lot of attempts (slow, because I have to regenerate the whole world every time), I can't find a way to do it that doesn't have awful knock-on effects on nearby rivers.

So I try a completely different approach. This time, I try placing the salt lakes during the river calculation phase. While tracing the drops that calculate the amount of flow on each cell, I put in a check to see (a) whether this is the first drop to pass over that cell, and (b) whether it's the right temperature/aridity for a salt lake. If so, there is random chance of creating not a lake but sea at that cell (and at surrounding cells, following a standard lake template). The routine also ensures that the flow direction on any neighbouring cells is into the new patch of sea. That means that it will be taken into account when tracing subsequent drops: if they flow into this patch of sea, they will stop.

Then, after all the rivers have been calculated, it's simply a matter of going over those bits of sea, raising them up, and turning them into lakes. That gets us lakes like this:



As you can see from the second image of this region, the lake has some rivers flowing into it, but none out of it. That's exactly what we're after. In fact some experimentation reveals that this is still a flawed method - some of these lakes still have rivers going in and out where they shouldn't - but for the most part it's more or less believable, so I'll stick with it for now.

Salt lakes have a tendency to vary considerably in size depending on how much precipitation there is. In dry periods they may shrink quite a lot. The result is a tendency to be surrounded by salt pans. So let's try to implement those.

I think that salt pans - or salt flats - should be another unusual terrain feature, like the saltiness of salt lakes, that can be stored in the specials array. They also have the property of being the same elevation as the surface level of the lake, so they are very flat. At the regional level, we can calculate them immediately after the lake phase. All we have to do is go over any cells that contain salt lake and paste salt pans around them, using our trusty small lake templates. The shallower the lake at that point, the more extensive the surrounding salt pans are likely to be. As with the river valleys, doing this before the main terrain generation means that the latter will simply work around them, raising hills (if appropriate) around the salt pans.

Salt pans shouldn't appear in areas where there is too much precipitation. At the point where we're generating them, we don't yet have the regional precipitation maps. So once we do have them, we make another pass over the regional map and remove any salt pans where there's too much precipitation. So where a salt lake straddles drier and wetter climates, the salt pans will only emerge on the more arid coasts of the lake.

Here's what they look like on the relief map:


Of course, salt pans can also appear by themselves, without permanent lakes, where the water has simply dried up completely (or comes and goes sporadically depending on the weather). It would be good to put those in UW too.

Small salt pans aren't too hard to do. We can use our ever-useful small lake templates to plonk them down on random desert tiles, provided there are no rivers present. Thus the unrelenting bleakness of the desert in this picture becomes - well, very slightly bleaker:


Those teeny salt pans (in fact they're several kilometres across) add a little variety to the desert, but it would be nice to have some really big ones too. In reality the largest salt pan in the world is the Salar de Uyuni, which at about 10,500 square km would, I think, be about 50 pixels across on my maps (if it were square).

We can create larger salt pans by treating them as sort of weird lakes without any rivers or water. Basically, we can store them on the global lakes array, just like normal lakes; but on the specials array, we'll mark the same cells as being salt pans. An advantage of this is that it allows us to ensure that the salt pans are perfectly flat, even though they extend over different cells. (This also allows us to use the same system for other features we might add later, such as swamps; we would make them like lakes too, but mark them as swamps on the specials array.) Then, at the regional level, we can calculate them like lakes again, but making them salt instead of water.

That takes a fair bit of messing about, because it requires a lot of rejigging of much of the code that refers to lakes in order to make sure that it doesn't think the salt pans are actually lakes, but it gets us this:


These salt pans are created in the lake generation phase of the regional map level, i.e. before the land around them, using exactly the same methods as normal lakes; but the program then goes over them and turns them into salt flats, at the elevation of what would have been the surface level of the lake. One feature of lake generation at this point is that a modified flood fill routine is used to identity any bits of lake that aren't connected to the rest of it, and to get rid of them. I've turned that off for the salt flats, because I think it looks quite good to have a more fragmented "coastline" with odd little bits separate from the main body.

One more little tweak: adding a random chance to place small salt lakes in the middle of large salt pans:



So you get a nice effect of an old inland sea, almost entirely dried up, with just an occasional shallow pool in the vast expanse of salt. I think it helps to make the deserts just a little more interesting.

1 comment:

  1. I'm definitely stealing some of this as soon as I have time!

    ReplyDelete