Monthly Archives: August, 2016

I Blame GreyKnight

Today GreyKnight tagged me in a G+ post regarding some machine-assisted mapping software by Martin O’Leary (Uncharted Atlas on Twitter).

Well, I say ‘machine-assisted’, but it looks like the software does most of the work.

It’s also frighteningly close to some ideas I explored about fifteen years ago, but Martin made it work much better than I did… and this gives me ideas for how to improve what I’d done, and make it a little more interactive.

Fantasy Map Generator (Terrain 2.0)

Some notes off the top of my head, so I don’t forget.

Original Version

My original attempt was a command line program. Given an an arbitrary height map (TIFF file with elevation ranging from black to white — which mapped to values ranging from 0..1) it would apply many iterations of ‘precipitation’ to discover rivers (and thus watersheds) and lakes/oceans (depressions that filled with water). I was good at finding waterways, I never did find a satisfactory method of finding bodies of water.

There was also an erosion element, where moving water would reduce the elevation along its path. This included a ‘sediment’ component where the eroded material could be dropped if the speed of the water became too low. This would happen mostly when the slope became to shallow or when the ‘water unit’ hit standing water. It didn’t work as well as I’d hoped but I think this was mostly because of my problem finding bodies of water.

The program would periodically render the image in several modes, so I could see what was going on.

  • Bump mapped height map, just the terrain itself. Over time I could see the effects of erosion.
  • Bump mapped colored height map, the terrain with pseudocolored elevation so I could more readily make out the differences in elevation.
  • ‘Water map’ showing the aggregated water flows, optionally with the ‘ocean’ (everything with an elevation under a specified value) filled in blue. This gave me a very good idea of how the water flows were working out. It was very satisfying seeing how, over time, I could pick out where the mountains were by the water flowing away from them.
  • Combined, the colored height map with the waterflows and ocean shown. Because I like the pretty pictures.

New Version

First thoughts on what will be in the new version.

  • GUI (C#/WPF, because that’s what I work with in my day job) allowing adjustments as it goes.
  • Multiple phases in map development:
    • Initial height map. The first iteration will load a greyscale raster image (black = low, white = high) to use as its height map. I might later add a height map generation tool, but that’s lower priority for me.
    • Adjustment layer, so the user can adjust the heights of the original height map nondestructively. I will probably add this after height map generation, since loading the height map from a raster image means the height map can be modified outside this program if needed.
    • Set sea level (which might be below the lowest elevation, if the entire map is above sea level). This should be readily adjustable, but will affect later steps.
    • Find lakes (apply the Planchon-Darboux algorithm), so I know where all the standing water is.
    • Erosion, per my original algorithm. Drop units of water on the terrain, see where it goes. If it hits a lake, go to the exit point of the lake and carry on until it hits the ocean (or the edge of the map). This will find my rivers and watersheds, and will affect the final height map.
      • I might need to find lakes a few times, depending how much effect erosion has. The water leaving the lake should probably erode the terrain as well, and would thus reduce the maximum elevation of the surface of the water. Ultimately it might even wash the lake out!
      • I might go with with a more approximate, but much faster, erosion mechanism. I might even make it configurable which gets used… but I will still need to do the water flow analysis.

That gets me more or less as far as I’d gotten before. Get height map, pour water on it. Now for the next steps.

  • New phases in map development:
    • Settlement. User identifies how many cities (major settlements) and towns (minor settlements) to add. There might be the option of manual insertion (put them exactly where the user says), but for the first pass I’m going to apply them based on rules — mostly around where the water is. Each city or town added will grab the most attractive location available.
      • Initial version will follow Martin’s algorithm, taking into account how attractive the location is (how much water) and how unattractive (how close to another city or town).
      • Later versions might allow weighting these. Perhaps cities want to be far from each other, but towns like to be close to cities.
    • Nations. Assign control (or at least influence) over the territory based on proximity to settlements.
      • It appears Martin assigns control of the territories based on relative proximity to the cities, splitting things as evenly as possible between them. This seems to take the terrain into account, with mountains, and rivers and other waterways, penalizing distance.
      • Martin’s process appears to assign all territory on the map. I am greatly tempted to restrict the reach of each settlement.
      • I might instead give each settlement a certain amount of ‘regional reach’ (first pass, each city is worth this much, each town is worth less) that governs how far their influence can reach. (City, city) regions overlapping are probably either contended or split based on proximity (each point goes to the closer city), (city, town) regions overlapping probably see the town allying with the closest overlapping city, (town, town) probably either stand alone or ally. Allied town regions are counted as part of their ally’s region, extending the reach of a city (or set of towns).
    • National option: iterative assignment.
      • Rather than working on ‘distance to settlement’, each settlement might have a certain amount or number of points of influence. Assign each in turn (proportional to number available, I suspect — if a city has twice as much influence as a town, the city should assign/grab two units of territory for each the town grabs… of course, there are more towns than cities).
      • Each time a settlement grabs territory, it looks for the most attractive location to grab. This is probably a function of:
        • Distance from settlement;
        • Ease of travel (proximity to water is probably a good measure here, easier to follow a river up-valley or follow a shoreline than to cross the mountains);
        • Distance to or amount of neighboring territory of the same settlement (while it is easier to go up-river for a while, eventually the proximity to other controlled terrain makes it cheaper to climb the hill than to follow the river).

I don’t anticipate worrying about names.

Further Adjustments

I expected to have more places for the user to intervene in the map development. Adjusting the height map is the biggest one, but by dropping the need (and ability) to do that there isn’t much left to change. There are some controls involved (how much erosion, etc.) but most of the work after that is done by the computer.

… I started to list other things that could be added, but I think I’ve got enough to start. It would be very easy to get bogged down in additional detail, and I don’t want that to happen. At least, not until I’ve got this part working.

Taxonomy and the Echelon Reference Series

In the last couple of posts it’s pretty clear I was wearing my geek hat. Time to lower the flaps and tie the strings under my chin, because this is going to get busy.

Taxonomy

Echelon Game Design Logo

Echelon Game Design Logo

Straight from dictionary.com:

taxonomy [tak-sonuh-mee]

noun, plural taxonomies

  1. the science or technique of classification
  2. a classification into ordered categories:
    a proposed taxonomy of educational objectives
  3. Biology. the science dealing with the description, identification, naming, and classification of organisms.

Moving to a more abstract representation of the game data means I need some way of identifying what a particular object is. At one point this was done using styles, but now ‘object’ is the only style left related to game objects. I have others for document structure and for certain types of information belonging to objects (the ‘abstract’ styles described in my last post, ‘attribute’ style from the last post, a ‘brief’ style for things like one-line spell descriptions), but these are not game objects.

I have styles in place for type declaration (d20-1-Decl, d20-2-Decl, d20-3-Decl), but what do I put in them? Well, I’m working a hierarchical taxonomy.

Hierarchical Taxonomy

Almost all taxonomies are hierarchical. Biological taxonomy has seven levels (kingdom, phylum, class, order, family, genus, and species), with each becoming more specialized and specific. At any given level, a member of a group is a member of that group’s parent group. For instance, a dog is canis lupus (or canis lupus familiaris, for domesticated dogs)… which means that it is of the canidae family, carnivora order, mammalia class, chordata phylum, and animalia kingdom. It shares characteristics with all canidae, all carnivora, all mammalia, all chordata, and all animalia. These characteristics become a smaller and smaller set the higher you get the taxonomy, but ultimately there are identifiable characteristics shared between dogs and cats (same order, carnivora), and dogs and humans (same class, mammalia), and dogs and sea slugs (same kingdom, animalia).

Game object taxonomy can be similar. I don’t plan to be nearly so rigorous or have so many levels, but having a hierarchy makes many things easier for me down the road.

Hierarchical Parsing

I can take advantage of this when parsing content. Because an object has all types at its level and above in the hierarchy, I can resolve many references I can’t now. Consider the partial hierarchy below:

  • Ability Something a creature can do
    • Feat Learned ability gained using a feat slot
    • Class Feature Ability granted by a class or archetype
      • Class Subfeature An element of a class feature, often chooseable (rage powers) but sometimes not (bardic performance)
        • Class Subsubfeature An element of a class subfeature, sometimes choosable (revelation) but often not (bloodline power, granted power)
          • Bloodline Power Ability granted by a bloodline
          • Granted Power Ability granted by a domain
          • Revelation Ability granted by a mystery
        • Bardic Performance Ability granted by the bardic performance class feature, not choosable but determined by class or archetype
        • Domain Ability granted by the domains class feature (or domain class feature for classes and archetypes that just get one), usually choosable
        • Mystery Ability granted by the mystery class feature, choosable
        • Oracle’s Curse Ability granted by the curse class feature, choosable
        • Rage Power Ability granted by the rage powers class feature, choosable
        • Rogue Talent Ability granted by the rogue talents class feature, choosable
    • Sense Sensory ability; included here as a universal monster rule but I’m not sure that’s appropriate for the taxonomy.
    • Skill Learned ability with variable degrees of expertise (skill ranks)
    • Trait Ability inherent to a creature
      • Character Trait Trait of characters, choosable
        • Class Trait Trait available to characters of a specific class
        • Race Trait Trait available to characters of a specific race [note collision with ‘racial trait’, below; personal peeve]
        • Regional Trait Trait available to characters from a particular region
      • Racial Trait Trait inherent to a race, common to all members of that race
      • Monster Trait Trait inherent to a species of monster, common to all members of that species
  • Magic Non-abilities that do fantastic things
    • Spell Castable magic
    • Magic Item Magic in physical form
      • Magic Armor Physical protection, magically enhanced
      • Magic Quality Magic that can be added to an item
        • Armor Quality Magic that can be added to magic armor
        • Weapon Quality Magic that can be added to a magic weapon
      • Wondrous Item Miscellaneous magic item
  • Affliction Persistent (usually bad) thing that happens to a creature or object
    • Curse Supernatural stuff that happens to a creature or object
    • Disease Illness that happens to a creature or object [O.o for consitent definition… –kjd]
    • Poison Venom or toxin that happens to a creature or object [well, applied to an object, so it affects a creature –kjd]

“Darkvision” is both a racial trait (dwarves have it) and a monster trait (dragons have it). There is also a sense (universal rules) called ‘darkvision’.

In the second and third versions of the Echelon Reference Series, ‘darkvision trait’ could not be readily resolved. I could find ‘darkvision racial trait’ or ‘darkvision monster trait’, but ‘darkvision trait’ did not exist. I also couldn’t find ‘darkvision’ because there were multiple objects with that name.

Under this taxonomy, I am in a much better position.

  • I can now resolve ‘darkvision trait’ because racial traits and monster traits also are traits (specializations of ‘trait’). If I search for ‘darkvision trait’ I find an implied ‘darkvision trait’. That there are two variations (racial and monster) doesn’t matter to me because I specified the ‘trait’ level. If I wanted the racial trait specifically, I would have said.
  • Similarly, ‘darkvision ability’ will resolve at the ‘ability’ level: I just care that you have the darkvision ability, and not whether it is a sense or a trait.
  • ‘Darkvision’ alone won’t resolve. There are traits (abilities) and a darkvision spell (magic). Without something to further identify the target, I can’t tell which is the correct link. ‘Heal’ is another challenging one (skill and spell).
    • I do get some benefit out of implied rules. If I see heal (that is, ‘heal’ in italics), by convention that is the magic heal, the spell, rather than the skill.

This can still lead to ambiguity, and I need to decide what to do. The ghost touch quality resolves to two different concrete items (armor quality and weapon quality) with different characteristics, and I do care about the distinction. Similarly, bane (weapon quality and spell) and spell resistance (armor quality and spell) conflict. I suspect marking certain elements of the hierarchy ‘abstract’ or ‘not implied’ could handle it. That is, while both are under ‘Magic’ for classification reasons, spells and magic items are to be considered sufficiently separate from each other and cannot be equated. For ‘bane‘ to resolve, it must be specifically the spell or the weapon quality (or technically it could be the quality, or the magic item).

Obviously the exact hierarchy will be in flux for a while. I’m still not satisfied with the class feature/subfeature bit.

On further consideration, I think I like the “blocker” possibility. While in many ways the taxonomy holds for many purposes, for some there might be a restriction on climbing the hierarchy for reference purposes. That there is both a “bane spell” and a “bane weapon quality” doesn’t mean there is a meaningful “bane magic”… but they are both still magic for other purposes. Must consider further, this seems very strange in a hierarchy, like it can be a thing without being a thing.

Hierarchical Rendering Rules

The Echelon Reference Series is quite consistent in how it renders game objects. Most often, each game object has a heading (rounded rectangle containing the name) that may have additional elements.

  • A stat block (spells, feats with prerequisites, archetype class features that replace or alter features of the associated class);
    • Because the stat blocks are so long, monsters and characters have a ‘relaxed stat block’: the stat lines are still grouped together, but are not contained inside the heading because it looks really, really bad when it doesn’t fit in the column. Though I think I haven’t had any single stat block fail to fit on a page; I could go full page width and two column within that. Hmm…)
  • a level marker (feats and other character options that have a minimum level derived from level, skill rank, or base attack bonus prerequisites);
  • a type marker (abilities can be (Ex), (Sp), or (Su); abilities might have other types such as (Combat) or (Item Creation) feats; some abilities have special rules, such as rogue talents that modify the sneak attack ability and only one can be applied at once).

Often the only visible difference between objects is color (class features are dark brown, class subfeatures are a medium brown, feats are pale brown). The rendering in documents is otherwise identical. When rendering an object I can take the type and work up the taxonomy hierarchy until I find rules for how to render the object: ‘rogue talent’ and ‘rage power’ are both ‘class subfeatures’ and have no special formatting, so I can fall back on the inherited rendering rules for ‘class subfeature’ when I want to render one of these objects. I might want to render bloodlines differently, so I override the rendering rules for bloodlines and they will look different… and when I add ‘draconic bloodline’ to the taxonomy, it gets rendered the same was as normal bloodlines.

The head of this taxonomy, ‘ability’ (which is ‘something a creature can inherently do’ — includes skills and feats, does not include spells) would thus provide a default rendering mechanism that will let me see the content. It might be very generic, it might be very ugly (I like to make undefined things red so they jump out when I’m reviewing documents — which is why some ‘links’ are red in my PDFs, it means I had identified some text as a link but no target was found, while green means a target was found but is not in this document), but it is presented in the document.

Closing Comments

Building a hierarchy gives me a lot of functionality by letting me ‘inherit’ parsing and rendering behavior, without really adding or changing code. For instance, I can add ‘draconic bloodline’ (child of ‘bloodline’ class subfeature, in the taxonomy) and objects marked as draconic bloodlines will be correctly identified as this kind of bloodline, but still parse and render as normal bloodlines.

I can also use the more more specific taxonomy to change behavior correctly. When I added ‘bloodline’ to the taxonomy it was rendered the same as any other class subfeature, and while that works, I’d like to do something a bit different. I can add code to change how bloodlines are rendered, without affecting other types… except draconic bloodlines, because they inherit this code.

Between the increased abstraction and the use of hierarchical taxonomy, I can get rid of a great deal of complex and redundant code, while making the processing more powerful and specific.