Problem
Deserts appear much rarer in-game than intended. The current worldgen does not seem to have a rendering/pass-order failure; the main issue is the shape of desert_mask itself.
data/worldgen/desert_mask.lua currently requires a location to be both sufficiently hot and sufficiently dry, then multiplies both already-selective responses with additional suppression terms:
hot = max(0, (temp - 0.56) / 0.38)
dry = max(0, (0.43 - rain) / 0.36)
desert = hot * dry * nonmountain * patch
The desert surface passes only activate above desert_mask > 0.10. In practice this means moderate hot/dry combinations are damped very quickly, producing small/scattered desert areas instead of broad climatic desert zones.
Example:
temp = 0.70 -> hot ~= 0.37
rain = 0.25 -> dry ~= 0.50
- before mountain/patch suppression:
hot * dry ~= 0.185
A fairly plausible desert climate is therefore already close to the visual activation threshold before the remaining multipliers are applied.
Additional finding: BiomeDef::weight is currently not used by terrain blending
data/biomes.json defines biome weights such as:
- plains:
3.5
- forest:
2.6
- desert:
1.7
- badlands:
1.4
However, RuntimeBiomeTerrain currently stores only the terrain definition, mask field and biome salt. adjustedSurfaceHeight() then uses the sampled terrain mask directly as the blend weight.
Therefore BiomeDef::weight currently has no effect on biome terrain contribution despite being exposed in the registry as a worldgen selection weight.
This should either be integrated with a clearly defined semantic or removed/renamed so the data model does not imply behavior that does not exist.
Desired behavior
Desert distribution
Deserts should remain climate-driven and deterministic, but occupy substantially broader contiguous regions.
Preferred direction:
- keep the existing large-scale temperature/rainfall fields;
- broaden the hot and dry response ranges rather than simply lowering the final pass threshold;
- use a softer combination than a raw
hot * dry product, for example a shaped product such as pow(hot * dry, exponent) with 0 < exponent < 1, or an equivalent smooth response;
- retain mountain suppression so normal deserts do not indiscriminately cover alpine/high-mountain terrain;
- preserve
desert_high_mountains_mask as the separate hot/dry mountain case;
- avoid tiny noisy sand patches. The result should look like large climate zones with soft transition regions.
A reasonable initial tuning target is roughly:
- clear desert cores: ~5-10% of representative large-area samples;
- desert transition / semi-arid influence: ~10-20%;
- badlands remain distinctly rarer than ordinary desert.
These percentages are tuning goals, not hardcoded runtime rules.
Biome weight semantics
Choose and document one of the following:
- Use
BiomeDef::weight as an explicit multiplier/normalization input in biome terrain contribution, with tests proving that changing the value affects the resulting blend; or
- Remove/rename it for terrain selection if weights are intended only for a future/discrete biome selector.
Do not silently keep a public data-driven parameter that appears active but is ignored.
Important non-goal
Do not fix desert rarity solely by reducing the desert_sand / desert_sandstone mask threshold below 0.10. That would mainly expose weak mask tails and risks scattered thin sand patches rather than correcting the climatic distribution.
Validation
Add deterministic worldgen tests/statistics over a sufficiently large representative 2D sample window for seed 1337 and at least one additional seed.
Tests should verify:
- desert mask produces non-trivial contiguous coverage;
- ordinary temperate/wet regions do not become desert;
- desert/high-mountain separation still behaves correctly;
- no seams/regressions across ChunkGroup/Section/Region boundaries;
- any chosen
BiomeDef::weight semantics are covered by a regression test;
- existing deterministic worldgen tests remain stable except for intentionally changed desert distribution snapshots/expectations.
Relevant files
data/worldgen/desert_mask.lua
data/worldgen/desert_high_mountains_mask.lua
data/biomes.json
data/worldgen.json
src/world/registry/Registry.h
src/world/worldgen/WorldGen.part02.inc
src/world/worldgen/WorldGen.part04.inc
- worldgen regression tests
Problem
Deserts appear much rarer in-game than intended. The current worldgen does not seem to have a rendering/pass-order failure; the main issue is the shape of
desert_maskitself.data/worldgen/desert_mask.luacurrently requires a location to be both sufficiently hot and sufficiently dry, then multiplies both already-selective responses with additional suppression terms:hot = max(0, (temp - 0.56) / 0.38)dry = max(0, (0.43 - rain) / 0.36)desert = hot * dry * nonmountain * patchThe desert surface passes only activate above
desert_mask > 0.10. In practice this means moderate hot/dry combinations are damped very quickly, producing small/scattered desert areas instead of broad climatic desert zones.Example:
temp = 0.70->hot ~= 0.37rain = 0.25->dry ~= 0.50hot * dry ~= 0.185A fairly plausible desert climate is therefore already close to the visual activation threshold before the remaining multipliers are applied.
Additional finding:
BiomeDef::weightis currently not used by terrain blendingdata/biomes.jsondefines biome weights such as:3.52.61.71.4However,
RuntimeBiomeTerraincurrently stores only the terrain definition, mask field and biome salt.adjustedSurfaceHeight()then uses the sampled terrain mask directly as the blend weight.Therefore
BiomeDef::weightcurrently has no effect on biome terrain contribution despite being exposed in the registry as a worldgen selection weight.This should either be integrated with a clearly defined semantic or removed/renamed so the data model does not imply behavior that does not exist.
Desired behavior
Desert distribution
Deserts should remain climate-driven and deterministic, but occupy substantially broader contiguous regions.
Preferred direction:
hot * dryproduct, for example a shaped product such aspow(hot * dry, exponent)with0 < exponent < 1, or an equivalent smooth response;desert_high_mountains_maskas the separate hot/dry mountain case;A reasonable initial tuning target is roughly:
These percentages are tuning goals, not hardcoded runtime rules.
Biome weight semantics
Choose and document one of the following:
BiomeDef::weightas an explicit multiplier/normalization input in biome terrain contribution, with tests proving that changing the value affects the resulting blend; orDo not silently keep a public data-driven parameter that appears active but is ignored.
Important non-goal
Do not fix desert rarity solely by reducing the
desert_sand/desert_sandstonemask threshold below0.10. That would mainly expose weak mask tails and risks scattered thin sand patches rather than correcting the climatic distribution.Validation
Add deterministic worldgen tests/statistics over a sufficiently large representative 2D sample window for seed
1337and at least one additional seed.Tests should verify:
BiomeDef::weightsemantics are covered by a regression test;Relevant files
data/worldgen/desert_mask.luadata/worldgen/desert_high_mountains_mask.luadata/biomes.jsondata/worldgen.jsonsrc/world/registry/Registry.hsrc/world/worldgen/WorldGen.part02.incsrc/world/worldgen/WorldGen.part04.inc