Friday, April 20, 2018

Back In the Woods (Part 2): Drawing A Tree

As mentioned last time, I'm in the process of drawing forests on maps by drawing lots of individual trees.  The first step is drawing a single tree.  And the first step of drawing a single tree is drawing the cotton candy / bumpy cloud that represents the ball of leaves.  So how do I draw that?

The obvious place to start is with a circle:
I'm using a function that makes a circle out of line segments.  But as you can see, this routine doesn't close off the circle.  If I fix that and use a curve to draw between the segments, it looks a lot more like a circle:
There's a discontinuity where the two ends meet.  I could fix that, but it isn't necessary for this usage.

I don't want every tree to be a perfectly circular blob, so I'll introduce some random distortion into the circle, by adding random offsets in both x and y to every point in the circle:
That gives me a lumpy, imperfect circle.

The next step is to add bumps to the circle, similar to the bumps on the outside of the forest masses I already draw:
In fact I can reuse the same routine I use for the forest masses.  It takes a polyline (a series of line segments) and replaces each segment with an arc.
Here I've purposely made it blocky so you see how each segment of the circle has been turned into a "bump" which is itself just a sequence of line segments.  Here's a smoother rendition:
For this example I just reused the default forest mass bump parameters.  I might want my individual trees to be more "fluffy" than the forest masses, so I can tweak that parameter accordingly:
And that's the basic approach for a simple tree shape.  If I add some random variation in the number of bumps and the size of the trees I can generate a pleasing variety.  Here's a grove of them at something closer to map scale:
That's a good start, but it's a little repetitive.  Next time I'll look at adding more variety to the basic shape.

Monday, April 16, 2018

Back In the Woods (Part 1): Introduction

Dragons Abound currently illustrates forests on the map by drawing a large mass with fluffy edges and bumps inside, as in this example:
Another approach to illustrating a forest is to fill the area with individual tree symbols.  Here's an sample of that from one of my example maps:
Tree symbols like these fit well on maps where the rest of the representation is also symbolic.

Usually mapmakers have a small number of different tree symbols to provide some variety.  If you look closely at this sample you can see that although it looks varied, there are only 4-5 different tree symbols.
 But sometimes just one symbol is used:
I don't really like this approach, but it can look okay when the symbol is tightly packed and forms an overall texture.

Sometimes map-makers use different symbols to distinguish temperate forests from alpine forests and swamps:
In this example you can see that the map has fluffy trees, pointy trees and trees mixed with plants in the swamps.

The usual approach for the tree symbols is a stylized tree shape with some rudimentary shading and a line to indicate a trunk, sometimes with a shadow underneath the tree.  But some map-makers use simpler symbols, sometimes no more than a rough brush stroke.
Over the next series of blog posts I'll work on implementing this style of forest illustration in Dragons Abound.  Obviously I'll be procedurally generating the individual trees, and I intend to tackle both deciduous (fluffy) and coniferous (pointy) trees.

Monday, April 9, 2018

Parameter Management

Dragons Abound  is controlled by a long list of parameters implemented as properties on a Javascript object.  At the moment there are about 2000 of these parameters.  There is a Javascript object that holds the world generation parameters, and another that holds the map generation parameters.  The start of the map parameters object looks like this:
var defaultMapParams = {
 // SVG rendering mode
 renderingMode: 'crispEdges',
 renderingMode: 'optimizeSpeed',
 // Color parameters
 colorsUseGrayScale: 0.10, // 10% of maps?
 colorsUseDesaturation: 0.20, // 20% of maps?
 // Saturation Range
 colorsSatRange: [.50, .70] ...
There are various problems with this approach -- finding a specific parameter in 2000 parameters isn't particularly easy, for instance.  One problem is that I often want to use a particular configuration of parameters for a run.  For example, I might want to use the parameter settings that product a map that looks like the "Skies of Fire" map:
This requires setting 186 values.  Obviously, it is impossible to do that by hand -- and then remember the default values to change them back!

My solution to that was to create something called “styles".  A style is just a set of parameter values that can be used to override the default values.  So I have a style for “Skies of Fire", which starts out like this:
  sof: {
     landPatternChance: 0,
     colorsWaterForce: [240, 228, 218],
     colorsLandForce: [225, 205, 182],
            forestMassShowChance: 0,
     oceanPatternChance: 0...
So when I want to generate a map in the “Skies of Fire" style, I just set the map style to point to the “sof" parameter values.  The first thing the program does when it starts up is look up the style and then copy all those values on top of the default values.

That worked pretty well for a while, but it soon became apparent that it would be helpful to have multiple styles.  For example, I have a style called “bestLabels" that sets parameters for the simulated annealing algorithm that places the labels to take longer and try harder to find good label placements:
      bestLabels: {
            saEnergyFactors: [500, 1000, 2000],
            saLabelQuality: 5000
      },
To make a map in the “Skies of Fire" style with the good label placement, I need to use both styles.  So I modified start up to look for a list of styles and copy them one after the other onto the parameter object.

A problem with this approach popped up when I started generating city icons.  One feature I have in city icons is to use different styles of icons for different countries.  But when I apply a “city icon style" by copying it into the parameter object, I wipe out all the default values on the object.  The when I switch to a different style, I have a problem if a parameter is left at the value for the first style instead of being reverted back to the default.  The problem is actually worse than that, because sometimes I want to generate one house out of the icon in a different style.  It became clear that I needed a way to temporarily change parameters.

My solution was to create a function called getProp() that takes a list of parameter objects and looks through them in order to find a value for a parameter.  Thanks to the Javascript spread syntax , it's easy to write a pretty flexible function to do this:
function getProp(name, ...sources) {
 // Looks through the sources in order to
 // see if we can find a value for name
 for(let i=0;i<sources.length;i++) {
     if (sources[i] &&
         sources[i][name] != undefined) return sources[i][name];
 };
 return null;
};
Rather than destructively copying a style onto a parameter object, using getProp() I can leave it separate and just include it in the list of sources ahead of the parameter object.  For example, to look for a property first on a roof, then on a house, then on a house style and then on the default parameters, I would call:
const rr = Utils.getProp('ciRoofRatiosPoint', roof, house, mapParams.houseStyle, mapParams);

Unfortunately for me, I didn't implement this approach until I started work on city icons, so it's only used in that part of the code.  Adding it into the rest of the code would seem to be very difficult -- I'd have to find every spot where I look up a parameter and replaced it with a call to getProp().  And frankly, it's kind of ugly to have getProp() all over the place.  However, Javascript is very flexible, and there's a way to seamlessly add this functionality to the parameter objects without having to rewrite all the existing code.

In programming, it's often useful to be able to go back and “retrofit" new behavior onto an existing functionality.  For example, suppose you were storing a person's age as the age field on an object:
     person.age = 100;
The way Javascript objects work, you can set the age property to any value.  But in this case, you might like to modify the behavior of the age property to complain if you set the age to something odd:
     person.age = 'young';
     // Error!
This is a case where you'd like to change what happens when you set the age property.

You can do exactly this with something called Proxy .  Proxy lets you replace an existing function with a new function -- even for some built-in functions like “getting" and “setting" an Object value.  I won't go into all the details, but for my need, the basic idea is to replace the “getting" function on the parameter values to something like getProp().  So when I get a property value by doing something like:
     params.useCountryBorders
or like:
     params['useCountryBorders']
what will actually happen is that the params object will look through a list of styles first, just as getProp() did.  I can even make this recursive, so the styles themselves might look into substyles for a value, and so on.

With getProp() I picked the styles to look through by passing them in as arguments to the function.  (And I could do as many as I wanted thanks to the spread operator.)  When I'm doing something like
     params.useCountryBorders
how will the params object know what styles to look through for a value for 'useCountryBorders'?

One possibility is to use Proxy to add some new functions, such as addStyle() and removeStyle(), and use these functions to maintain the list of styles currently in effect.  However, it's probably easier to keep a list of the styles in a specific property on the params object, e.g., “styles".  So every parameter object knows to look through all the objects on it's own styles property when looking up a property value.  If I want to temporarily use the “tower" style, I can do something like this:
     params.styles.push(towerStyle);
     //  Use params
     params.styles.pop();
I push towerStyle onto the list of styles, do something (e.g., draw a tower) and then pop off the towerStyle when I'm done using it.

Less obvious is that if I implement a Proxy for getting a value off of my parameters object, I have to implement a similar function on setting a value on the parameter object.  To see why, suppose the default value for the showCities parameter is false, and I'm using a style which changes that value to true.  That works fine, and I get showCities as expected.   Suppose I now want to temporarily turn off the showing of cities so that (for example) the underground cities of the dwarves don't show up on the map.  To do that, I set showCities on my parameter object to false.  What happens when I next look up the value of showCities?  Well, because I have a Proxy on the parameter object, it looks into the styles and finds the value of showCities on the style -- which is still true!  When this happens, we say the value on the style object “shadows" the value on the parameter object.

To avoid this, I need to put a Proxy for setting a property on the parameter object as well.  This Proxy looks through the styles and sets the property on the first style where that property has a value.  This way, when I change a property value it won't get shadowed by another value on a style.

As I've described, my approach to parameter management has changed multiple times during development.  The current approach with styles and Proxy() seems to be working well for the moment, but I won't be surprised if I have to change it again in the future.

Monday, March 26, 2018

Recreating a Map Style: Skies of Fire

As part of a series of posts on creating and using city icons, I've recreated the icon style used on the Skies of Fire map:
This map can be seen in its entirety here.  In the next part of the posts on city icons, I'll be placing these style icons on a map, so I thought I'd recreate the Skies of Fire style map in Dragons Abound.

To start, this excerpt shows the base colors for sea and land:
Interestingly, the sea is actually tinted slightly red.  Although there's a grunge texture laid on top of the map, there's no other mottling of the land or the sea, any 3D effects, or any pattern in the sea, so I'll turn those features off.   I can somewhat recreate the grunge texture with a grain filter, although I'm not going to spend too much time on tweaking that.  Normally there is also a forest color, but on this map there are no forests shown.  I don't know whether that's because there are no forests or they're just not shown, but at any rate I will turn off forests in this style.  The pattern of ocean lines is similar to one of my ocean decorations.  Setting these things gets me to here (reference map on top; my map below):
There are a few differences.  The coastline on my map is much thicker, and the ocean lines in my map are based on the ocean color, where they're based on the coastline color on the reference map.  Adjusting the width of the coastline is trivial, but it doesn't look like I have any option to manually set the color of the ocean decoration lines.  Adding that isn't too hard, although interestingly enough I find an error that's been lurking in that code for some time.  Fixing those things gets me to this:

Which is close enough for the basic colors and the ocean scheme.

There aren't many rivers on the reference map, but as it happens their style (black lines with water color in-between) matches the default river style for my maps.  That leaves mountains:
The mountains on the reference map are fairly broad, have rounded peaks and contour hatching in black for shading.  The unshaded parts of the mountains are the background color and don't have snow indicated.  Ridge lines (from the peak along the shadow line) are not drawn, just indicated by the shadow line.  The mountain icons themselves are fairly small in relationship to other map elements.  These can all be set by parameter in Dragons Abound to give this (Dragons Abound mountains on the right side):
Dragons Abound doesn't mark peaks as was done with "Alvent" here but otherwise it's not a bad match.

The Skies of Fire map marks country borders with a color around the country border.  Dragons Abound has a similar option.  There's not much to be done here other than to turn on that option:
There's quite a bit of labeling on the reference map.  I'm not entirely sure what font is being used:
It's probably IM French Canon, although the version used on the Skies of Fire map seems to have some internal glyph details that my version lacks.  Small caps is used for all labels except cities and rivers.  Ocean and coastal labels are in a dark rust color.  The larger labels have black outlines filled with brown, and the capital cities are underlined.  Underlining is the only element here I haven't done before.  It's added using the CSS (or SVG) “text-decoration" style.  Here's what those styles look like in Dragons Abound:
I don't much like the way the underlining looks; it's too heavy and clunky.  However, there doesn't seem to be a lot of control over this in CSS/SVG, and I'm not interested enough to implement my own underlining.  The reference map also stretches out region labels and turns them to fit their regions.  This is something I haven't yet implemented in Dragons Abound.

That's about it for capturing this map style.  Here's the side-by-side comparison:
Reference map to the right; Dragons Abound to the left.  One of the most obvious differences is the red city icons in the reference map, so let me add those in.  I implemented them fairly early in my series on city icons:
Dragons Abound version on the left; original on the right.

Here is a full-size map in the Skies of Fire style (click through to see full size):
To my eye, the icons are a little too intrusive on this map; that might be because of the regional scale of this map.

You might want to compare this to the map at the end of this posting.

Thursday, March 22, 2018

City Symbols (Part 17): Some New Icon Styles

Having recreated some of the icon styles from my reference maps, I'll now work on creating some new styles.

One thing I'd like to try is to create a silhouette style, something like these skylines:
There a couple of ways to do this.  One way is to generate a city icon as normal, and then go through and change the fill and line colors for all the components to black.  Another way is to take the union of all the elements in the icon to create an outline, and then fill that outline.  (And in fact, I already have some of this implemented for the Skies of Fire style icons so that I could put a heavy outline on those icons.)

Of these two choices, it turns out that the second is a little problematic.  One reason is that there are many pieces to the icons:  building fronts, building sides, roofs, roof sides, roof backs, building attachments, flags, bridges, and so on.  Iterating through all of them is non-trivial.  The second reason is that -- in general -- taking the union of two polygons doesn't result in a single polygon.  For example, the polygon representing a flag is connected to the rest of the city by a line.  Since a line doesn't have any width, the union of the flag with the rest of the city results in two polygons -- the city and a separate flag.  Not only would that look a little odd, but I've been trying to avoid having multiple polygon unions, because it makes the code to deal with them complicated.

I might eventually have to deal with unions the “right way" and allow multiple polygons, but in this case I've got an easier alternate solution, so I'll use that.
There are a couple of problems with these silhouettes.  The first is that silhouettes look better with some separation between buildings so that the silhouette isn't just an undifferentated blob.  So let me add more distance between the buildings.
A little better, but icons where the buildings are completely separated like Shimmiid look wrong.  I can fix that by putting a short wall along the base of the icon to connect up all the buildings.  I'll also shrink down the icons:
Which I think looks pretty good.  Of course, I need to be able to color the silhouettes by the territory color.
This looks okay, but it's hard to distinguish some of the colors without making them jarringly bright.  An interesting variant is to add an outline to the icon:
This makes the icons a little more distinct on the map.  I tried reversing the colors as well:
But that doesn't seem very effective to my eye.

Another thing I'd like to try is to make the height of the icon follow a particular shape rather than be determined randomly by the height of the buildings.   And in particular to have a sort of semi-circular icon.
Pardon the poor quality of the illustration, but you get the idea.

To do this, I essentially need a function that determines the height of a building based upon it's position in the icon.  I'd also like to have a little more precision than just 1, 2 and 3 story buildings.  So I'll vary the height of the building as well as the number of stories, so I can get a range of total building height.
For large cities this often works fairly well, although the special fantasy builds can throw it off.

Now that I've written the code to vary the floor height as well as the number of floors, I can add an option for icons to keep adjacent buildings from being the same height.

Sunday, March 18, 2018

City Symbols (Part 16): Custom Icons and External SVG

Another feature I want to support is the ability to use custom icons, e.g., as drawn by a human artist. Here's an example using some simple icons I created in Inkscape:
This works much the same way as the custom texture patterns for the ocean and land.  The custom icons are put into an HTML <img> tag to force the browser to load the image and then an SVG <image> is created which references the same url.  This SVG <image> is then put onto the map.

The advantage of this approach is that it works for any image format the browser supports.  However, there are also several disadvantages.  If I use any pixel-based image format (such as JPEG or PNG) then the image will degrade as the map is zoomed.  On the other hand, if I use a vector-based image format (such as SVG) then zoom will work fine, but I have no access to the actual SVG of the image.  Why is that important?  Well, in a case like the city icons, it would be nice if I could (for example) go into the SVG of the capital city icon and re-color the star so to match the territory color.  (So Shimpes above would have have a green star, for example.)

To do this requires solving a couple of problems.  First, I need a way to load an external SVG file so that I have access to the DOM when the SVG is inserted into the page.  Second, I then need to be able to walk through the DOM and adjust colors (etc.) to fit the map.

As far as loading the external SVG goes, d3 provides a function d3.xml that will help.  XML -- the eXtensible Markup Language -- is a language for creating data files that are easily machine-readable, and SVG is written in XML.  So d3.xml can be used to read and parse SVG files, and actually returns a document fragment that is suitable for injecting into a web page.

Of course, there are a few wrinkles to getting this working.  One is that I currently run Dragons Abound as a standalone Javascript application directly from the file system.  (It loads in the browser as a file:/// URL.)   It turns out that using XMLHttpRequest from a file URL is a little problematic.  There's something in modern browsers called the same-origin policy.   The same-origin policy is intended to keep Javascript from one web page executing Javascript from another web page, since this could be used to do things like steal your PIN number out of your banking web page.  However, same-origin policy is only well-defined for protocols like HTTP and HTTPS.  And in particular, it has never been defined for file URLs.  As a result, browsers can do whatever they want with these URLs.  And they do!  It turns out that Chrome simply forbids any file URL to load any other file URL.  (Whether this is reasonable is a separate debate.)

There are couple of ways to work around this.  The first would be to switch Dragons Abound to run off an HTTP URL.  Technically, this is the best solution.  It would make accessing external resources simple.  The drawback is that it would require me to run a web server on my development machine.  That's not a huge problem -- there are plenty of small, lightweight web servers I could use -- but it's a little bit annoying to have to bring up a web server when I want to work on the program.

Another solution is to start Chrome with the "--allow-file-access-from-files" switch.  This switch is described as "By default, file:// URIs cannot read other file:// URIs. This is an override for developers who need the old behavior for testing."  In other words, exactly what I'm doing.  So that's my solution, at least for now.

Another wrinkle has to do with the contents of the SVG files.  If you open up an SVG file created by something like Inkscape, you find that it's actually a complete SVG:

<svg [...] sodipodi:docname="icon00.svg">
    <defs  id="defs2" />
    <sodipodi:namedview
     units="px" />
    <metadata
     id="metadata5">
        <rdf:RDF>
            <cc:Work
         rdf:about="">
                <dc:format>image/svg+xml</dc:format>
                <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
                <dc:title></dc:title>
            </cc:Work>
        </rdf:RDF>
    </metadata>
    <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0.64906156,-291.10098)">
        <circle
       style="opacity:1;fill:none;"
       id="path4506"
       cx="2.6249902"
       cy="294.37503"
       r="2.4633491" />
        <path
       style="opacity:1;fill:#000000;"
       id="path833"
       d="m 4.9755297,296.6547 [...]" />
    </g>
</svg>

All I really care about in here is that <g> element about halfway down, or maybe only the elements inside that group.  So I could just pull those out.  But I might also need something in the <defs> element, and there are other complications -- this is actually a very simple example.

Happily, it turns out that SVG has no problem including another SVG.  This whole element can just be pulled out and dropped into the map SVG and everything works exactly as we'd like it to.  So I just have to pull the SVG element out of the document fragment returned by d3.xml:

let svgNode = documentFragment.getElementsByTagName("svg")[0];

And then I'm good to go.  Well, almost.  XMLHttpRequest is actually asynchronous, which means I have to kick it off and let it go do the business of loading the external file, and take care not to use it until that has finished.  (Dragons Abound takes long enough to generate the world that this isn't a problem.)   This Stackoverflow answer outlines the basic method for using d3.xml and a callback to read an SVG file, and Mike Bostock (the d3 author) provides a working example here.

Now that I have the SVG file loaded so that I have access to it's structure, I want to customize the icon.  In this case, I want to recolor parts of the icon to match the color of the surrounding territory. Recoloring an SVG element is easy -- I just need to set the 'fill' style to the new color.  The trick here is figuring out which elements within the file I just loaded I should recolor.  I need some way to "mark" elements for recoloring when I create them in Inkscape (or some other way).

One straightforward way to do this is to add an XML attribute to the objects to be recolored, for example, adding a 'recolor' element.  SVG files are text files, so you could do this by opening the icons up in a text editor and manually adding the attribute.  But Inkscape also has an XML Editor that lets you directly edit the XML representation of any object, so it's also easy to add a custom element that way.  Then you can recolor all the marked elements in one fell swoop with something like this:

city.icon.selectAll("[recolor]").style('fill', Color.makeColor(atc));


(Assuming you're using D3 and you've marked elements with a "recolor" attribute.)  Throwing all that in the program gives this:
And voila! the inside of the star icons have been recolored to match the territory color.

This is of limited use for city icons, but the same approach can fix a problem I've had with land and sea patterns.  When these patterns are treated as images, they cannot be recolored.  So to make the patterns work with any color of sea or land, I've made them a partially transparent gray color.  This has the effect of darkening the underlying color, as can be seen in the land hatching in these examples:
But as you can see, this not only darkens the color (changes the luminance) but it also changes the shade of the color (changes the hue) making it grayer.  Recoloring the pattern with a color made from the base color of the land fixes this.
In the example on the right, the land hatching is no longer gray but a darker land color.  It also makes it possible to change the darkness or color programatically.  (Rather than having to create a new pattern image file.)  I'm not sure why I'd want to do that, but I guess it's now an option...

Friday, March 9, 2018

City Symbols (Part 15): Culture Identifiers

I took a nice long break from Dragons Abound during the Christmas holiday, but now I'm back to continue to work on city symbols.  One feature I've wanted to have with my city symbols is to tie them to the city's culture, so that all the city symbols for a particular territory (culture) would have similar features distinct from other cities.

Typically territories are distinguished on maps by colors, and Dragons Abound has options for using colors to display territories or to mark borders, as in this example:
So one obvious feature I can add is to have any city flags be the color of the city's territory.  That's a little bit more complicated than you might expect, but after some refactoring:
Here you can see that Shimpes is flying flags that match its border color.

The flags are a pretty subtle indicator.  In general, I'd like to be able to style the city icons in more obvious ways based upon the territory in which they fall.  By changing building selection, colors, etc., I can make more distinct icons.  So I need to extend the code that varies the flag colors based on territory to vary any generation parameter.

Once that's done, I can pick different colors, roof styles, etc., and generate city icons for different territories that are visually quite distinct:
Eventually, I might tie the city icons to features of the territory's culture.  For example, if a territory is populated by dwarves, then the city icons can be gray to indicate the cities are built with stone.  Another possibility is to use city icons to indicate the merging or splitting of cultures.  For example, if a Culture A conquers Culture B, that could be indicated by making the icons for the conquered cities be a mix of the icons from Culture A and the icons from Culture B.

As is often the case as I work on developing Dragons Abound, I wrote a couple of different versions of icon generation (in the style of Skies of Fire and then Torfani), and then wrote the above code to modify the icon generation based on territories.  At this point, I understood enough to abstract the icon generation into a generic version that can be driven by parameters (instead of having different generators for different styles).  This gives me flexibility to experiment with different styles without having to touch the actual code.  It also means that when I add a new feature (say territory colors) it becomes available for all the icon styles.

For example, here's the Skies of Fire icon style as created by the generic generator, modified to use the territory colors for the building colors (instead of all red as in the original map):
Note that in this version of the map, it's much easier to tell whether Miet belongs to Kiil or to the territory above it.