Tuesday, October 16, 2018

Sprucing up the Rivers

There are a few problems with the way Dragons Abound draws rivers, and in this posting I'm going to try to fix up some of them.

First of all, I realized recently that I'm still drawing rivers using SVG lines, and changing the width of the river by adjusting the width of the line.  In extreme cases this can result in some odd effects:

And in fact, I've had to add code to avoid these kinds of situations.  But some time ago, I implemented a different way of drawing lines that lets me smoothly vary the width of the line any way I'd like.  But for some reason I'd never switched over rivers to using the new line routines, so let me do that and see whether it improves the river visualization.
Here's a side-by-side comparison with the old version on the left and the new version on the right.  If you look carefully you can see that the transitions are smoother and more natural in the new version.  This is most noticeable in places like the fork where there are some sharp changes of direction.  With the new version, I also have better control over the quality of the path drawing, so I can vary it between smooth and rough as I desire.

That's a small improvement, but the real reason to switch to the new lines is to address the starts (and ends) of rivers:
Rivers start in the mountains and flow downhill to end at the coast.  As you can see in this screenshot, the start of the river is pretty abrupt.  It just starts at a minimum width, and if the river has an outline (as in this example), the outline is missing across the start of the river.  (Rivers have a minimum width to avoid having rivers that are nearly-invisible thin lines.)  This is largely an artifact of the old way of drawing the river, and would have been annoying to fix.  With the new river code, though, I can just set the initial width of the river to zero, so that the river starts with a point:
That works, but looks a little pinched off.  Let me try phasing in the river over the first part of the river:
Now the river starts at a point and then gradually increases to the minimum width.  That looks much nicer.

Another problem area is at the mouth of a river where it joins the sea.  If the land has an outline then it cuts off the river, as you can see in the map above.  I don't think that looks very good, but it's a problem I also see on a lot of my reference maps:
If you look at the river right below the city of Avinnor at the top of the map, you'll see the land outline goes right across the mouth of the river.  So this is something people struggle with too.

The obvious fix would be to draw the river on top of the land outline.  The problem with doing this is that it is hard to end the river exactly where the ocean starts without leaving a gap or an overlap.  So to avoid this, I have been drawing the river a little long and then drawing the ocean on top of the river.  This eliminates any potential gaps.  For similar reasons, the land outline needs to be on top of both the ocean and the land.  So I cannot put the river on top of the land outline without causing a problem where the river meets the ocean.

One solution is to mask out the land outline where the river crosses it.  This is fairly straightforward -- I just need to draw the river a second time in black into a mask, and then apply that mask to the land outline.  If the river has a black outline like the land outline, this works pretty well:
The transition is more abrupt than I'd like, though.  I can address that by broadening out the river where it joins the ocean.
That looks pretty good.  It looks even better when the weight of the coastline is closer to the weight of the river border:
I see a similar treatment on a lot of my reference maps:
Unfortunately, it doesn't look as good when the outline color of the river doesn't match the outline color of the land:
What I'd like to do in this situation is start the river outline as the same color as the land outline and then use a gradient to transition to the river outline color.  Unfortunately, that's not easily done as SVG doesn't provide gradients that follow a path.  There some ugly workarounds, but I'll leave that for another day.

As I discovered while working on the Tolkien-style map, this approach to drawing the river mouth turns out to be exactly backwards for a style which uses a solid black river:
Masking out the coastline at a river mouth with a black river ends up creating an unnatural gap.  In this case I want to turn the mask off and leave a solid coastline.
Dragons Abound has many ways to style every part of the map, and that creates lots of edge cases to make things look good!

There's at least one more improvement I'd like to make to rivers, but I'll leave that for another time.


  1. Hi. When, if, you ever release this program will it be possible to load a pre-existing map into it and use the label placement functions on that map? I'd happily pay for some automatic map labeling because I'm working on a pretty huge map with hundreds or even thousands of named villages and other features.

  2. That would be pretty challenging, but an interesting idea. I'll keep it in mind!