Land elevation is computed by first placing mountains, then elevating land to fit. Mountains placement is a weighted random sampling. A sector's weight is its distance to sea capped at five and squared. Non-mountain, non-capital sectors get assigned equidistant elevations from 1 up to 97 rounded to integer in an order that depends on distance to mountain and distance to sea, both capped at 5. Mountains get equidistant elevations starting at 98 (see recent commit "fairland: Fair mountain resources"). Capitals get 36. Sea elevation is randomly chosen from a range that depends on the sector's distance to land. The range increases from [-27,-1] next to land to [-127,-1] for distance 5 and up. Without mountains, the result is boring: elevation increases pretty much linearly with the distance from the coast, i.e. each islands is a single cone. With mountains, we get one cone per mountain. The sea sea elevations are basically noise. Worse, it's buggy: mountain placement can place fewer mountains than requested. The weighted random sampling assigns weights even to sectors that cannot be picked (capitals and sectors that have been picked already). When the dice land on such a sector, it instead picks the next one (in island growth order) that can be picked. If there is no next one, the mountain is not placed. This is a fairness issue. Impact varies with fairland parameters. For 60 sector islands with 5% mountains, around one in 10000 islands is short one mountain in my testing. For 10 sector islands with 50% mountains, some 760 out of 10000 islands are short one sector, 80 short two, and five short three. The numbers get worse as spikiness increases. Undocumented misfeature: the placement loop is limited to 1000 iterations, supposedly to catch a runaway loop. Since the loop iterates exactly once per mountain, all this accomplishes it limiting mountains to 1000 per island. When too few mountains are placed, the loop assigning elevations to non-mountain, non-capital decrements elevations below 1. Since Chainsaw 3, such elevations then get mapped to 1, plastering over the bug. We get non-mountain sectors with elevation 1 instead of mountains. Rewrite as follows. Use a simple random hill algorithm to assign raw elevations: initialize elevation to zero, then randomly raise circular hills on land / lower circular depressions at sea. Their size and height depends on the distance to the coast, capped at 3. After a sufficient number of iterations, the resulting terrain has a "natural" look. This is elevate_prep(). elevate_land() then sorts non-capital sectors by raw elevation. The highest become mountains. Sectors get assigned the same equidistant elevations as before, just in raw elevation order. elevate_sea() simply normalizes raw elevation to [-127,-1]. Elevations now show a nice undulating pattern independent of mountain percentage. Implementation detail: replace elev[x][y] by elev[XYOFFSET(x, y)], and narrow the element type from int to short. Takes a fourth the space. Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
56 lines
2.7 KiB
Text
56 lines
2.7 KiB
Text
Creating a planet with:
|
|
|
|
8 continents
|
|
continent size: 30
|
|
number of islands: 8
|
|
average size of islands: 20
|
|
spike: 50%
|
|
10% of land is mountain (each continent will have 3 mountains)
|
|
minimum distance between continents: 2
|
|
minimum distance from islands to continents: 1
|
|
World dimensions: 64x32
|
|
|
|
#*# ...fairland rips open a rift in the datumplane... #*#
|
|
|
|
seed is 1
|
|
placing capitals...
|
|
growing continents...
|
|
growing islands: 1(3) 2(3) 3(3) 4(3) 5(3) 6(3) 7(3) 8(3)
|
|
Only managed to grow 24 out of 160 island sectors.
|
|
elevating land...
|
|
writing to sectors file...
|
|
|
|
# b b # # . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
^ # # # . . . . . % % . . . . . . . . . . . . . . . . . . # # #
|
|
# # # # . . . . . . % . . . . . . . . . . . . . . . . . . . # #
|
|
# # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #
|
|
. # . . . . . . # . . . . . . . . . . . . . . . . . . . . . . .
|
|
. . . . . . . # # . . . . . . . . # # . . . . . . . . . . . . .
|
|
. . . . . # # ^ # # . . . # . . # # # # # # . . . . . . . . . #
|
|
. . . . # # # ^ ^ . . . . # # # ^ f f . . # # . . . . . . . # .
|
|
# . . . . # # e e # # . . . . # ^ ^ # . . . # . . . . . . . # #
|
|
. . . . . . # # # # # # . . # # # # . % % . # . . . . . . # # #
|
|
. . . . . . . # # . # # . . # # # . . . . % . . . . . . . # ^ ^
|
|
. . . . . . . # . . . . . . . . . . . . . . . . . . . . h h ^ #
|
|
. . . . . . . . . . . . . . . . . . . . . . . . . . # # # # # #
|
|
. . . . . . . . . . . . . . . . . . . . . . . . . # # # . . # .
|
|
. . . . % . . . . . . . . . . . . . . # . . . . . # . # . . # #
|
|
. . . % % . . . . . . . . . . . . # # # # # # . . . . # . . . .
|
|
. . . . . . . # . # # . . . . . . . . # ^ ^ ^ # . . % . . . . .
|
|
. . . . . . # # # # . . . . . % % . # # d d # # . . % % . . . .
|
|
. . . . . # # ^ # . . . . . . % . . # # # # # # # . . . . . . .
|
|
. . . . . # ^ ^ . . . . . . . . . # . # . . . # . . . . . # . .
|
|
. . . . # # c c . . . . . . . . . # . . . . . . # . . . # # # .
|
|
. . . . . # # # . . . . . . . . . . . . . . . . . . . # # # . .
|
|
. . . . . # # # . . . . . % % . . . . . . . . . . . . ^ g g # .
|
|
. . . . . . # # . . . . % . . . . . . . . . . . . # # ^ ^ # # .
|
|
. . . . . . . # # . . . . . . # # . . . . . . . . . # # # # # .
|
|
. . . . . . . # # . . . . . . # . # # . . . . . . . # # . . # #
|
|
. . . . . . . . . . . . . # # # # # # . . . . . . . . . . . # #
|
|
. . . . . . . . . . . . . . . # ^ ^ # # . . . . . . . . # # . .
|
|
. . . . . . . . . . . . . . . # a a ^ # # . . . . . . . . . . .
|
|
. # . . . . . . . . . . . . # # # # # # . . . . % % . . . . . .
|
|
# # # . . . . . . . . . . . . . . # # . . . . . . . % . . . % .
|
|
^ ^ # # . . . . . . . . . . . . . . . . . . . . . . . . % % . .
|
|
|
|
A script for adding all the countries can be found in "sandbox/spike-newcap_script".
|