As I documented in a previous series of posts, I recently wrote a procedural map compass generator. That was partly an experiment in making my code publicly available, so I wrote it as a standalone program separate from Dragons Abound so that it could be more easily used by someone else. (You can play with it here.) Now I'm going to integrate that code back into Dragons Abound.
The first step is to import the libraries used by the compass generator. A couple of these are already used by Dragons Abound. One of these is Nearley, but Dragons Abound is a couple of releases behind the compass generator. So the first step is to switch Dragons Abound to the current version of Nearley and see if that breaks anything. It seems to work fine, at least for the first few test maps I generated.
The second step is to bring all the code into Dragons Abound and see if it will run. In the compass generator, I had a simple function that ran the compass rules and then drew the compass at [100, 100] and size 75 on the test SVG. I need to tweak that function to use the correct location and size for the map. Otherwise the compass code “should" work as is.
But the code immediately dies with rather an odd error, which I trace down to a Compass Description Language (CDL) command that reads:
SPACE(NaN)
A little more tracing and I eventually figure out that the problem is with a utility function called randIntRange(), which is supposed to generate a random integer in the given range. I borrowed that function from Dragons Abound, but in the course of the Compass work, I beefed up that function a bit to take a wider variety of more convenient inputs, like so:
// Random integer in a range. // randIntRange(lo, hi) // randIntRange([lo, hi]) // randIntRange(hi) lo == 0 function randIntRange(lo, hi=false) { if (!hi) { if (Array.isArray(lo)) { hi = lo[1]; lo = lo[0]; } else { hi = lo; lo = 0; }; }; return Math.floor(randInt(hi-lo+1)+lo); };
The flexibility of Javascript isn't always a blessing, but here I'm using it to create a function that takes any sort of representation of a range and “does the right thing." This new version is compatible with the old version, so I just have to replace the version in Dragons Abound with the one from the compass generator.
That fix in place, the next problem is an attempt to set the opacity of the compass. Dragons Abound expects the compass generator to return an SVG element of the whole compass, but in the compass generator project I wasn't actually using the compass SVG for anything so I wasn't returning it. It's simple to tweak the generator to draw the compass in an SVG group element and return that.
At this point the code is completing, but still with errors. Some of these trace back to the size of the compass. The compass generator expects to make square compasses, but Dragons Abound can handle non-square compasses. (Because some of the canned compasses it uses are not square.) This leads to a parameter mismatch, where the compass generator expects to get a single number as the size of the compass, and Dragons Abound is supplying an array of width and height. But in fact, Dragons Abound is providing square dimensions, so the generator can use either the width or the height as the size of the compass.
At that point, I'm finally getting a compass on the map:
The compass is a *little* too big. This is mostly another parameter mismatch; the compass generator is expecting the size to be the radius of the compass, and Dragons Abound expects it to be the total size of the compass. So the compass is twice as big as it should be.
That's better, although still a bit larger than it should be. This image also illustrates another problem -- the compass should be centered on the windrose network. If you look, you'll see that the center of the E and the S are centered on lines. This suggests that the bottom-right corner of the compass box is centered on the windrose network. And in fact, this is another mismatch between Dragons Abound and the compass generator. The anchor point for images (like the canned compasses) in Dragons Abound is usually the lower left corner of the image. For the compass generator, the anchor point is the center of the compass. So for a procedurally-generated compass, I need to shift the center accordingly.
When I wrote the compass generator, I used black and white as the colors. In Dragons Abound, I will also have a dark and light compass colors, but I might want to use some different colors than black and white to better match the map. To do this, I replace all the “black" and “white" color names in the compass rules with “line" for the line color, “dark" for the dark fill color, and “light" for the light fill color. Then before I render the compass, I can substitute whatever color I desire.
Here I replace the white with a subtle cream color to make it work better with the dominant land color: