Monday, October 5, 2020

Delta Drawn (Part 2)

At the end of the last post, I had created land part of a delta at the mouth of a river:
Now I need to fix the river so that it actually crosses the delta, and then add in the branches.

To start off, I'll send the river across to the middle point of the delta.  Rivers are normally created as part of a process that traces the flux of water across the Voronoi grid.  I can't do the same thing here but I'll have to make sure my new invented river course has all the proper attributes and values.  The first step is to find the midpoint of the new delta, and connect the existing river to that:
Well, that sort of worked.  But the new river segment is narrowing down to nothing at the mouth of the river.  The problem turns out to be a missing divisor in a calculation and that is easily fixed:
Okay, so now we have the river reaching the ocean, which is a good start.  Right now it's just a single straight segment from the old end of the river to the ocean.  We can break that up into a few segments and add some variation.
Now the final segment is fairly indistinguishable from the original river.  However, there's a slight trace of line across the mouth of the river.  This happens because I've drawn the river exactly to the shore, and (because lines have thickness) some of the coastline is still showing.  The solution is to project the river a little bit further into the ocean.
Now I need to fill in the rest of the criss-crossing rivers of the delta.

The basic idea is that I'll repeatedly branch one of the existing rivers in the delta and then run the new river to some point on the coastline of the delta.  Something like (bad graphics warning):
Each time I split off a branch, I'll split some of the river's flow off to go with it.  I don't care if rivers cross each other, but one thing I want to avoid is a river with an impossible or highly unlikely flow, like this:
To keep this from happening, I'll force branches to go somewhere close to the mouth of the river they are branching from.  The farther back they branch, the farther away from the mouth they can go.

I'll start by just creating a branch manually to see if I can get that to work:
That sort-of worked.  There are a couple of problems.  First, the river is hitting the shore at a very oblique angle, which causes problems.  Secondly, the start of the river where it branches off the main river is very narrow.

The latter problem occurs because prior to creating deltas, I've never had a river split off of another river.  I've only had rivers join with other rivers.  Every river starts from nothing, so Dragons Abound always draws rivers starting from a point and growing to their initial width.  What I need to do is add a test to detect when a river is branching off of another river, and then suppress the narrow start.
That seems to have worked.  The problem of the oblique approach to the coast is more troublesome; with an irregular coast and a thick river, making them meet seamlessly in all cases is challenging.  For now I'm going to ignore it and see if I can get the rest of the delta drawn.

My idea for drawing the delta is to start at the point furthest from the coast, pick one or more random spots on existing rivers to branch from, then move a little closer to the coast and repeat.  By varying the number of branches and the space between branches and other variables, I should be able to tweak until I get something I think looks good.  We'll see.

Here's the first attempt, with decorations turned off (so all the rivers are straight):
This looks surprisingly un-terrible.  One problem seems to be that the very short rivers right at the coastline are a mess, so it might make sense to end the river splitting early.
That looks better.  Let me now introduce some noise into the paths of the rivers.
That is starting to look okay.  One noticeable problem is that sometimes the river branches run through other branches.  I'd like to notice when a river hits another river and then terminate it there.  This would create short connectors between branches.  Unfortunately, that turned out to be very difficult to program.  First it was difficult to detect intersections and correct the rivers to merge, and then these short connectors broke all the succeeding delta creation.  Eventually I had a “duh" moment and realized I could keep the short connectors as rivers but drop them from all the subsequent delta processing, and then things more-or-less fell into place.

I also did some experimenting with various parameters for the branching trying to find a combination that would give me something pleasing to the eye and avoiding some of the more obvious problems.  Here are some examples at slightly enlarged size:

These all look pretty good to me, so I'm willing to declare victory on the basic concept.  

The last step is parameterize the code.  Up to this point I've hard-coded the delta onto the longest river on the map, and hard-coded the values for the parameters that control branching, etc.  Now that I've got a working version, I can go through and parameterize the code so that I can have more than one delta and the deltas can have different characteristics.

Here's a kind of interesting result after that work:
Here the generator has randomly plopped a lake down right on top of a delta.  I'm not sure what to think about that.  On the one hand, the code does a pretty good job of rendering the situation.  The northern-most river is implausible because it connects to the lake in two places, but other than that I'm not sure this isn't a real-world possibility.  There's a lot of weird terrain in the world.

Here's another weird one:
What the heck happened here?  Let's look at the river without the delta.
The problem is that the delta algorithm somehow put the mouth of the river on the far left of the delta rather than near the middle.  This occurred because the semicircular delta added to the map intersected with the coastline in more than two spots.  It cuts off a little bit of the bay just above the river bend, and the algorithm puts the river mouth there, causing the acute turn in the river.  The fix is to use the first and the last intersections rather than the first two intersections.
Oops.  Well, maybe not.  Without going into too many details, this happens because the delta happens to get added where the coast wraps around, so the “center" found by the algorithm is in the whole rest of the coast rather than on the delta!  This is actually a rather tricky problem to detect, much less to fix.  After thinking about it for a couple of days, I decided there wasn't a solution that didn't require a lot of painstaking bookkeeping.  So I've decided to simply detect this case and reject this delta.

Of course, in most programming jobs you can't simply decide to skip something because it would be hard.  But a map doesn't have to have a delta. If I decide to add a delta to the map, I can also “undecide" that later on if it is too hard to do.  Of course, if I do that too much I may run into trouble, but I've found that the 80 / 20 rule is a good guide -- I can throw out about 20% of the problem cases without too much negative impact.

Adding the tests to avoid the case above turned up a couple of other bugs in the implementation which took a while to correct.  I also had a few maps that took a very long time to run, so I made one of my periodic performance investigations.  One of the big culprits was the code that tests whether a point is within a polygon.  My implementation was based upon code I found here.  I did some research on efficient point in polygon algorithms, and found an interesting discussion on the topic by Dan Sunday.  Dan suggests that a proper implementation of the “winding number" algorithm is both more correct and faster than other implementations, so I tried a Javascript implementation of his algorithm, based on code by Vlad Lasky that you can find here.  This indeed was about 10% faster than the old algorithm.  

The more interesting discovery is that every once in a while a map takes much, much longer to run than normal.  I suspect this happens when the JIT compiler in the browser has to compile the Dragons Abound code, but I'm not sure, and there doesn't seem to be any easy way to tell.  (Send me an email or a comment if you know how to suss this out.)

That pretty much wraps up deltas for now.  Here's a random map (click for full-size) showing a delta in context:
This is literally just the first random map I generated, but it happens to have cluster islands opposite the mouth of the delta, which is a nice touch.

Monday, August 24, 2020

Delta Drawn (Part 1)

Since I'm apparently on the topic of rivers, I decide to take a look at adding deltas to rivers.  River deltas form where a river enters a slow-moving or stagnant bay.  Sediment in the river deposits out and “grows" land at the mouth of the river, usually in the form of a large fan.  If Dragons Abound implemented a full model of rivers including sediment deposition, this would happen naturally during world generation.  But Dragons Abound's river model is simplistic and doesn't do this.

Simply adding some land area to the mouth of rivers is not very interesting but the way deltas are created has an interesting side effect.  The river can only deposit sediment where it flows, so it can never build up land that is higher than the level of the water.  As the sediment builds up to almost as high as the water level, the river turns aside and finds another path.  Meanwhile wind and rain and other forces may push the sediment into piles higher than the water level.  The end result of all this is that the delta tends to grown into a fan of river branches across the delta:
(Lower Cook Inlet, Kachemak Bay. Alaska, from NOAA Photo Library)
Unlike a simple fan of land at the end of a river, a fan of branching rivers looks pretty interesting, so that's what I'll work on adding to the map.  But to start off, let's go back to that uninteresting bump at the river's mouth.

Adding a bump to the mouth of a river might be uninteresting, but that doesn't mean it is easy.  Naively, you might think that it's only a matter of finding a river mouth and then building up the land around that point.  But here's what happens when I do that:
You can see a (ridiculously exaggerated) semi-circle of lighter-colored ocean where I've added the new land.  It is getting displayed as “shallow ocean" rather than land.  Why is that?

The reason has to do with how Dragons Abound generates land.  In order to get detailed coastlines, Dragons Abound generates land using a dense Voronoi grid.  However, using a dense grid drastically slows down subsequent world generation routines (such as calculating wind, precipitation and rivers).  To avoid that, once the land has been defined, Dragons Abound saves the detailed coastlines and reduces the size of the grid.  From that point on, the coastlines define the land, so raising parts of the ocean doesn't change the land.  So there's a bit of a Catch-22 here: until I have the rivers defined I don't know where to add a delta, but after the rivers are defined I can't change the shape of the land!

Of course, it's only code so nothing is really impossible.  But rather than simply raise the ocean where I want new land, I have to do something more tricky, like intersecting the coastline of the new land with the coastline of the old land.  This sort of thing can be pretty finicky, but might as well give it a shot.

The first step is to find the outline of the new land.  I do this by drawing around all the locations I have raised up out of the ocean:
This illustrates a couple of problems.  First, there may be islands that create “holes" in the outline.  This is less likely with a more reasonably-sized delta, but still a possibility.  Second, this outline doesn't actually correspond to the coast, because it is based on the coarser Voronoi grid.  So if I try to “add" this coastline to the existing coastline, I'll end up with holes.  A better solution is probably to make an outline from the whole circle:
Now I need to find where the circle intersects with the coastline.
This has been easy enough so far but not yet very useful.  What I really need is to create the union of the red circle with the existing coastline.  This is called a boolean polygon operation, or polygon clipping.  You can imagine how you might do it in this case, but in its most general form it's quite a challenging problem.  Fortunately, Alexander Milevski has essentially solved this by implementing the Martinez-Rueda polygon clipping algorithm in Javascript.  So I will apply that code to create a coastline that includes the circle:
So now in theory I should be able to replace the existing coastline with the new combined coastline:
That almost works.  The land is not being rendered correctly, the islands create some problems, and the coastline looks jagged and primitive due to the reduced resolution.  Some of these problems will likely be non-issues with a smaller delta, but I will address them anyway.

I'll start with the jagged coastline.  Since the added land will be a river delta, it should look okay if I relax the circle to create a smoother outline.  (In fact, since I'm creating the new coastline by a union with the circle, I can create the circle however I want, so I don't actually have to work on the coarser Voronoi grid.  But this way is easiest.)  I'll interpolate the new coastline for a bit more detail and then apply some smoothing:
That looks okay, at least for now.  (For the future: Rather than use a semicircle for the delta, I could use a distorted semicircle or some other more natural shape.)

To take care of the islands, I can use the union function I used above.  I can union each island with the mainland, and if the result is just one coastline (meaning the island was inside the mainland), I can delete the island.  Unfortunately, all these unions are slow but I only envision doing 1 or 2 deltas on a map, so perhaps it will be acceptable.
Now let me see about the odd land color.  Since the island is still showing up as a correct land color, I suspect the new land I'm creating is missing some attribute.  When the coarse Voronoi grid is created, each spot gets marked as land if it overlaps at all with the coastlines or not land if it is entirely outside.  The new locations I've included are still marked as being “not land" and hence are not getting colored in.  Marking them land fixes that problem:
Now the land color is being added, but there's no markings for the biome.  But that's not incorrect; its just that this part of the world doesn't receive much precipitation and is a desert.  If I artificially add precipitation, I can force it to display as a swamp:
So everything seems to be working, and I can try dialing the size back to something more realistic.
Looks pretty good.  Not shown here, but I also added some logic to keep cities from being placed on deltas.

Now that I've finished the “easy" part, next time I'll work on creating the actual tangle of rivers on the delta.

Monday, July 6, 2020

A Meandering Subject

For the past few months I've spent some time away from Dragons Abound to pursue other hobbies and interests.  I've had a surprising number of people contact me to ask about my well-being.  I am very touched that people care enough to inquire!  I'm perfectly fine, but I find that (for me at least) “Forever Projects" like Dragons Abound work best if I allow my attention to be pre-empted by other projects and interests.  Sometimes I come back to the original project, and sometimes I don't, but I think that's better than getting caught up in trying to meet some preconceived notion of what I should be “accomplishing."  I have some much longer thoughts on Forever Projects that I'll try to post soon.

In the meantime, I recently had some thoughts about rivers and decided to spend a little time on that topic.

This map excerpt illustrates one aspect of Dragons Abound's rivers that bothers me.  Rivers often have stretches of wiggles as you see on the right-hand branch of the river in the plains.  This happens because the rivers are drawn from the center of one Voronoi polygon to the next, and three adjacent centers are almost never collinear, so rivers always have a kind of snaky path.

To some extent I can eliminate this by smoothing the river's path before drawing it.  In fact, the example above has been smoothed.  Without smoothing it looks like this:
You can see that smoothing has already greatly improved the look of the river.  

One possible solution is to increase the density of the Voronoi polygons that underlie the map.  The river will still wiggle, but at a finer scale that will be much less noticeable.  
Here (at 150%) you can still see some wriggles, but they're less noticeable and essentially invisible without some magnification. However, this solution creates other problems, most noticeably performance.  In this case I quadrupled the number of underlying polygons and increased the runtime by about 10x.

A better solution is to remove the river's strict tracing from the center of a Voronoi polygon to a neighboring polygon.  I'd like to do this in a way that eliminates the small wiggles while retaining (as much as possible) the overall path of the river.  Conveniently, there's an algorithm to do exactly this -- Visvalingam's algorithm.   I've written about this algorithm previously, when I used it to (ironically) simplify river paths when attaching labels.  There's a detailed explanation in that previous posting, but the simple version is that algorithm removes the point that creates the least change in the path.  You then do that repeatedly until you (say) remove 50% of the points in the path.  This has the effect of removing the highest frequency “noise" first.  Here's the river with 70% (!) of the path removed:
Visvalingam's algorithm is so good you have to remove a surprising amount of the path to make a noticeable difference, but you can see that it has retained the shape of the river and the broader curves while eliminating the wiggles.  Unfortunately, it has created a new problem.   One of the junctions of two rivers is now wrong, and the joining river overshoots.  This happens because the point where the two rivers joined has been removed.  To fix this problem, I have to modify Visvalingam's algorithm so that it doesn't try to remove any point where rivers join.  I already have that fix in place for the smoothing algorithm, so it's mostly a matter of applying the same logic.
Now the wiggles are gone but (at least to my eye) the rivers lack character.  They're reasonable, and they look a lot like other procedurally-generated rivers, like these from Azgaar's generator:
Most procedurally-generated rivers look like wandering lines with some side-to-side perturbation.  Real rivers seem to have more radical bends to them.  For example, this is a stretch of the New River in Virginia:
Note how the river bends so much that it actually reverses direction four or five times along this stretch.  There's nothing particularly unusual about this stretch of river.  You'll see this on almost any river you examine.  I actually picked the New River because it is (ironically) the oldest river in the US, and I figured it would have fewer bends than younger rivers.

In the example above, the New River is winding around hills.  Where the terrain is flatter, rivers can form meanders with even more dramatic bends:
But you'll rarely (never?) see this sort of river on a procedurally-generated map.  There are a number of reasons, but the primary reason is that procedurally-generated terrain only looks realistic at certain scales.  It doesn't have the right characteristics for drainage that mimics the real world.  And most procedurally-generated worlds don't implement realistic river erosion, either.  Whatever the reasons, the Dragons Abound rivers don't have realistic bends and twists, so I want to see if I can add some.

The first difficulty is that I have to recode the representation of rivers.  Currently, rivers are generated as a sort of linked list between Voronoi locations.  It's only when the river is being drawn that it is converted to a path.  In order to add more realistic curves to the rivers, I need to do is convert the rivers to paths immediately after they're created rather than right before they'd drawn, and then use these paths for the rest of the map creation.  This isn't too hard conceptually, but it involves recoding in a number of places.

[After a few sporadic days of refactoring.]

For various uninteresting reasons, that was much more difficult than it should have been, but the refactoring improved the code a bit, so it was (perhaps) a good investment.

Before I get to work on meanders, I want to see about adding some variety to the width of the river.  For various reasons having to do with the way terrain is generated and smoothed, the width of rivers tend to be smooth, slowly increasing curves, as can be seen in this example:
While there's some variation here, it's generally a pretty smooth curve.  To add some interest, I'll vary the width slightly using a noise source.  Here's an initial attempt:
That's a bit too extreme a variation.  After tweaking the noise parameters a bit to get something I like a little better:
So that adds some interesting variation to the river.  One minor problem is that these width variations are always symmetric, but if that bothers me enough I'll address it later.

Now that I have the river as a polyline, I can look at adding curves to the river.  In the real world, the basic process that creates meanders is pretty simple -- a combination of erosion on the outside of curves and deposition on the inside of curves.  
As water moves through a curve, the water at the outer part of the curve pushes against the bank and erodes it away, causing that bank of the river to move outward.  At the same time, the water moves more slowly on the inside of the curve, which gives any material in the water a chance to settle out, so sand and other materials get deposited on the inside of the curve.  The result is that the curve keeps shifting farther out.

I had a good idea of how to implement this, but coincidentally as I was working on this, Robert Hodgkin released a page describing his Meander project, which contains a better description of my idea than I could have written myself, so I encourage you to read his page.  The “TLDR" is to move each point on the river towards the outside of the current curve and also in the direction the river is flowing at that point.  By modifying the way these two elements combine, you can create various kinds of meandering.

If you read his explanation, Robert's method depends on something he calls the “modified bitangent" of the path of the river.  These look like this:
These lines are perpendicular to the path of the river, point to the outside of the curve, and their length is proportional to the amount the river is curving.  

I have a routine to calculate the normals of a polyline, which are similar but not quite the same:
These vectors are normalized to a length of one and don't always point to the outside of the curve.  To get to the modified bitangent, I have to calculate the curvature of the river at each point, and then scale the vector by that curvature.  To calculate the curvature, I use Menger's Curvature which looks very complicated but is actually simple to implement.  It's also a signed curvature, which means that negative curves will be inward and positive curves will be outside (or vice versa).  The last thing I have to think about is the range of the curvature.  If you look at Robert Hodgkin's example above, it's obvious that he is limiting the curvature measure -- all of the curves below a certain radius have the same length bitangent.  This is necessary because the curvature can have a large range and we don't necessarily want to apply thousands of times more erosion force at one point in the river than in another.

With the curvature measure implemented and forced to a limited range, I can multiply the normals by the curvature to get the “modified bitangents."
However, these modified bitangents are only one part of what I need.  The other part is the tangent.  As it turns out, to generate the bitangent I generate the tangent and rotate it 90 degrees, so conveniently I already have the tangents.  It's a little harder to visualize the tangents because they point straight down the river:
The two vectors are then combined into a vector that points somewhere in-between the two:
This combined vector shows the direction (and scaled distance) the path of the river will move as the curves erode to create meanders.  (Note that combining the tangent and the bitangent this way is equivalent to just rotating the tangent vector 45 degrees.  But it's perhaps easier to visualize this way.)

A couple of things to note about the meander process.  First of all, it's an iterative process.  I need to change the path of the river a little bit according to the combined vectors, then recalculate the vectors and repeat.  If you try to do it all in one shot, you just get a weirdly exaggerated version of the original path.  Second, this process will change the length of the river.  If I want to keep the same uniform distance between points on the river, I'll need to resample the path or add in new points where the existing points have grown to be far apart.  Lastly, there are some points on the river I have to keep the same -- notably the spots where two rivers join each other -- or else I'll have problems where the rivers join.

To start with, I'll do a single iteration at the scale of the visualization and see what that looks like.  Before meander:
After meander:
You can see that the meander process is starting to exaggerate curves in the river.

Here it is with 10 iterations, with smoothing and re-interpolation between each iteration:
It's instructive to vary the direction of the combined vector and see the results.  Here's a version using 90% bitangent and 10% tangent:
This exaggerates the curves.  (And as you would expect, 90% tangent adds only small curves.)  Increasing the strength of the vector also exaggerates the curves:
All these examples have looked mostly okay, bad things can happen when meandering:
This is obviously exaggerated, but illustrates a couple of different problems.  First, meanders can cause a river to cross itself or another river.  Second, meanders can cause problems where rivers meet other rivers or enter the ocean, by creating unrealistic paths.  Multiple approaches will be required to tame these various problems.

I'll start off by avoiding meanders not just where rivers join other rivers or the ocean, but also for a distance on either side.  The easiest cases to handle are the start and end of the river.
The river now meets the ocean cleanly, but there's an abrupt and obvious transition where meandering kicks in.  The solution is to have a “mask" that tapers in the meander:
Here the last part of the river is not meandered at all and then the next part slowly gets more meander.  Now I need to apply the same masking principle to all the joins on the rivers.
Now let me address rivers crossing themselves.  When this happens, the river can be repaired by removing the loop and adding a new point where the intersection occurred.  If I step through the river a segment at a time and see if the current segment intersects any of the later segments, that will provide the new intersection point as well as all the segments that can be eliminated.  In the real world, when this happens the cutoff portion of the river becomes an oxbow lake.  For my purposes, I'll just eliminate the cutoff.
If you compare this map with the one two above, you'll see a river loop has been removed in the area circled in red.

Dealing with rivers crossing other rivers is more difficult.  Here's an example:
Inside the circled area a river crosses one of its tributaries several times.  If this were to happen in real life, the two rivers would join at the crossing point, removing the downstream portion of one of the rivers.  That would be very difficult to implement in Dragons Abound, so instead I'll simply detect when this happens and reject that meander.  A second difficulty is that there can be quite a few rivers on a map, so checking all of them for intersections after every meander iteration will likely be slow.  To address this, I'll only check to see if a river intersects with a river it joins to.  It's very unlikely that a river will intersect with a river that it doesn't join at some point; but if this happens a lot I'll find a way to deal with it.

Here's is the same map with the meanders stopped before they created an intersection:
Now the rivers get very close to each other but do not cross.  However getting very close is not very realistic either, so let me adjust the code to create a buffer between the rivers.  The basic idea is to notice when part of a river is getting too close to another river and freeze that part so that it cannot be meandered further.  I can extend that same idea to self-intersections, so that I don't get spots like in the lower right of the above map where the river is so close to itself the border is lost.  Technically it doesn't intersect, but it gets drawn incorrectly.

With that in place the meanders look like this:
The guardrails do a pretty good job of keeping the rivers from getting into unrealistic paths because of the meanders.  Now I need to think about how I want to use meanders.

Obviously I don't want to meander every river to the extent shown in the examples above.  Meanders ought to be a sort of “special interest" feature like swamps or a deserted coast line.  I could achieve this by treating meanders the same way I do deserted coast lines -- at most one on a map, and often none.  However, unlike deserted coast lines, meanders are infinitely variable, so another possibility is to use only small amounts of meander on most of the map and significant meander in only some places.

In real life, meanders form in river valleys where the down-valley slope is gentle.  Dragons Abound has a measure of slope for each segment of a river, so I can try using that to control the amount of meander applied to the rivers. To start with, I can restrict meanders to the flattest quarter of the rivers:
A small amount of meander is applied to all rivers, but only the center part of the Fine Bight River gets fully-developed meanders.  I've also added a parameter so that on any map at most one river gets the full meander treatment.  A small improvement is to use a noise map to control the amount of base meander applied to rivers.  This will result in rivers in some parts of the map remaining straight while others will develop some gentle curves. 
Here the main meanders remain on the upper Jellyfish River but the Kaumgun River has had it's curves gently exaggerated.

Testing on a different map reveals a problem:
Tributaries are getting detached from their rivers.  Some debugging reveals that my calculations for curvature are broken if two adjacent points on the river are the same; that's fixed by filtering out repeated points, but the above problem remains.  After a couple of days of increasing intense debugging, I finally found the error in a piece of utility code that checks where to not move the rivers.  I had assumed that code was correct (it has been around a while) but it wasn't -- a check of the code base revealed that I'd never actually used it before.  Oh, well.  Don't assume when you are debugging!

With that debugged, meanders are working on this test map as well:

With the meanders more-or-less working (I tend to tweak features for quite a while as I study them more) the next (and last step for this blog post) is to work on naming.

One problem with naming is immediately evident: meandered rivers will never get a label.  This is because rivers use path labels that (more-or-less) follow the river, and with very sinuous rivers the label can never get snug enough to the river to warrant display (or at least not along the sinuous part).  Second, I'd like meandered rivers to get a name that reflects the character of the river, e.g., something like “The Meanders" or “Snake River."  There are a few names like this in the river name generator, but of course they won't necessarily come up on the meandered river.  Finally, in the case (as above) where the meandered river later straightens out and continues on, I'd like to give the meandered part a separate name from the rest of the river.

Since I'll later need to treat the meandered section of a river as a separate river, I'll break it off from the rest of the river and actually make it a separate river.  Then I can give that river its own name.
Unfortunately, this breaks the connections between the rivers and tributaries flowing to the sea, so that the meandered river just ends abruptly and the remainder of the river thinks it is starting from that location.  Fixing that will be very difficult / impossible, so I will have to seek a different solution.

Instead, I will mark the area of the river that has been meandered and save the original river path.  Then when I get to naming I'll add a second name to the meandered portion of the river.  That gives me this:
For the meander, I let the label overlap with the river and try to center it somewhere roughly in the middle of the meanders.  This works okay, but I might have to tweak it a bit in the future if it is too hard to distinguish.

In the map above, the river name was hard-coded.  I need to be able to generate a variety of names for meanders.  In this case, I generate two kinds of names.  One kind is variants of  “The Meander" using different synonyms for meander, both obvious ones like Rambles and archaic ones like “Cringle-Crangles."  The other kind is variants on “The Snake River" with different synonyms for snakes and other snake-like things.
Here it has been called the “Anaconda."  Technically, this is still part of the Moor River, but given how meanders are created, there will always be a join between the meandered part of the river and the other part, so the names don't clash.

In the map above, you might notice that some of the meanders go into the forests, while elsewhere the forests avoid the rivers.  This happens because the forests look at the actual water flux to decide where to avoid, but of course in creating the meanders I've moved the river to places where the flux is low and there wouldn't normally be a river.  So I need to fix how forests detect rivers to a method that looks at the actual river paths.
With that in place, the forests now properly edge back from the meanders.

That's a good stopping point for now.  Next time ... well, I'm not sure what, but don't expect weekly updates as in the past!