Complete.Org:
Mailing Lists:
Archives:
freeciv-dev:
September 2004: [Freeciv-Dev] (PR#7584) [RFC]: generalizing terrain in mapgen |
![]() |
[Freeciv-Dev] (PR#7584) [RFC]: generalizing terrain in mapgen[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<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
|