Saturday, July 28, 2018

The Naming of Places (Part 10): Towns (continued)

In the last posting, I covered a number of ways to generate town names:
  1. An invented name plus a word for “village," e.g., “Schen Village"
  2. A descriptive natural feature, e.g., “Blue Hill" or “Apple Woods"
  3. An invented name plus a suffix for “village," e.g., “Schenley"
  4. A city base name plus a suffix, e.g., “Woodford," “Hollyville"
That produced a pretty good mix of names, but there are a few other variants I want to add.

Many towns are named after people.  Variant #3 above is a version of this, where the name is invented.  But it would also be nice to have a scattering of “real names" or at least some typical medieval English names.  In medieval times most people were identified by first name, and towns reflected this, e.g., James-town, Louis-ville, etc.  I put together a list of about 500 common medieval first names (both female and male) and made a rule to combine them with the town and city suffixes.  This gives me names like this:
Michaelview
Athelinaley
Deniseview
Owenside
Margeryton
Celestriaton
Castortown
Constanceton
Orellason
Ralphdale
Some of these might seem a little unfamiliar, but for the most part they seem like reasonable town names.

The next variant is to take a descriptive natural feature name and run the words together, e.g., “Blue Hill" become “Bluehill".  This is just a matter of leaving the space between the words out and forcing the second word to be lower case:
Bestmarsh
Firstcanyon
Superiororchard
Desertedwasteland
Beguilingquarry
Emeraldspur
Pearlmoorland
Ivoryheath
Earlyspur
Youngsaddle
Cloudychasm
Wetneck
Quietbrake
About half of these are not too bad -- “Wetneck," “Earlyspur," “Bestmarsh" and a few others.  For some, the words don't match up very well, e.g., “Beguilingquarry".  “Desertedwasteland" is actually a good match, but just seems too long and labored to really be a town name.

However, I won't normally be using these words directly.  Instead, I will feed the two word names (e.g., “Early Spur") into a process of linguist drift that will mimic the sort of shortening and word changes that could turn a descriptive name like “Pearl Moorland" into “Pearlmoorland" into “Pearlmoor" into “Pearlmore" and finally into “Perlmore."  I'm sure there are many sophisticated models of linguistic drift, but my approach will be rather more adhoc :-).

The first step will be to reduce the longer word combinations by dropping some syllables.  To do that, I need some code to break words into syllables.  This is a little bit of a problem.  There are a number of Javascript packages to hyphenate words, but since you can't hyphenate at every syllable (e.g., you can't hyphenate the word “ivory" between the first and second syllables) that doesn't help much.  There are also a few packages to count syllables that seem to work fairly well, but they don't actually break the word down into syllables as they count, so that's not much help.  The best I found was the fairly simple and short nlp-syllables, although it makes mistakes:
Safe Mink (Safe-Mink)
Normal Bull (Nor-mal-Bull)
Lucky Hollow (Luc-ky-Hol-low)
Twin Hill (Twin-Hill)
Remote Plateau (Re-mote-Pla-teau)
Loose Ditch (Loose-Ditch)
Garnet Onion (Gar-net-Onion)
Busy Spur (Bu-sy-Spur)
Hidden Hedgerow (Hid-den-Hed-ge-row)
Weary Lagoon (Wea-ry-La-goon)
The idea will be to trim any combinations that are greater than 3 or 4 syllables.  I will do this by removing syllables from the middle, i.e., from the end of the first word or the beginning of the second word.  So trimming “Lucky Hollow" to three syllables and combining the words would give me either “Luckylow" or “Luchollow."  “Remote Plateau" would become “Replateau" or “Remoteteau."  It also works pretty well to sometimes trim from 3 to two syllables:  “Normal Bull" to “Norbull", “Busy Spur" to “Buspur" etc.

My current setting trims phrases to 2 syllables 25% of the time, 3 syllables 50% of the time, and 4 syllables 25% of the time:
Stony Bog (Sto-ny Bog)
   Stonybog
Merry Landslide (Mer-ry Lan-dsli-de)
   Merryde
Paltry Magnolia (Pal-try Mag-no-li-a)
   Paltrya
Key Quarry (Key Qu-a-rry)
   Keyarry
Jasper Foothill (Jas-per Foo-thill)
   Jasthill
Tourmaline Peak (Tour-ma-line Peak)
   Tourpeak
Magenta Snake (Magen-ta Sna-ke)
   Magenke
Burgundy Volcano (Bur-gun-dy Vol-ca-no)
   Burcano
The results are interesting.  It's not exactly what I expected, but the names have a good sound to them.

I sometimes get long single word city names as well, usually when the fantasy language generator spits one out.  I've done something similar to reduce the length of long single word names as well:
Shortened Reslonley to Resley
Shortened Gundreawood to Gunwood
Shortened Branwyneton to Branton
Shortened Bramblside to Bramde
Shortened Wrongfile to Wronle
Shortened Regsetken to Regken
Shortened Memkenfield to Memfield
Shortened Setslenti to Setti
Shortened Sutanken to Suken
The algorithm maintains the first and last syllable and randomly removes syllables in the middle of the word.  The result is often quite different from the original word, but if you squint can often imagine the name getting shortened that way.

Sometimes shortening words results in some wrong or unlikely spelling, like having three of the same letter in a row.  To address these sorts of problems, I created a small dictionary of regular expressions that are used to fix these problems.  Each entry is a regular expression to match in the word, and then a substitution for the match.  The entry for triple letters looks like this:

// No tripled letters
[ /([a-z])\1\1/, '$1$1' ],

This is a list in which the first element (enclosed in slashes) is a regular expression to match in the word, and the second element (enclosed in single quotes) is the string to substitute.  I won't provide a tutorial on regular expressions here, but the regular expression above matches any letter that appears three times consecutively, and then the string replaces that with the matched letter two times in a row.   Here are some examples of these rules being applied:
Applied rule to change Timrardan Castle to Timardan Castle
Applied rule to change Raenmeton to Ranmeton
Applied rule to change Plebmetittown to Plebmetitown
The first rule gets rid of hard-to-pronounce r-vowel-r patterns, in this case, the “rar" in the middle of the name.  The second one replaces “ae" with “a", and the last one gets rid of the awkward doubled t caused by adding -town to a word ending in a t.  Some of these are obviously a matter of taste, but I've picked a small set of rules that I think improves the readability of the city names.

The last set of modifications makes more substantive changes to the names.  I only do this to 25% of the names.  Some of these modifications try to give a “medieval" feel to the word, such as by adding an “-e" to the end of a word, e.g., “Memfield" to “Memfielde".  Other modifications randomly swap sounds, e.g., “Bududu City" to “Buwudu City."   Here are some examples:
Modified Tiunchin Manor to Tiufin Manor
Modified Shamsland to Shamslande
Modified Oranfore to Ozanphore
Modified Rare Cut to Rale Cutte
In the first name, “f" has been substituted for “nch".  (When substituting vowels or consonants, the rules always replace a string of vowels or consonants.  This prevents a substitution into the middle of a sound, so you never get something like “nch" to “njh".)  The second example has had an “-e" added at the end.  The next two examples have had multiple modifications.

At this point I have about 20 rules that fix names, and about 50 rules that do linguistic drift of one sort or another.  I'll use these for a while and see how I feel about the results.

The next thing I want to tackle are related city names, such as “Hampshire" and “New Hampshire" or “Virginia" and “West Virginia."  My approach is pretty simple.  When I'm naming a city, there's a small chance I'll name it after a nearby city.  If that happens, I'll pick the nearest city as a namesake and then create either a directional name or “New/Old".  The only slightly tricky aspect is that the namesake city might not actually be named yet.  To avoid that problem, I'll actually do this check as a second step -- I'll name all the cities as normal and then go through to see if I want to create any namesakes.

This happened during an early test run:
The city on “ke Te Island" got named after a town that had been named after a town...  I realized that I don't want to have multiple namesakes from one town (I don't want “North Goton" and “Old Goton" as well) and I don't want to create a namesake from a namesake.

Another useful constraint is to set a maximum distance between a city and its namesake.  It seems odd to have “North Goton" be on the opposite side of the map from “Goton."  A distance of about 1/5 of the map seems to work fairly well as a limit.

Finally, another version of related names is to name a city on an island after the island, so that you get “Gonlo City" on “Gonlo Island."  I've added a rule for that as well.

Sunday, July 22, 2018

The Naming of Places (Part 9): Towns

I'm now going to turn my attention to naming towns.  The toponymy of city names is quite different from landscape features.  Geographical features in English typically have a descriptive name or phrase and end in an identifying noun (e.g., “Black Mountain," “Black Bay," “Black Point," etc.).  Less often, geographical features combine a proper name and an identifying nount (e.g., “Aberdaron Bay," “Zahn Point", etc.)  Town and city names are somewhat the reverse -- there are many proper names (“Chicago," “St. Louis," “Denver") and fewer descriptive names (“New York," “Long Beach").  In addition, town and city names don't usually end in an identifying noun (although it does happen e.g., “Oklahoma City," “Greenwich Village", etc.) but many of them do end in suffixes that mean town, village or some variant, e.g., -ton, -ville, -boro, etc.

On the other hand, although it seems like there are lots of proper city names, it turns out that many of them aren't really proper names at all.  To our modern ears, many English town names sound like proper names, e.g., “Ripley," and “Aldwark."  But in fact “Ripley" is a combination of “ripel" (Old English for a strip of land) and “leah" (Old English for a forest), and “Aldwark" is “ald"  (Anglian for old) and “weorc" (Old English for a fortification).  As you can see with “weorc" becoming “wark," over the years the language and spelling drifts until the original words are hardly recognizable.  The names lose all their underlying meaning and really do just become proper names to us.

Another factor is that towns have many names borrowed from other languages.  This is particularly evident in the United States, where names borrowed from Native American languages are ubiquitous -- “Chicago" (from the Miami-Illinois word for wild onion), “Appalachia" (from the Alpachen village in Florida), “Mississippi" (from the Ojibwe word for Great River), and so on.  But in England there are many names from Danish, French, Celtic and other languages.

Cultures also affect city names -- US names are different from UK names and both are different from French names.  Part of this is the difference in underlying languages, of course, but there are cultural factors as well.  For example, the suffix “-ville" was rarely used in the US until after the Civil War, but never became very popular in England -- where they have a less friendly history with France.

So there's a lot of room for creativity in naming cities, and in particular some interesting opportunities to tie culture and history to city names.  This is probably an area I'll be able to revisit many times in the future, but for now I want to get a basic naming capability in place.

I'll aim for generating a few different sorts of city names:
  1. An invented name plus a word for “village," e.g., “Schen Village"
  2. A descriptive natural feature, e.g., “Blue Hill" or “Apple Woods"
  3. An invented name plus a suffix for “village," e.g., “Schenley"
  4. A descriptive natural feature run together, e.g., “Bluehill" or “Applewoods"
  5. A descriptive natural feature run together plus a suffix, e.g., “Bluehillton" or “Applewoodsly" 
For the first version, I need a list of synonyms for “village."  If I analyze my corpus of US and UK city names for the top synonyms for “city" that are used in names, I get this list:
estates: 8456
corner: 3933
acres: 3809
village: 3509
place: 2273
city: 2228
junction: 2162
manor: 1990
crossroads: 1808
corners: 1807
center: 1326
terrace: 1193
court: 1128
station: 854
town: 639
colony: 411
square: 363
castle: 92
commons: 84
hamlet: 54
I've edited out anything that wasn't a synonym (e.g., “heights") and some that were obviously unusable on a fantasy map (e.g., “subdivision").  A few that I've left in are pretty dubious -- I think of “estates" as a faux title to dress up an otherwise vanilla neighborhood with pretensions of style, but it's interesting that it is so popular.  (But I probably won't use it.)  It seems like it also might make sense to distinguish large cities from small villages -- words like “city," “court," “manor," and “castle" don't sound like they'll work well as village names.

In the end I have these synonyms for village:
Corner [3933]
Village [3509]
Place [2273]
Crossroads [1808]
Town [639]
Square [363]
Commons [84]
Hamlet [54]
and these synonyms for cities:
City [6228]
Manor [1990]
Court [1128]
Castle [92]
I've shown here the weighting taken from corpus data, but I'm usually unsatisfied with that distribution and tweak it extensively.  (I can tell you already I don't want most villages to be named “Corner.")

Here are some examples of these types of names:
Zhalzhul City
Ulil City
El Ir Manor
Dirch Court
Urgal City 
Orur Village
Orilm Town
Zhalb Place
Zirkulp Square
Urnal Town
Next is descriptive names based on natural features, e.g., “Blue Hill" or “Apple Woods."  For this variant, I'll be generating only an adjective plus a noun.  For adjectives I have quite a few from previous names that should work:  colors, weather qualities, etc., and I'll add some specific adjectives for cities.  Likewise for the nouns I can reuse landscape features, animals, fruits, plants and trees, etc.  Here are some example names:
Triple Quarry
Rocky Dale
First Fen
Drowsy Daffodil
Tired Copse 
Sunny Boar
Elegant Drizzle
Real Pony
Obvious Bilberry
Cold Wilderness
The first five are pretty good.  The next five not so much, usually because of a mismatch between the adjective and the noun.  It's hard to avoid a certain amount of that unless you're willing to break your word lists down to a pretty fine grain.  But I can trim out some of the more problematic words as I go along.

For the next type of village name I need a list of the suffixes used to indicate a town or a village.  There are some obvious ones, like “-ton" and “-ville" but there are many more than you might think.  I ran through my corpus of town names and pulled out the most common 3 and 4 letter suffixes:
-ton: 15029 (Abberton, Ripton)
-ville: 13248 (Reubenville, Ridgeville)
-wood: 6800 (Johnswood, Kenwood)
-town: 5230 (Kidtown, Meyerstown)
-son: 4281 (Michelson, Madison)
-ley: 3913 (Pilsley, Abbotsley)
-ford: 3645 (Abbotsford, Landford)
-dale: 3568 (Orangedale, Otterdale)
-land: 3344 (Lapland, Vineland)
-field: 3176 (Whitefield, Northfield)
-ell: 2966 (Nutwell, Tiprell)
-ngton: 2839 (Tissington, Chillington)
-ham: 2673 (Chillingham, Feetham)
-ter: 2604 (Finster, Hanover Center)
-ers: 2437 (Hanville Corners, Leon Corners)
-burg: 2429 (Leonardsburg, Middleburg)
-view: 2248 (Middletown View, Millersview)
-man: 1846 (Millman, Poorman)
-den: 1520 (Virden, Academy Garden)
-side: 1438 (Ambleside, Downside)
-more: 957 (Dunmore, Rossmore)
-well: 1393 (Ruthwell, Alumwell)
-mont: 1276 (Ashmont, Beaumont)
A few of these can be tossed out -- “-ell" is mostly an artifact of -well and -fell, “-ngton" is primarily “-ington" (which is actually a combination of -ing and -ton), “-ter" and “-ers" are artifacts of longer words like Center and Corners, and “-man" comes from towns named after men of some sort.  But it's quite a long list nonetheless.  Wikipedia also has an article on town suffixes (and prefixes) that is interesting and explains the origins of these suffixes.

I ended up with about 34 suffixes.  I can combine invented words with suffixes to generate town names like this:
Rarptown
Gullridge
Chalchall
Che Befield
Chemibdale
Sorbrarpbrook
Cheprarpill
Balkelzhand
Solmibton
Sol Geland
Some of these are pretty good; others not so much.  Mostly the problem is that the invented language is not much like English, so the combination with English suffixes doesn't always work.  I can make this better by tweaking the language generator to create more “English-like" languages.  It actually has a setting for this, but it doesn't work as well as I'd like.  After some tweaking:
Giville
Mukkouton
Dolgiill
Deton
Kouwood
Chokodon
Dolville
Mideland
Daburg
Guwood
These are better, without sounding too much like actual English names.

When I stripped off the suffixes to build my table of suffixes, I was left with about 7000 or so “base names".  To get more realistic town names, I can randomly combine these base names with the suffixes, to get names like these:
Woodford
Hollyville
Potterington
Garmanridge
Greenford
Kileley
Meadowtown
Edgeson
Ridgetown
Stanson
These are generally pretty solid names.  If I turn on all these variants I get a mix of names like this:
Bad Prairie
Bradton
Chaneydale
Cho Village
Davingview
Dotham
Far Hollow
Flat Vista
Gonneogill
Hematite Grotto
Julestown
Kadale
Kawood
Lapo City
Meadowwood
Offenbury
Parishson
Plumham
Proud Plateau
Wallley
This is a pretty good mix (I think), although you can see there are occasional spelling problems where words have been joined together.  More on that next time.

Monday, July 16, 2018

The Naming of Places (Part 8): The Sea

Next up on place names are oceans (or seas).  Currently there can only be one ocean name on the map, and it's hard-coded to be “Chrysalis Sea":
That name was borrowed from one of my reference maps.

The real world isn't much help in naming oceans or seas.  There are only 5 oceans in the world, and only a hundred or so “seas," many of which are actually bays, gulfs and the like.  The thesaurus isn't any help, either.  There are only two synonyms in English for large bodies of water -- “ocean" and “sea."  Even the historical thesaurus doesn't offer any additional vocabulary.  So it looks like I'm on my own.

To start with, I think weather qualities work for ocean names (“The Stormy Ocean"), water qualities (“The Glassy Ocean"), colors (“The Azure Ocean"), directional adjectives (“The Western Ocean"), climate adjectives (“The Steamy Ocean" / “The Frigid Ocean").  On these fantasy maps, the ocean is a place of mystery -- it's the edge of the known world -- so a lot of the mystery adjectives I used for the Lost Coast work here as well (“The Bloodstained Ocean").  Marine animals and seabirds should work too (“Amberjack Ocean" / “Albatross Ocean").  Some miscellaneous adjectives work as well.

Note that the ocean is usually singular on the maps, or at least distinguished, so using “The" with the name seems to work well.  I can also use the “Ocean of ..." form as well.
I went through all my reference maps and collected the ocean names to see how well it matched what I done so far (and to gather new ideas as well):
The Summer Sea
Eastern Sea
Western Sea
Southern Ocean (x4)
Endless Ocean
Eternal Sea
Vast Sea
Trackless Sea
The Great Sea
Black Sea
Silver Sea
Sea of Mist
Frozen Sea
White Sea
Twoways Sea
Ocean of Despair
Salt Sea
Sea of Glass
Sea of Narcissus
Dreamer Sea
Inner Sea
Twilight Ocean
Sea of Frost Ridge
The Jade Sea
The Silent Sea
Sea of Whispers
Chrysalis Sea
Sea of the Great Deep
Sea of Fangs
I'm surprised at how many of these I can already generate.  Here's a list of names generated using the ideas above:
Cormorant Sea
The Eerie Sea
Squid Ocean
The Peridot Sea
Codfish Sea
The Vermilion Sea
Hatchetfish Ocean
The Torrent Ocean
Jaeger Ocean
Sea of Maelstroms
The Icy Ocean
Razorbill Sea
The Dark Ocean
Sea of Cannibals
Oyster Ocean
The Ravaged Sea
Drum Sea
The Unlit Sea
This list seems a little heavy on sea creatures, but overall it seems a good selection. Unlike some of the other place names, I'm not generating any ocean names based upon invented words, but that's something I could easily add if I feel the need.

Generating the directional and temperature-related adjectives is a little challenging.  For something like a point or a bay, there's a pretty-well defined and small area, and the label is going to be close to that area.  But an ocean can stretch across much of the map, and so it's hard to pick a particular spot to serve as the reference point for temperature and direction.  In fact, I really want the temperature and direction to be based on where the label ends up.  So if I have (say) an ocean that stretches all the way from the bottom of the map to the top of the map along the left edge, I can call it the “Frigid Ocean" if I put the label up near the top, and the “Southern Ocean" if I put the label near the bottom.  But I pick the name before I place the label, so there's a bit of a problem here.

One workaround is to use the anchor point I select for the label as the reference point.  The label isn't tied very strongly to this point, but perhaps it will work for temperature and direction.
It isn't obvious, but this is a cold map (you can see some pine trees mixed into the forest), so “The Iceberg Sea" makes sense here.

When I implemented ocean labels I only created the one style shown above -- and angled, slightly curved label.  Since I'm working on ocean labels, I decided to add a couple of other styles.  First, a multi-line label:
And a single-line, horizontal label:
I don't much like this style.  One thing that might improve it is to let the label fall at an angle; that's something I've wanted to look into for some time, so I'll take this opportunity to implement it.

The basic implementation is to provide a range of allowed angles for each label, and let the label placing routine vary the angle along with the position as it is trying to find a good spot for the label.  (None of the evaluation code needs to change, because the criteria for a good placement hasn't changed.)  Generally speaking I will limit straight labels of this sort to the angle range of -45 degrees to 45 degrees.  Anything outside that range becomes hard to read, looks awkward, or is upside down on the map.

With that fix in place, I get this:
The red box here shows the original label placement (basically the same as the final label placement above) and the green dot marks the “center of the ocean" that is an anchor for this label.  The program has found an angle that allows it to slide the label up between the two islands to get the label closer to the anchor.

If I relax the pull towards the anchor point, this happens:
With less pull from the anchor, the label swings the other way and slides below the middle islands.  This is a better placement in some aspects (further away from other labels primarily).  

If I force a sea illustration onto the map, the ocean label will try to create some separation from the illustration, and this happens:
Now the label has swung back up between the islands, but pushed over a bit to stay away from the illustration.

The placement of the anchor point in this example actually isn't very good; it's near the center of the ocean, but too near islands in the ocean.  It would be better to find an anchor point that tries to stay away from land.  Also, it's nice for this anchor point to be close to an edge of the map that is largely ocean, so that the label indicates the greater mystery beyond the edge of the map.
At this point I realized that these are variants of a general case label that can move around, tilt, and have an arc to it.  And while I could always force a particular style by locking down any of those variables, I ought to just write the generalized label that would let the label placement algorithm change the location, angle and arc to try to find the best fit.  

(The exception here is the multi-line label.  SVG doesn't natively support multi-line text, so doing anything beyond stacking up a bunch of centered single-line labels quickly becomes very complicated.  In this case, I don't think multi-line labels work very well for oceans at any rate.)

Much hacking between that last paragraph and this one, but I have the general case working:
In this case, you can see the original label (the olive green outline) was arced upwards and fell partly off the map because the green anchor point is close to the edge of the map.  The final solution is arced downward and moved left and upwards so that it can both fit on the map and still be close to the anchor point (the bright green dot).

If I relax the requirement to stay near the anchor point it moves up and keeps the upward arc:
With that I'll declare victory on ocean labels.

Monday, July 9, 2018

The Naming of Places (Part 7): On Point

Next up in place names are points -- fingers of land reaching out into the sea:
Right now points are given place names from combining an invented word with “Point."  Let's try to improve on that.

I'll start at the usual place and gather some data about how points are named in the real world.  To start with, the common synonyms for “Point":
Point: 12674
Bar: 1123
Neck: 732
Ledge: 702
Rock: 542
Reef: 524
Shoals: 482
Head: 179
Peninsula: 158
Bank: 155
Unlike the other place names I've looked at, the synonyms for “Point" don't have anything like a power law drop-off.  In this case, “Point" is used overwhelming, with only a few other synonyms showing up.  A few other true synonyms show up further down the list:  “Flat", and “Horn" primarily.  There are also a few mountain-ish nouns mixed in; I suspect this is because you also sometimes see a mountain or ridge named “Point".

Here are the common adjectives used to directly describe points:
Long: 233
Middle: 106
North: 101
Indian: 91
West: 75
East: 74
White: 55
Grassy: 36
Big: 35
Great: 35
These are also familiar from bays.  (“Indian" was actually also on the bays list, but I didn't use it for the obvious reason -- doesn't really work on a fantasy map!)  Not a lot of creativity here; most points get adjectives describing their size or location.

One interesting type of adjective I notice is country-related:  American, Spanish, French, etc.  Since I do name countries/regions on my maps, I could conceivable do this same thing.  It looks to me that the rules for creating a “country adjective" from a country name are pretty simple (although there are many exceptions).

Now let's look at the most common nouns used in naming points.
eagle: 83
saint: 71
sand: 70
bluff: 63
oak: 54
birch: 53
tree: 52
neck: 51
goose: 51
pine: 49
Again, like bays, “saint" is a surprisingly popular choice.  In fact, there's a lot of overlap between bays and points -- all ten of these nouns already appear in my name choices for bays.

Finally, let's look at the adjectives used to modify those names:
old: 68
big: 57
lower: 38
long: 37
upper: 34
white: 29
lone: 26
great: 25
black: 22
green: 21
There's a lot of overlap here with both the direct adjectives above as well as the similar adjectives from bays.

My overall conclusion -- which matches my intuition -- is that points get named in much the same way as bays.  It probably isn't a perfect match, but I should be able to reuse most of the naming rules from bays for points.

There are a few bay-naming rules that don't work for points.  Most are just bay-specific vocabulary, like “Deep," but a more complex rule is the one that names a bay after a river that flows into the bay.  This doesn't make any sense for points (which at any rate rarely have rivers).  An alternate rule that does make sense is to name a point after a nearby bay.
On the left side of this map, the bay has been named after the city and the point has in turn been named for the bay.  (!) On the other side of the map, the point has been named directly after the city that is out on the point.

As is often the case, working on this surfaced a number of bugs in the point creation code.  For example:
I'm not sure what I think of naming geographical features after a Chicken Butcher, but the real problem here is the two co-named bays are too far apart.  I also found a number of problems where bays (and points) weren't being detected properly, and some cases where I thought there should be a bay and there wasn't.  I also added in some limits on the number of bays and points that can show up on a map.

I've fixed those, but there are probably still other tweaks I'll have to make for point names.  I'll deal with those as I see problems arise.

Monday, July 2, 2018

The Naming of Places (Part 6): Bay Watch

In the last posting, I mentioned that some of the common adjectives used for naming bays couldn't be applied randomly because they described aspects of the bay that could be determined from looking at the map.  If you name a bay “Big Cove" then it had better look big on the map.  In this posting I'll talk a little bit about how Dragons Abound will try do that.

Dragons Abound doesn't intentionally create bays; instead it identifies them on the coastline by searching for bay shapes.

The green line here on the coast shows a bay being detected.  At this point, Dragons Abound knows the start and end points of the bay, the coastline in-between, the center point of the bay, and the sinuosity.  I can also calculate the area of the bay from the outline.  This is most of the information I need to smartly apply many adjectives.

To start with, I'll look at directional adjectives.  From the location of the center point, I can decide where the bay is on the map.  If the bay is toward the top of the map I can call it  “North Bay" or toward the bottom “South Bay," and likewise for east or west.  Of course, that isn't exactly right for naming.  The map is presumably just a part of the world.  The top of the map isn't necessarily the “North."  And actually, places like “North Bay" don't alwaysget called that because they're in the North, but rather because they're north of some landmark.  For example, a bay on the northern end of a lake is likely to get named “North Bay."  All the same, it will make more sense to the reader if “North Bay" is in the top part of the map.  This also means that if I happen to get a “North Bay" and “South Bay" on the same map, “North Bay" will actually be north of “South Bay!"

I could divide the map in halves and call anything on the top “North," etc., but this would lead to bays just barely above the center of the map getting labeled “North," which is probably bad.  So I'll divide the map in thirds, and anything in the middle third won't be eligible for a directional label.  I can also name the areas that are both “North" and “East" to “Northeast" and so on.  Here's a map with three bays labeled that way:
These all happen to be in the corners so they get the compound names.  Here's an example where the bay falls in the middle third of the map:
If I want to use these directions as adjectives, I can tack “-ern" onto the end of them and then use them as a possible adjective directly on the bay name, e.g., “Northern Bay" instead of “North Bay."

However, directional adjectives don't really work in other phrases, such “Northwestern Bayberry Cove."  The problem is that a directional adjective would only be added to a name like “Bayberry Cove" to distinguish it from a similar location with the same name.  So unless there's another “Bayberry Cove" around, the directional adjective is not really needed.  And that's not likely to happen with my place name generator.

Unless I do it intentionally, of course.

The idea would be to find two bays on the map, give them the same name, and then add directional adjectives to distinguish them.  The directional adjectives in this case are a little different.  Unless we're amazingly lucky, the centers of the two lakes are going to be on a diagonal -- they'll be separated in both north/south and east/west.  So is we use the kind of directional adjectives I used above, they'd always end up “Northeast/Southwest" or a variant.  In this case, what we really care about is which direction has the most separation between the bays.   And then we use “North/South" or “East/West" as appropriate to name the bays.
I might want to only do this with bays that are within some distance of each other, and maybe only with bays that are on the same shared sea.  But for the moment, if I decide to do this on a map I'll just pick the two closest bays.

Now let me move on to another case:  size adjectives.  I can calculate the area of the bay and use that to decide that the bay is big and should be described as “Great" or that the bay is small and should be described as “Little".  Of course, big and little are relative terms; I'll have to try some examples and figure a cut-off size that works well.  I'm helped here that these are supposed to be names that people gave these bays; people are imprecise about things like size, so I don't have to worry too much about getting the cut-off exactly right.
You'll notice I've gotten the synonym “Narrow" on this map.  I could actually calculate the longest and shortest axes of the bay and decide if it was more oblong or round, but I don't think that's really worth it; people will use their imagination to fill that in.

Just as I could use the directional adjectives to distinguish two bays with the same name, I can use size adjectives the same way.  This works much the same way; I pick two bays near each other and call the larger one “Big Dolphin Bay" and the smaller one “Small Dolphin Bay".
Or in this case, Lesser/Greater Tapicer Cove.

Since I'm working with the bay sizes, I also want to distinguish the bay synonyms based on size.  I've generated a couple of test maps where a small bay gets labeled “Gulf" or a large bay gets labeled “Pocket," which is jarring.  So I'd like to divide the synonyms up by the sizes they imply and then use them appropriately.  Here's how I broke down the synonyms:

SmallMediumLarge
Cove [125]Bay [166]Gulf [17]
Inlet [42]Anchorage [83]Basin [8]
Hole [21]Sound [28]Reach [3]
Eddy [13]Bight [14]Refuge [1]
Pocket [8]Bottom [8]Arm [1]
Bend [6]Slough [6]
Neck [4]Gulch [4]
Hollow [3]Lagoon [3]
Prong [3]Wick [2]
Branch [2]Firth [2]
Pool [2]Voe [2]
Horn [2]Gut [1]
Narrows [1]Cut [1]
Gap [1]
Gully [1]
Indent [1]

The numbers in brackets indicate the relative probability of picking each option.  It's long been known that vocabularies follow a power law distribution (Zipf's law).  I don't know if synonym choice follows a similar pattern, but it seems reasonable, and power law distributions seem “natural" to people, so I used a rough power law distribution on the synonyms as well.
Another bit of information I have about bays is temperature.  I can use this to decide whether a bay is hot (“Jungle Bay") or cold (“Arctic Bay").  This works the same way as the other choices.
On this map (which is entirely in Arctic regions), I get “Winter Bay" and “Frosty Basin."

That covers the descriptive adjectives, but there's a similar case I want to implement as well -- naming the bay after a nearby map feature.  In the arctic map just above, both of the bays have cities on their shores.  In these cases, naming the bay after the city makes sense, e.g., “Winter Bay" could be named “Kigil Bay."  This could make sense for other features as well, for example, having a point and a bay with the same name.  But for the moment I'm only going to name after cities.

One tricky aspect of this is that there are often multiple cities on a bay:
In this case, it seems like the bay ought to (usually) be named after the biggest city.  Of course you can imagine situations where the bay would be named after one of the smaller cities, so I'll include that as a (lower-likelihood) possibility as well.
You might recall in my previous posting that I noted that the synonym “harbor" is a little different from the other bay synonyms because it implies that people have created a harbor on that bay.  So when I name a bay after a city, I include the possibility of calling it a harbor, e.g., “Chatgar Harbor."

Finally, I also want the option to name a bay after one of the rivers that flows into the bay.  So in this case:
the bay might get named “Ruzu Cove" after the Ruzu River that flows into the bay.  To do this, I need to make sure that I've named the rivers before trying to name the bay, and then look through the rivers that end in the bay to find the largest named river flowing into the bay.
Now the bay is named after the river.  In this case I've forced all the bays to be named after rivers, but note that the upper bay seems to have a random name.  That's actually the name of one of the rivers flowing into that bay, but the labeling algorithm has decided the river is too small to display that name, so it has been left off the map.

And that about wraps up my current plans for bay place names.  I'll keep adding vocabulary as I have ideas and tweak the probabilities of the different naming options, but that can wait for the future.  A test run with all the possibilities turned on:

Tuesday, June 26, 2018

The Naming of Places (Part 5): At Bay

Now that I have a grammar tool more-or-less working and retrofitted the Lost Coast names to the tool, I'm going to tackle another type of place names: bays.
This picture illustrates how Dragons Abound currently handles bays:  It identifies a stretch of coastline that creates a “pocket" and then attaches a label to the center of the pocket.  Currently the place name is just an invented name from Martin O'Leary's generator plus one of a few synonyms for “bay," such as “basin" and “harbor."  Let's see if I can do better.

I'm going to start out by looking at how bays are named in the real world.  As I did previously with mountains, I'm going to analyze real world naming data to see what kinds of words are used in bay place names.  In my previous effort, I analyzed place names data from the USGS.  Since then, I've discovered another source for real world place names:  geonames.org.   This organization provides a worldwide geographical naming database under a Creative Commons license.  Like the USGS database, names are labeled with a feature class that I can use to extract out all the “bays".  I can then run some lexical analysis on these names to help guide how I create my fantasy place names.

For a first step, I'll run all the names through and look at the last word, which is usually “Bay" or a synonym.  Here are the top 20 results:
  1. Bay: 9482
  2. Cove: 6674
  3. Harbor: 1280
  4. Creek: 904
  5. Bayou: 850
  6. Inlet: 404
  7. Pond: 363
  8. Lake: 302
  9. Arm: 297
  10. Sound: 291
  11. Lagoon: 281
  12. Hole: 228
  13. Canal: 216
  14. Bight: 204
  15. Pass: 169
  16. Basin: 167
  17. Slough: 134
  18. Anchorage: 90
  19. River: 84
  20. Eddy: 59
There is some duplication here because many of the same features appear in both the USGS data and the Geonames data.  Some notes:
  • “Bay" and “Cove" are by far the most common names.
  • “Harbor" is an interesting synonym, because it presumably applies only to bays where people have created a harbor.  For Dragons Abound purposes, this suggests only using it where a city is on the bay.  “Anchorage" also implies a human use to the area, but in that case it doesn't imply a city.
  • “Creek," and “River" are odd synonyms to apply to a bay.  Looking at some examples in Google Maps suggests that these are places where a creek/river empties into a larger body of water and the area has been identified as a bay:

    which I think means I can safely ignore these names for my purposes.
  • Something similar is happening with “Pond" and “Lake"; these seem to be mostly ponds and lakes connected to some bigger body of water.  I'll ignore these too.
In the end, I have about 40 synonyms for “bay", most of which will be used very infrequently.

Next, let me look at the nouns that I have been used in bay names, but not as the last word of the name:
  1. island: 269
  2. creek: 215
  3. lake: 181
  4. port: 180
  5. point: 159
  6. saint: 118
  7. arm: 111
  8. sand: 91
  9. river: 85
  10. goose: 81
  11. rock: 77
  12. mud: 75
  13. mill: 70
  14. harbor: 70
  15. oyster: 64
  16. spring: 59
  17. head: 50
  18. hill: 48
  19. house: 46
  20. beach: 45
You can see some interesting trends here.  There are a lot of bays named after other (presumably nearby) geographical features: islands, creeks, lakes, points, arms, rivers, springs, heads, hills and beaches.  Harbor and its synonym port show up again.  Terms for earth are common:  sand, rock, and mud.  Animals, too:  goose and oyster.  An interesting term is Saint -- many geographical features are named after saints.

I looked at about the hundred most common terms and tried to break them down by category:

CategoryTerms
Geo Featuresisland, creek, lake, point, arm, river, spring(s), head, hill, branch, pond, hole, brook, fork, finger, key, neck, wash, sea, bluff, isle, mountain
Manmade Featuresport, mill, harbor, house, shelter, camp, boat, garden, yacht, castle, fort, town, sawmill, schooner
Personsaint, squaw, king
Natural Itemssand, rock, mud, salt, water, stone, boulder, granite
Animalsgoose, oyster, eagle, fish, deer, turtle, bass, horse, seal, fox, otter, alligator, cow, clam, beaver, mosquito, herring, swan, buck, bird, bull, salmon, pigeon, sheep
Plantswillow, oak, pine, tree, hickory, stump
Mischammock, devils, mile, greens, basin, drum, echo, sunset, tar, winter, paradise, dollar, crescent

Almost all of the terms fall into just six categories.  Of course, as you go further down the list into less common terms they become more diverse, but I can take this as a starting point to elaborate a more complete set of possible nouns to use in naming bays.

It would be nice if there was a simple automated system for elaborating these categories, but there's not.  It's mostly a matter of grunt work to research and capture terms, and to try to decide along the way how much categorization is worthwhile.  For example, to elaborate the “animals" category, I have to go to various websites with lists of animals and decide which ones to include, and whether it is worthwhile to categorize them as land versus sea (yes), whether a “pelican" should go into land, or sea or air (maybe both sea and air?) and whether insects should be included (no).  Eventually I end up with a list of land animals:

AardvarkBushbabyCougarGila MonsterJaguarMule DeerPythonTapir
AnacondaBushpigCowGiraffeKangarooMuskoxRabbitTiger
AnteaterCaimanCoyoteGliderKoalaMuskratRaccoonTortoise
AntelopeCalfCrowGnuLambOcelotRatTurtle
ApeCamelDeerGoatLangurOpossumRattlesnakeViper
ArmadilloCapybaraDingoGopherLemmingOryxRhinocerosVole
Aye-AyeCaracalDogGorillaLionOtterSalamanderWallaby
BaboonCaribouDonkeyGrizzlyLizardOxScorpionWarthog
BadgerCatDormouseHareLynxPeccarySea LionWater Moccasin
BandicootCattleDuikerHartebeestMacaquePigSheepWeasel
BearChameleonElephantHedgehogMarmotPikaSkinkWhale
BisonCheetahElkHippopotamusMartenPlatypusSkunkWildcat
Boa ConstrictorChickenEmuHogMeerkatPolecatSlothWildebeest
BoarChimpanzeeErmineHoney BadgerMinkPonySnailWolf
BobcatChipmunkFerretHorseMolePorcupineSnakeWolverine
Box TurtleChuckwallaFoxHyenaMongoosePorpoiseSpiderWombat
BuckCivetGazelleIguanaMonkeyPossumSpoonbillWoodchuck
BuffaloCobraGeckoImpalaMoosePrairie DogSquirrelWoodrat
BullConstrictorGemsbokJackalMousePronghornStallionYak
CottonmouthJackrabbitPumaZebra

After completing this, it occurred to me that I might like to have a separate list of polar animals, so that I can use more appropriate names when adding bays in cold climes.  So I went back and broke out the list of polar animals.

penguinternmoosenorthern pike
whalewolfmuskoxsalmon
sealcaribounarwhalsmelt
lobsterreindeerptarmiganherring
polar bearerminepuffincod
snow foxstoatsnow goosewhiting
snowshoe harelemmingwalrusflounder

So now in a snowy clime I'll get “Penguin Cove" instead of “Camel Cove."

If this sounds like a lot of work, it is.  But for something like this, a shortcut is not going to produce a good result.  In fact, I'm probably not doing *enough* work on this; a really good solution would capture more semantic information about the words and use that to construct the place names.

An initial pass generates a few thousand possible nouns to use in bay names, and generates names like these:
  1. Swirl Cove
  2. Headrail Gulf
  3. Annihilation Sound
  4. Illuminator Bay
  5. Fool Bay
  6. Silk-Dresser Cove
  7. Monastery Bay
  8. Moneyer Bay
  9. Beryl Bay
  10. Table Bay
You can see that there are some archaic terms in the list that you might not recognize.

A simple extension is to flip a name like “Swirl Cove" into “Cove of Swirls."  Note that in most cases I have to pluralize the noun for this to sound right -- but not mass nouns like “mud" or abstract nouns like “annihilation."  
  1. Shale Bay
  2. Cove of Chamberlains
  3. Bay of Furriers
  4. Gum Bay
  5. Pocket of Nakerers
  6. Rogue Cove
  7. Bushbaby Hole
  8. Mud Cove
  9. Brewer Bay
  10. Orca Cove
Another variation for nouns that represent individual people is to use the possessive, e.g., “Rogue's Cove" or “The Rogue's Cove."  I can also use an invented name for the individual, and I can add a title to that individual as well (as I did when naming the Lost Coast).
  1. Cartier Bay
  2. Oilskin Gully
  3. Viper Cove
  4. Steward Bay
  5. Dolphin's Bay
  6. Purse Maker Bay
  7. Vicar Daedoe's Prong
  8. Catchpole's Bay
  9. Reverend Beedae's Cove
  10. Duednoeb's Cove
Interestingly, it sounds fine to use animal names where individual names work, which is why I get “Dolphin's Bay" above.

Another way to name a bay is with an adjective, such as San Francisco's “East Bay" or “Long Bay" in Myrtle Beach.  To get an idea of what sort of adjectives I can use to name bays this way, I'll go back to my corpus of US and UK bay names and pull out all the adjectives that are used this way (as best I can).  Here's the top ten:
  1. North
  2. West
  3. Long
  4. Big
  5. East
  6. Little
  7. Grand
  8. Middle
  9. Hollow
  10. Indian
  11. Sandy
  12. Horseshoe
  13. Browns
  14. Great
  15. Round
  16. Blind
  17. Flat
  18. Twin
  19. Finger
  20. Blue
Directions are very popular.  (South is missing, but that seems to be a problem with my Parts of Speech classifier not thinking it is an adjective.)  Sizes are also popular: Long, big, little, grand, great.  A little further down are shapes:  Hollow, horseshoe, round, flat, twin, finger.  “Browns" is a little odd; I think that's a possessive with a missing apostrophe:  “Brown's Bay."  At number 20 we get an actual color -- a bit of surprise to me because I thought colors would be more popular.

One note about direction and size adjectives -- I probably don't want to use these randomly.  A “northern" bay ought to be to the north in some way, and “great" bays should be larger than average.  I'll talk about implementing that next time, but for the moment I'll just collect these adjectives and set them aside.
  1. Admiral dem Gen's Bay
  2. Chokeweed Bay
  3. Indigo Pass
  4. Paradise Bottom
  5. Deserted Bay
  6. Pufferfish's Bay
  7. Damnation Bay
  8. Catfish Cove
  9. Quiet Bay
  10. Glassy Cove
I've turned up the frequency to make the adjective names more common, but you see here “indigo", “paradise," “deserted,", “quiet," and “glassy" as examples.

The next option is to use both an adjective and a noun to name the bay, such as “Blue Dolphin Bay."  In this case, the adjective modifies the noun, not the bay, so a different set of adjectives is needed.  In theory, the adjective should be something that makes sense with the noun, but in practice the human mind is so good at conjecturing connections between an adjective and a noun that it's almost difficult to come up with an example that seems totally wrong.  For example, “Virgin Dolphin Bay," “False Dolphin Bay," and “Barbarian Dolphin Bay" are all cases where the adjective doesn't really fit with the noun, but seem like acceptable place names.  I'm sure it's possible to come up with combinations that totally don't work, but my point is that you don't have to be as careful about this as you might imagine.  However, you do have to avoid abstract nouns.  Something like “Blue Infidelity Bay" is nonsensical enough to trigger even the most forgiving reader.

An initial cut at adding these sorts of names gives me (again, with tweaked probabilities) this list:
  1. Sore Brigantine Bay
  2. Imashosh's Bay
  3. Dead Raft Bay
  4. Lone Cedar Bay
  5. Dukdush's Cove
  6. Broom-Dasher Bay
  7. Cove of Hermits
  8. Dukuklen's Bay
  9. Roadhouse Bay
  10. Parson Prong
Here “Sore Brigantine" doesn't make much sense (a brigantine is a two-masted sailing vessel) and “Dead Raft" isn't much better, but I think they would pass on a map.  (“Lone Cedar" on the other hand is nearly perfect.)

That's it for the first part of naming bays.  The lists of nouns and adjectives can be expanded near endlessly, but I have about 3000+ in the vocabulary right now, which makes for plenty of different names.  In the next posting I'll get into some of the less random naming strategies.

Obligatory map shot:
“Limner's Bay," “Elk Bay," and “Penny Firth."


Wednesday, June 20, 2018

The Naming of Places (Part 4): Using a Tool

One thing I learned in working on “Lost Coast" names in the last posting was that treating words as lists of strings is very limiting.  For example, I added some common monster names to the words I was using, and I could use those in various ways:  “The Vampire Coast," “The Coast of Vampires," “The Vampire's Graveyard," and so on.  But I ended up just duplicating those names in different templates.  It would be nice if I had a way to say “Include all the monster words here."  Likewise, I sometimes need the plural form of a word, and I had to add that in manually.  So it seems like it's time to consider using a language generation tool.

One of the main features I need is to pick a word randomly from a class of equivalent words, as for example when I select a word that means “coast."  It would be nice to have a tool that provides built-in word categories that would solve all my needs.  Some tools (like WordNet) provide word classification into various categories, and also provide lists of synonyms.  Unfortunately, these tools usually categorize words by parts of speech (POS), e.g., noun, adjective, verb, etc., which isn't useful for me.

Some tools also provide synonyms, but they're not usable without manual editing.  For example, WordNet synonyms for coast include “seashore" and “lakeshore", neither of which work well in labeling a coastline.  And there's no way for WordNet to know that in this case, “cliff" is an acceptable synonym for coast, even though those words do not mean at all the same thing.  There are shades of meaning in words that are difficult to capture and use in a language library.

So I don't think I'm going to find a tool with built-in categories and synonyms that I can use without modification.  Instead, I'll need a tool that supports creating my own categories, e.g., to be able to say “words to use in labeling a coastline are coast, shore, strand, bank, ... etc."

I also want to be able to weight the choices in these synonym lists to indicate that some choices are more common than others.  Quite a few of the tools I've looked at only support choosing randomly (with equal probability) from a list.  I can work around that limitation by repeating the same word multiple times in the list, but if I want a word to be 100 times as common as another word, that requires a lot of repeats.

Another feature I'd like is for the tool to be able to pluralize (and conversely, singularize) words for me, so that I don't have to enter each word as both a singular and a plural.  I can use this to switch between “The Ogre Coast" and “The Coast of Ogres" easily.  I think there will still be some cases where I have to explicitly indicate a plural or a singular but in many cases I could rely on the tool to create the appropriate plural / singular.

There are also a number of common features I don't need.  I'm not building interactive fiction (IF) so I don't need any facilities for interacting with the user.  Some tools have ways to remember a choice and use the same choice later, so that you can (for example) pick the name “Pete" in one place and then use it throughout a long text.  I can think of some cases where I might want to do this, but in general it's a feature I can live without.  I also don't need to parse text, assign parts of speech to words, or similar input-oriented tasks.

With all that in mind, I think my best choices come down to Tracery and RiTa.

Tracery is focused on text generation, and has a simple, clean format for expressing a grammar and some nice built-in features like capitalization.  On the negative side, it lacks any way to do choice weighting.  (There exists a fork of Tracery that adds choice weighting (and much more!) but it is written in Swift rather than Javascript.)  In fact, Tracery does a “shuffled deck" selection when making choices, meaning it runs through all the choices (randomly) before repeating itself.  Since I want some place name choices to repeat (e.g., I want to use “coast" much more often than “bracks"), this won't work for me.

RiTa is a more general toolkit that provides features like analyzing text, conjugation, stemming, Markov chains, and more.  The grammar format is similar to Tracery, but lacks a number of features (like capitalization) that Tracery provides.  However, it does provide choice weighting.  On the negative side, it's much bigger (about 10x) than Tracery, but it has some reduced versions and I suspect I can make do with the smallest.

For the moment, at least, I'm going to work with RiTa.

Both Tracery and RiTa do generation with context-free grammars.  If you aren't familiar with context-free grammars, they consist of rules that look something like this:
<coast> => coast | shore | banks
This rule means “Wherever you see the symbol <coast>, replace it with the word coast, or shore or banks.'  You can chain these rules:
<lost> => lost | forgotten | accursed
<name> => The <lost> <coast>
Together, these rules say that you generate a <name> by generating the word “The" followed by whatever the <lost> symbol generates and then whatever the <coast> symbol generates.

(The “context-free" part just means that you can only have one symbol on the left side of a rule.)

As you may remember, I can also name a lost coast after a monster, e.g., “The Zombie Coast".  With a grammar, I can now separate out the monster names:
<coast> => coast | shore | banks
<lost> => lost | forgotten | accursed
<monster> => Zombie | Kobold | Orc
<adj> => <lost> | <monster>
<name> => The <adj> <coast>
The <adj> symbol can now expand into one of the synonyms for lost, or a monster name.

Whenever the grammar engine has to make a choice, it chooses randomly among the options.  So in this case, “coast", “shore" and “banks" are all equally likely names.  If we want “coast" to occur more frequently than the other choices we can (in RiTa) add a frequency to the choice:
<coast> => coast[5] | shore | banks
which says (in this case) to pick “coast" five times out of seven.

That works well to intentionally adjust word frequencies, but random choice can cause a more subtle problem.  Consider, for example, this rule:
<adj> => <lost> | <monster>
50% of the time this rule will use a “lost" adjective, and 50% of the time it will use a monster name.  But in my case, I have 325 synonyms for lost, and only 33 monster names!  I really want to pick an adjective equally from that whole pool.  I can fix this by adding a frequency to this rule:
<adj> => <lost>[10] | <monster>
but this requires me to count the choices in each category, calculate the ratios, and keep all this up-to-date as I add new terms and options.  That's error-prone, and gets complicated when there are multiple levels of rules.

These sorts of rules represent composition rather than choice -- we'd really like to have some syntax like
<adj> => <lost> & <monster>
to indicate that the grammar engine should compose the two lists together before choosing.   Neither RiTa or Tracery seem to have this capability.  Maybe I'll add that, but in the meantime I'll use a workaround of defining <lost> and <monster> in Javascript and combining them when I create the rule:
let lost = 'lost | forgotten | accursed';
let monster = 'Zombie | Kobold | Orc';
[...]
<adj> => lost + ' | ' + monster
Apologies for the psuedocode mish-mash, but I hope you understand what I mean.

Another thing I need to do in name generation is to insert the result of a Javascript function call.  For example, I can name a lost coast after some (imaginary) person:
Mesh's Boneyard
In these cases, the name of the imaginary person is generated by Martin O'Leary's place name generator, with a call that looks like this:
Language.makeName(world.lang, 'person')
So if I want to be able to generate a name like this, I need a way to tell the grammar “Hey, at this point go off and execute this Javascript and use the result."  This is called a “callback", and in RiTa this works by enclosing it in backticks:
`Language.makeName(world.lang, 'person')`'s <coast>
There's a lot of  quoting going on there, but the important part is that the call to Language.makeName() is inside backticks.  When the grammar engine evaluates this rule, it knows to pull out that bit of code, run it, and put the result back into the rule.

It turns out that this isn't as straightforward as it looks.  Without getting too technical, every bit of code executes in a context that represents all the other code and definitions around it.  In this case, code was written in one context but gets executed in a different context.  This creates no end of problems.  For example, in the rule above, “Language.makeName" isn't defined in the context where the code actually gets executed, and so the callback fails.

RiTa has a solution for this problem, but it isn't very good.  I patched my copy of RiTa with a better solution (and provided that back to the RiTa authors) so my callbacks work as I expect.

RiTa has a number of ways to actually write a grammar, but I'm using a JSON format.  Here's what the core of the Lost Coast naming rules look like:

     // The Lost Coast
     '<lc1>': 'The <lost> <coast>',
     '<lc2>': 'The <coast> of <lost2>',
     '<lc3>': "The <sailor>'s <negcoast>",
     '<lc4>': "`Language.makeName(world.lang, 'person')`'s <negcoast>",
     '<lc5>': "<noble> `Language.makeName(world.lang, 'person')`'s <negcoast>",
     '<lc6>': "<admiral> `Language.makeName(world.lang, 'person')`'s <negcoast>",
     '<lc>': '<lc1>[10] | <lc2>[5] | <lc3>[3] | <lc4>[3] | <lc5> | <lc6>',

<lc1> through <lc6> are the basic patterns for different Lost Coast names (as described in the previous posting).  In <lc4>, <lc5> and <lc6> you can see callbacks to Martin O'Leary's name generator.  The last rule sets the proportions to use the various forms, “The Lost Coast" being the most common and forms like “Admiral Dyg's Boneyard" being fairly uncommon.

There are a couple of functions I think I might eventually want to use that aren't in RiTa or Tracery.

One is the capability to remember and reuse a name across different runs of the grammar.  For example, I create “Admiral Dyg's Boneyard" I might want to name a nearby rocky point “Admiral Dyg's Folly."  Or if I name a mountain “Black Rock Peak" I might want to name a nearby city "Black Rock Town."  I'm not exactly sure the best way to do this yet.

Another is the capability to adjust the distribution of some terms on a per-map basis.  For example, I might have a distribution for the names of bays:
'<bays>': 'Bay [10] | Cove [5] | Basin [3] | Bight | Estuary'
Mostly I want to use “Bays" and “Coves" and rarely “Bight" or “Estuary".  This reflects the relative proportions of those names on today's maps.  But maybe on this map, bays are mostly called “Bights" and only occasionally other names.  Right now I don't think there's a way to write a “meta-rule" to figure out the distribution within another rule.

Next time I'll start to work on bay names.