Added: Initial world generation tool
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"salty/terrain/internal/manifest"
|
||||
"salty/terrain/internal/uplift"
|
||||
)
|
||||
|
||||
// TestBorderIsAlwaysOcean is the boundary condition the whole solve rests on, asserted rather than assumed.
|
||||
//
|
||||
// A cell on the map border is an outlet: `fluvial.isOutlet` returns true for it whatever else is true, so it
|
||||
// takes no uplift and is never eroded, and the repose clamp will not lower it either. Land that reaches the
|
||||
// border therefore freezes at whatever the initial relief gave it while the interior erodes away beneath it,
|
||||
// and what that looks like is a rim of untouched terrain standing a hundred metres over its neighbour — it is
|
||||
// what once reported a 66 degree slope on a map whose angle of repose was 22. `continentMask` imposes a
|
||||
// margin to prevent it, and this test is what says the margin is still doing its job.
|
||||
//
|
||||
// It is worth a test rather than a comment because the margin is easy to break from a distance. The uplift
|
||||
// rate used to be multiplied by the continent mask, so the margin's taper was suppressing uplift at the border
|
||||
// as a side effect; decoupling the two (D-52) removed that, and nothing in the change was anywhere near this
|
||||
// file. The invariant is the border cells themselves, so that is what is asserted; the distances and rates are
|
||||
// reported alongside because they are what a person would want to see when it does fail.
|
||||
func TestBorderIsAlwaysOcean(t *testing.T) {
|
||||
const size = 1400
|
||||
const sideM = 14280.0
|
||||
cell := sideM / (size - 1)
|
||||
|
||||
for _, seed := range []int64{7, 9342, 67914} {
|
||||
m := manifest.Defaults()
|
||||
m.Source.Seed = seed
|
||||
up := uplift.Build(size, cell, m)
|
||||
|
||||
for x := 0; x < size; x++ {
|
||||
for _, i := range [2]int{x, (size-1)*size + x} {
|
||||
if !up.Base[i] {
|
||||
t.Errorf("seed %d: cell (%d,%d) on the top or bottom border is land", seed, i%size, i/size)
|
||||
}
|
||||
}
|
||||
}
|
||||
for y := 0; y < size; y++ {
|
||||
for _, i := range [2]int{y * size, y*size + size - 1} {
|
||||
if !up.Base[i] {
|
||||
t.Errorf("seed %d: cell (%d,%d) on the left or right border is land", seed, i%size, i/size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// How hard the margin is pressing. The margin does not only keep land off the border; where the
|
||||
// continent would have run past the edge it *cuts* it, and it cuts along a contour of distance-to-edge,
|
||||
// which is a straight line parallel to that edge. So a coastline inside the margin band is a coastline
|
||||
// the margin drew rather than one the noise did, and the count is the measure of how much of one there
|
||||
// is. It is logged, not asserted: some is unavoidable and the right threshold is a judgement.
|
||||
band := int(0.04 * size)
|
||||
nearest := size
|
||||
var peakRate, peakHeight float64
|
||||
landInBand, shoreInBand, shore := 0, 0, 0
|
||||
for i := range up.Base {
|
||||
x, y := i%size, i/size
|
||||
d := min(min(x, size-1-x), min(y, size-1-y))
|
||||
if up.Base[i] {
|
||||
// A waterline cell: ocean with land in the four-neighbourhood.
|
||||
for _, n := range [4]int{i - 1, i + 1, i - size, i + size} {
|
||||
if n >= 0 && n < len(up.Base) && !up.Base[n] {
|
||||
shore++
|
||||
if d < band {
|
||||
shoreInBand++
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if d < nearest {
|
||||
nearest = d
|
||||
}
|
||||
if d < band {
|
||||
landInBand++
|
||||
if r := float64(up.Rate.Data[i]) * 1000; r > peakRate {
|
||||
peakRate = r
|
||||
}
|
||||
if h := float64(up.Height.Data[i]); h > peakHeight {
|
||||
peakHeight = h
|
||||
}
|
||||
}
|
||||
}
|
||||
pct := 0.0
|
||||
if shore > 0 {
|
||||
pct = float64(shoreInBand) / float64(shore) * 100
|
||||
}
|
||||
t.Logf("seed %6d: nearest land %d cells (%.0f m) from the border; inside the %d-cell margin, "+
|
||||
"%d land cells, peak uplift %.2f mm/yr, peak initial relief %.0f m; %.1f%% of the shoreline is "+
|
||||
"inside the margin band (a coast the margin drew, not the noise)",
|
||||
seed, nearest, float64(nearest)*cell, band, landInBand, peakRate, peakHeight, pct)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user