// World-generation configuration. The seed is overridden per game; the rest // tunes the shape and populating of the map. export const MAP_CONFIG = { mapSize: { x: 100, y: 100 }, topology: "cylindrical", terrainSeed: 0, // Continents grow from `minContinents` smooth domes rather than a plain // continent noise field. The domes are spread by farthest-point sampling and // the sea level is then found by lowering the water in `seaLevelStep` steps // until exactly that many landmasses remain; `seaLevel` is only the fallback // when the search finds no exact match. seaLevel: 0, // Fraction of the shorter map side used as each dome's radius. There is no // falloff: the domes are simply islands in one ocean, and where a dome // reaches a pole it parts the ocean there. domeRadius: 0.26, // How far the detail noise may bend the dome edge. The field is rescaled to // [-1, 1] per map so the coast stays rough whatever the map size. detailAmplitude: 0.25, // Domes are kept this fraction of a half-map away from the poles, so their // peaks are never buried under the polar ice. domePolarMargin: 0.25, // The detail field that roughens the coastline. `cycles` is how many base // waves span the map width, so the coasts stay ragged on a small map as well // as on the default one; the frequency is derived per map. detailNoise: { cycles: 1, octaves: 8, lacunarity: 2.0, gain: 0.5, }, seaLevelStep: 0.01, // A body of land has to reach this fraction of the map to count as a // continent while the sea level is being chosen, so speckle cannot stand in // for one. minContinentFraction: 0.01, // The share of the ice-free tiles the water search aims to leave as land. // The water is lowered in `seaLevelStep` steps and the level whose land is // closest to this fraction wins; the ocean is then joined into one body, so // the map keeps a single connected sea whatever the continents do. landFraction: 0.6, // A few small islands are stamped into open water after the continents have // settled. They never join a continent or sway the water search, and each is // kept under `minCapitalLandmass`. The count is scaled by map area (so the // small test fixtures get none) and capped at the number of nations, because // every island is a starting island: `pickCapitals` puts one nation on each // before the rest go on the continents. smallIslandCount: 5, smallIslandSize: 30, // A field that chews the small-island rims so they read as ragged coast // rather than as dice. It is coarse enough to grow lobes a couple of tiles // across without splitting the island. smallIslandNoise: { frequency: 0.14, octaves: 2, lacunarity: 2.0, gain: 0.5, }, falloffEnabled: false, falloffStart: 0.55, falloffStrength: 0.6, // The polar ice is exactly `iceRows` rows at each edge of the map, and the // tundra fringes it for `tundraRows` rows more. Fixed bands, so the sheets // take only the most extreme rows and never wander deep toward the equator. iceRows: 3, tundraRows: 3, // A finer field that roughens the coastline on top of the detail noise, and // how strongly it bends the shore away from the smooth dome outline. coastNoise: { frequency: 0.09, octaves: 2, lacunarity: 2.0, gain: 0.5, }, coastRoughness: 0.4, // Third pass: clusters of terrain laid over the plains, independent of the // continent shape so no terrain type follows the landmasses. `coverage` is // the share of the land aimed for and `size` the tiles per cluster (jittered // per cluster). Earlier entries take priority where clusters overlap. terrainBiomes: [ { terrainType: "Mountain", coverage: 0.03, size: 10 }, { terrainType: "Hills", coverage: 0.1, size: 26 }, { terrainType: "Forest", coverage: 0.22, size: 30 }, { terrainType: "Desert", coverage: 0.08, size: 48 }, ], capitalMargin: 2, minCapitalDistance: 8, minCapitalLandmass: 40, // Landmasses and seas smaller than these fractions of the map are smoothed // away, so the world reads as a few big continents rather than speckle. The // thresholds scale with the map, so tiny test maps are left alone. minIslandFraction: 0.0015, minLakeFraction: 0.0015, // How many continents to seed and to keep once the water has settled: the // generator places one dome per continent and searches for the sea level that // leaves exactly this many landmasses. minContinents: 3, connectOceans: true, citiesPerCiv: 10, // Minimum distance between any two cities during generation (never below 5). citySpacing: 5, };