Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#7584) [RFC]: generalizing terrain in mapgen
Home

[Freeciv-Dev] (PR#7584) [RFC]: generalizing terrain in mapgen

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Cc: mburda@xxxxxxxxx
Subject: [Freeciv-Dev] (PR#7584) [RFC]: generalizing terrain in mapgen
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 1 Sep 2004 17:09:18 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=7584 >

We don't really have a plan yet.  But we have the beginnings of a plan.

I speak below in terms of percentages.  Each percentage can be
represented as an integer from [0,100] or as a floating value [0,1] or
as a larger integer [0,1000000].  It doesn't really matter.

The terrain server options are removed.  In their place go:

  landmass : this keeps the same meaning
  wetness : ranges 0 to 100%
  steepness : ranges 0 to 100%
  temperature : ranges 0 to 100%

the question is how to use the last three values.

(Side note: The current model is that the "steep" terrains are just the
highest ones.  While this may not be accurate it, keeping it can't make
things any worse than they are now.)

We already have a height map.  This assigns a height to each terrain
from 0 to 100%.  We also know temperature, which we can access directly
or make a temperature map out of (from 0 to 100%).  We can also make a
wetness map *after* water is placed.  Wetness is affected by height,
presence of water, and temperature.

-----

So we need some way to match terrains up with these values.  Marcelo's
already made a patch that does something along these lines.  But here is
my idea.

For each terrain, we give a range of values:

  [terrain_grassland]
  height_min = 0
  height_max = 50
  wetness_min = 30
  wetness_max = 80
  temperature_min = 30
  temperature_max = 80
  likelihood = 10

Note these are percentage values (except the last one which is just a
ratio).

For each tile, we look at it's height, wetness, and temperature and
consider each possible terrain.  We find the terrain that matches most
closely.  Something like:

  - If there is a single terrain whose values it falls within, choose
that terrain.
  - If there is more than one terrain, choose one at random based on the
likelihood.
  - If there is no matching terrain, choose the closest one.

Another way this could be done is by assigning an "average" and a
standard deviation for each value:

  height = 25
  height_dev = 15

then find the probability that matches the tile.  With a normal
distribution if the height of the tile is 40 that's one standard
deviation off so the chance is 60% or something.  We then multiply
together the probability based on each dimension of matching (height,
wetness, temperature) and multiply the whole thing by the probability of
the terrain.  We do this for each terrain and pick one at random based
on the resulting numbers.

landmass should act as a dividing point.  Ocean terrains are completely
separate from land terrains.  The coastline should be placed at
height=0.  So we end up with heights actually ranging from -100% to
100%.  Thus ocean terrains work exactly the same way but we flip the
height.  Ocean terrains aren't eligible for positive-height tiles and
non-ocean terrains aren't eligible for negative-height tiles (but there
may be the possibility for freshwater inland lakes via some other
mechanism).

So:

- First generate a height_map.  Note that generators 1-5 in principle
only differ based on how the height map is created.  The rest can all be
the same.

- Create rivers.  Rivers start at a high point and flow downward into
the ocean.  Rivers must be created before terrains since the terrain
depends on the water (not the other way around).  If a river can't flow
down it will carve out a canyon (i.e., decrease the nearby height and
keep going) or (potentially) fill up a lake and keep going.

- Create a temperature map.  This is pretty straightforward, except that
tiles close to the ocean are generally milder (closer to average) than
those inland, and high tiles are generally colder than low ones.

- Create a moisture map.  I'm not quite sure how this should be done. 
Probably you want to calculate prevailing wind direction (based on the
location of the equator) and simply calculate how "far" each tile is
from a body of water based on distance and the height of the intervening
tiles.  Tiles with high altitude are drier.

- Place terrains, tile by tile.

Note that the last step is different from the current method.  With the
current method one terrain type is placed on all tiles, then we move on
to the next terrain type.

One thing that isn't accounted for here is clumping.  The current
algorithm has vegetative terrains (forest, desert) clumped.  One way to
do this would be to have a second pass that completely recalculates
everything, but for terrains that clump (which is also a percentage
given in the ruleset) their likelihood is increased by some factor.

Another thing I haven't explained is how the server options come into
play.  These should act to redistribute the values in the maps
(height_map, moisture_map, temp_map) _before_ assigning terrains.  I'm
not sure of the exact math, but I can say that with steepness==50 the
hmap should be unchanged, while with steepness==100 the hmap should end
up entirely at its maximum while with steepness==0 the hmap should end
up entirely at its minimum.  Presumably all parameters should be at 0 by
default.

Having said all this, I think the first step might be to rewrite gen234
so that they first create an hmap, then use the same terrain-placement
routines as gen15.

jason



[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#7584) [RFC]: generalizing terrain in mapgen, Jason Short <=