---> Useage <---

Move to the RandomMap directory, and run the command 
"perl ./randomize_map.pl path/xxx.map path/yyy.ran" 

This will create a new .map file, placed in the same directory as the
original. The name of the new .map file consists of the main name of
the original file (the part before the ".map" ending), and underscore
and a theme-specific name.

For instance, "perl ./randomize_map.pl ~/dominions3/maps/cradle.map
DragonSprinkle.ran" will create the file cradle_DragonSprinkle.map
located in ~/dominions3/maps.

---> Making theme files for randomized maps <---

The randomize_map.pl program takes two arguments - the first is the
base .map file to work from, and the second is a .ran file which
contains a description of how to randomize it -- the theme.

The .ran files are rather non-intuitive and can seem a bit strange to
begin with, but they are very flexible and opens up for creating a
great deal of various maps.

The .ran files consists of four different types of lines - _comments_,
_properties_, _name maps_ and _named sets_.

Comments are any line starting with two dashes (--) and any line
containing only whitespace.

Properties is denoted by a hash-sign, followed immediately by a
keyword. If the property takes a value it's written after an equal
sign, as so: "#PropertyName = value"

At the moment, the randomization program recognizes only three
different properties: #RandomizationName, #DescriptionAddition and
#UseSetland. #RandomizationName takes a value, which is the additional
name of the map that is created. #DescriptionAddition also takes a
value - a text string that is appended to the description from the
original map. #UseSetland takes no value, but if this property is
included in a .ran file, the new map will be made with #setland
commands rather than the default #land commands. (At the moment you'll
have to use #UseSetland to prevent the pretenders being killed before
the first turn.)

---> Named Sets <---

Named sets look at first identical to properties, as they start with a
#, have a name and then an equal sign followed by a value. However,
the name can be choosen freely, and does not have to be something
recognized by the randomize_map program. Secondly, the value must be a
valid _description of a weighted set_.

Ignoring the weighted part for now, a set is for this purpose a
collection of unique numbers. Normally, sets are written as a list of
comma-separated numbers enclosed in curly braces. For instance
{1,2,3,4,5} is a set which contains the five numbers 1 through 5, and
the line "#MySet = {1,2,3,4,5}" is a valid named set in a .ran file.

It can quickly become too much work to write out all the numbers that
are part of a set, so we also allow sets to be written with _ranges_
instead of just individual numbers. So the above set can also be
written as {1-5}, and a more complicated set might be written as
{1,8-18,20,75,100-150, 152-160} (Sets do not have to be written with
the numbers in increasing order, I'm only doing that for legibility.)

---> Set operations <---

A set can also be described as an operation on other sets. .ran files
support three different set-operators, namel "U" for set union, "^"
for set intersection and "\" for set difference (or "subtraction"):

The meaning of the union operator is basically that "SetA U SetB"
contains all the numbers from _both_ set A and set B, so "{1,2,3} U
{4,5}" is identical to "{1,2,3,4,5}"

Intersection, on the other hand, means that we only get the numbers
that are in _both_ sets. So "{1,2,3} ^ {2,3,4}" is identical to
"{2,3}"

Finally, set difference means all the numbers that are in the first
set, but not in the second. So "{1,2,3,4,5} \ {2,4}" is the same as
"{1,3,5}"

Several set operations can be strung together, so a line in a .ran
file might look like "#ComplexSet = {1-10} U {15,17,19} U {200-800} \
{678,712-720}" All operations are then performed straightforwardly
from left to right.

---> Using set names in operations <---

Set operations might seem rather pointless at first glance, but as we
can refer to earlier defined sets by name, they quickly become very
useful. In other words, you can write a section of .ran files as follows:

#SetA = {1,19,20-34,78}
#SetB = {6-18,29,78-90}
#SetC = {20,22,24,26}
#SetD = SetA U SetB \ SetC
#SetE = SetA ^ SetB U SetC

This might still not look particularly useful, but when you start to
have pre-defined sets with, for instance, all the cavalry units, or
all the Ulm heavy infantry, you can combine them in logical,
meaningful ways. Look at the example file Horse.ran for how this is
used.


---> Special Sets <---

That's what the sets _are_. As for how they are _used_, things get a
little complicated. Basically, the randomize_map.pl program look for
sets with special names and chooses various values in the map from the
values in those sets. The clearest example is how the program
determines the population-type. At the simplest, when the program
wants to determine what population type to use for a province, it
merely looks for a set with the name "PopulationType", and then
chooses randomly one of the numbers from that set to use. So if you
have the line "#PopulationType = {25,36,37,38}" in your .ran file, all
the provinces in the map would be set randomly to one of either
Barbarians (population type 25), Lizards (36), Woodsmen (37) or
Hoburgs (38).

In addition to PopulationType, the program looks for sets with the
following names (listed here in the order they are evaluated):


Fort - which details which fort to set in a province. "0" means no
fort will be set.

Lab - details if a province will have a laboratory or not. "1" means
yes, "0" means no.

Temple - details if a province will have a temple or not. "1" means
yes, "0" means no.

KnownMagicSiteNumber - the number of known magic sites to add to a
province

KnownMagicSite - the reference number of the magic site (as defined in
the map %MagicSiteNames - see about maps later in this text.) to be
added as a known feature to a province.

UnknownMagicSiteNumber - the number of unknown magic sites to add to a
province

UnknownMagicSite - the reference number of the magic site (as defined in
the map %MagicSiteNames - see about maps later in this text.) to be
added to a province as an unknown feature.

CommanderNumber - the number of commanders that will be added to a
province.

CommanderType - which unit number to use for one commander in a
province

MagicItemNumber - the number of magic items to give to the current
commander

MagicItem - the reference number of the magic item (as defined in the
map %MagicItemNames - see about maps later in this text) to be given
to the current commander.

RandomEquip - which value to set the #randomequip value to, for a
commander

BodyguardType - Which unit number to use for bodyguard for a
commander.

BodyguardSize - The number of units in the bodyguard for a commander.

UnitsNumber - The number of additional squads of regular units that
will be assigned to a commander.

UnitsType - Which unit number to use for one squad

UnitsSize - How many units to use in one squad


---> Constraints <---

On their own, the above sets are a good start, but they're not quite
enough. For instance, if we use "#PopulationType = {25,36,37,38}" as
above, then _all_ the provinces will be set to one those four
populations - including all the underwater provinces. In addition, a
mountain province has as much chance of getting a Woodsmen population
as a forest province has. Similarly, we may want to have one choice of
bodyguards if the commander is a barbarian chief and another choice if
the commander is a hoburg hero.

We need a way to select from different sets depending on what choices
(including terrain) has been done for the current context (i.e. the
current province, or the current commander) earlier. This is done by
adding constraints to the baee name of the set. A constraint is the
name of some feature with the valid values for that feature enclosed
in parantheses. The valid values can be expressed either as a single
number, a set description or the name of a previously defined set.

These "features" are a number of specially defined features that are
related to the terrain in the current province, and also the base
names of the sets the program has already made a choice for in the
current context (i.e. "PopulationType", "Fort", "Temple" and so on.)

To define that a province with a barbarian populatation (pop-type #25)
should always have two barbarian chiefs (unit-type 141) you'll use the
following two lines in your .ran file:

#CommanderNumber_PopulationType(25) = {2}
#CommanderType_PopulationType(25) = {141}

The "PopulationType(25)" is the constraint, and here it specifies that
the previously selected value for the population type in the current
province must have been the value "25".

As constraints can also be sets, or set-names, we can also have lines
such as these:

#AmazonPopulations = {40-43}
#CommanderNumber_PopulationType(AmazonPopulations) = {1}
#CommanderType_PopulationType(AmazonPopulations) = {138}
#CommanderNumber_PopulationType({34,36}) = {1}
#CommanderType_PopulationType({34,36}) = {265}

The above will give every province with one of the amazon populations
a Meduse (unit number 138) as a commander, and a raptor (population
type 34) or lizard (population type 36) province will have a blue
dragon (unit-type 265) as a commander in it.

We can also add several constraints into a set, so we can have, for
instance:

#CommanderType_PopulationType(25)_Fort(3) = {325,349,363,364}

This line basically means that in any province Barbarian (25) province
which has a Wizard's Tower (fort number 3), the commanders will be a
random selection of Master Smiths (325), Garnet Sorceress(349) and
either of the two Enchantress units 363 and 364.

The basic rule is that it is the set with the most fullfilled
constraints (and no constraints that are not filled) that is used for
a selection. If there is two or more sets with the same number of
constraints filled, the selection is made from a union of those sets.

That means that if you have defined the sets

#CommanderType_PopulationType(25) = {141}
#CommanderType_Fort(3) = {364}

and a province is created that has _both_ population type 25 and fort
type 3 in it, the program will select the commander-type from the
union of {141} and {364} - i.e. {141,364}. In other words, it will
choose either a barbarian chief or an enchantress.

The special constraints for terrain that I mentioned earlier is as
follows:

Terrain - the precise, numerical terrain-code for this province.
TerrainSmall - 1 if this province's terrain-code has the "small" flag set, 0 otherwise
TerrainLarge - 1 if this province's terrain-code has the "large" flag set, 0 otherwise
TerrainRiver - 1 if this province's terrain-code has the "river" flag set, 0 otherwise
TerrainMountain - 1 if this province's terrain-code has the "mountain" flag set, 0 otherwise
TerrainSwamp - 1 if this province's terrain-code has the "swamp" flag set, 0 otherwise
TerrainWaste - 1 if this province's terrain-code has the "waste" flag set, 0 otherwise
TerrainForest - 1 if this province's terrain-code has the "forest" flag set, 0 otherwise
TerrainFarm - 1 if this province's terrain-code has the "farm" flag set, 0 otherwise
TerrainSea - 1 if this province's terrain-code has the "sea" flag set, 0 otherwise
TerrainLand - 1 if this province's terrain-code does _not_ have the "sea" flag set, 0 otherwise

So, to set the population type for all provinces, except sea
provinces, you can use a constraint as this:

#PopulationType_TerrainLand(1) = { ... }

And if you want to set a particular population type for all large,
swampy provinces you'll use:

#PopulationType_TerrainSwamp(1)_TerrainLarge(1) = { ... }


---> Set weights <---

I mentioned earlier that randomize_map.pl uses _weighted_ sets, but so
far we haven't seen much of the weights. I decided to leave them for
last, since they'd only add unnecessary complexity over.

Basically, a regular unweighted set is useful enough if you want _all_
the values in the set to be equally likely to be choosen. However,
often we want to make some values common, and others rare. The best
example of this is when selecting forts. If we have the set

#Fort_TerrainLand(1) = {0,1-15,19,21}

every province on land has a chance of getting either no fort (the
value "0"), or any of the land-based castle (the rest of the values in
the set.) However, since every value is equally likely when we make a
pick from the set and there are 17 values that creates a fort in the
province, but only one that doesn't create a fort, we will end up with
about 17 out of 18 provinces having some kind of fort, and only 1 out
of 18 provinces without forts.

To fix this, we add a _weight_ to the value "0", so that it has a
greater chance to be choosen than the other values. Weights are added
with the symbol <xN> where N is an integer value. If we change the set
description above to 

#Fort_TerrainLand(1) = {0<x85>,1-15,19,21}

we assign the weight "85" to the value 0. When we know make a
selection from the set, the value 0 "counts" as if it had been 85
different values, while the other values still only count as one
each. So the chance of getting a fort has now been reduced from 17/18
to 17/(17 + 85) = 17/102 - or roughly 17% The rest of the provinces,
about 83%, will have no forts.

You can also assign weights to a range, or to a whole set, as here:

#SomeSet = {1,2,3,4,5-7<x2>}
#SomeComplexSet = SomeSet U {1,3,9}<x10>

but be careful. The <xN> operator works on every number in the element
to its left, which means that the above is equal to:

#SomeSet = {1,2,3,4,5<x2>,6<x2>,7<x2>}
#SomeComplexSet = SomeSet U {1<x10>,3<x10>,9<x10>}

This is often _not_ quite what you intend, so have a care when using
this.

---> Set weights and set operations <---

The set operations work on set-weights in the following manner:

Union will add set weights if the same number occurs in both sets:

{1,2,3<x5>} U {2,3<x5>,4} = {1,2<x2>,3<x10>,4}

Intersection will yield the _smallest_ set weight for a number:

{1,2<x5>,3} ^ {2<x3>,3<x3>} = {2<x3>,3}

Set difference will remove a number, even if it has a greater weight
in the leftmost operand than the rightmost. I.e.:

{1,2<x10>} \ {2<x3>} = {1} 

and it is _not_ so that {1,2<x10} \ {2<x3} = {1,2<x7>}

The reason for this is basically to ensure that we can be certain that
set difference will get rid unwanted values for a selection, no matter
what the set we remove them from is like.

---> Named maps <---

Magic sites and magit items has to be referred to by name in the .map
files, but the weighted sets we use in the .ran file can only handle
numbers. We solve this problem by supplying a mapping between numbers
and names. It's a little bit cumbersome, perhaps, but it works and it
keeps other things simple.

A named map is declared in the .ran file by a the following syntax:

%MapName = { 1 => "String One", 2 => "String Two" ... }

That is, a percent sign followed by the name of the map, followed by
an equal sign and followed by the definition of the map enclosed in
curly braces. This definition, in turn, is defined as a list of
comma-separated assignments on the form "number => String". The symbol
=> can be considered an assignment operator (read as "maps to"), and
the string must be enclosed in double quotes.

Map definitions extend from the start of the opening curly brace to
the end of closing curly brace, and _can extend over several
lines_. That means that the following is a valid map declaration:

%MagicSiteNames = { 1 => "Whispering Woods",
                    2 => "Canyon of Wild Winds" }

You can define maps with whatever names you like, but at the moment
only two names are recognized by the program, "MagicSiteNames" and
"MagicItemNames". The first is used to convert from the numbers in the
KnownMagicSite and UnknownMagicSite sets, and the latter is used to
convert the numbers from the MagicItem sets.

For an example of the use of named maps (and the magic site and magic
item sets) see DovregubbensHall.ran


---> Word of warning on Magic Sites and Magic Items <---

At the moment, there's a problem with using magic sites or magic items
in constraints. You can do so _only_ if you make a _single_
choice. I.e. the relevant KnownMagicSiteChecks, UnknownMagicSiteChecks
or MagicItemNumber must be set to { 1 }. If it is potentially greater
than 1, you are not guaranteed that the constraint will be read
correctly. This will be sorted out eventually, but for the moment you
should be a little careful about it.
