Surface settings v2

- Replace hydraulics, ridge tunnel, branching and inset ranges with channel, banks, flow and mouth configs
- Add routing cost weights, underground mouth leveling, bank biomes and bank multiplier
- Map the new schema into planner settings and derive refinement spacing
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-01 18:46:12 -04:00
1 parent 48afa0d93f
commit 915cc1a2f0
37 files changed
+528 -291

No files matched your search

@@ -50,7 +50,7 @@ public class PackHydrologyValidatorTest {
"derivative": "minecraft:river",
"riverPolicy": {
"profiles": ["default"],
"dryBiomes": ["river_dry"]
"bankBiomes": ["river_dry"]
}
}
""");
@@ -267,7 +267,7 @@ public class PackHydrologyValidatorTest {
"surfaceBiomes": ["missing"],
"mouthBiomes": "river",
"shoreBiomes": ["biome", "biome"],
"dryBiomes": [17],
"bankBiomes": [17],
"floodedCaveBiomes": ["../escape"],
"widthMultiplier": 0,
"depthMultiplier": 17,
@@ -286,7 +286,7 @@ public class PackHydrologyValidatorTest {
assertContains(result.errors(), "surfaceBiomes[0] references missing biome 'missing'");
assertContains(result.errors(), ".mouthBiomes must be an array or null");
assertContains(result.errors(), "shoreBiomes[1] duplicates biome 'biome'");
assertContains(result.errors(), "dryBiomes[0] must name a biome resource");
assertContains(result.errors(), "bankBiomes[0] must name a biome resource");
assertContains(result.errors(), "floodedCaveBiomes[0] must name a biome resource");
assertContains(result.errors(), "widthMultiplier must be at least");
assertContains(result.errors(), "depthMultiplier must be at most");
@@ -859,7 +859,7 @@ public class PackHydrologyValidatorTest {
"surfaceBiomes": ["river_surface"],
"mouthBiomes": ["river_surface"],
"shoreBiomes": ["river_shore"],
"dryBiomes": ["river_dry"],
"bankBiomes": ["river_dry"],
"floodedCaveBiomes": ["river_dry"],
"widthMultiplier": 1,
"depthMultiplier": 1,
@@ -164,7 +164,7 @@ public class IrisRiverSchemaTest {
assertEquals("array", properties.getJSONObject("surfaceBiomes").getString("type"));
assertEquals("array", properties.getJSONObject("mouthBiomes").getString("type"));
assertEquals("array", properties.getJSONObject("shoreBiomes").getString("type"));
assertEquals("array", properties.getJSONObject("dryBiomes").getString("type"));
assertEquals("array", properties.getJSONObject("bankBiomes").getString("type"));
assertEquals("array", properties.getJSONObject("floodedCaveBiomes").getString("type"));
assertEquals(16D, properties.getJSONObject("widthMultiplier").getDouble("maximum"), 0D);
assertEquals(0D, properties.getJSONObject("incisionMultiplier").getDouble("minimum"), 0D);
@@ -270,7 +270,8 @@ public class HydrologyPlannerCrossTileCaveAdmissionIntegrationTest {
true,
96,
10
),
,
HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(12, 40, 1, 3, 8, 4),
new HydrologyPlannerSettings.Underground(
true,
@@ -351,7 +352,8 @@ public class HydrologyPlannerCrossTileCaveAdmissionIntegrationTest {
baseSurface.ridgeTunnelsEnabled(),
baseSurface.maximumRidgeTunnelLength(),
baseSurface.ridgeTunnelHeadroom()
),
,
HydrologyPlannerSettings.Banks.defaults()),
base.hydraulics(),
new HydrologyPlannerSettings.Underground(
false,
@@ -412,6 +414,7 @@ public class HydrologyPlannerCrossTileCaveAdmissionIntegrationTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -452,11 +455,12 @@ public class HydrologyPlannerCrossTileCaveAdmissionIntegrationTest {
sample.depthMultiplier(),
sample.incisionMultiplier(),
sample.routingMultiplier(),
1D,
sample.parentBiomeKey(),
sample.surfaceBiomeKey(),
sample.mouthBiomeKey(),
sample.shoreBiomeKey(),
sample.dryBiomeKey(),
sample.bankBiomeKey(),
sample.floodedCaveBiomeKey(),
sample.preferredProfileKeys()
);
@@ -484,6 +488,7 @@ public class HydrologyPlannerCrossTileCaveAdmissionIntegrationTest {
1D,
1D,
1D,
1D,
"ocean_parent",
"surface",
"mouth",
@@ -687,7 +687,8 @@ public class HydrologyPlannerGlobalInvariantTest {
false,
0,
0
),
,
HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(8, 16, 1, 3, 8, 4),
new HydrologyPlannerSettings.Underground(
undergroundEnabled,
@@ -752,7 +753,8 @@ public class HydrologyPlannerGlobalInvariantTest {
surface.ridgeTunnelsEnabled(),
surface.maximumRidgeTunnelLength(),
surface.ridgeTunnelHeadroom()
),
,
HydrologyPlannerSettings.Banks.defaults()),
base.hydraulics(),
new HydrologyPlannerSettings.Underground(
underground.enabled(),
@@ -935,6 +937,7 @@ public class HydrologyPlannerGlobalInvariantTest {
1D,
1D,
1D,
1D,
ocean ? "ocean" : "land",
"surface",
"mouth",
@@ -985,6 +988,7 @@ public class HydrologyPlannerGlobalInvariantTest {
1D,
1D,
1D,
1D,
"land",
"surface",
"mouth",
@@ -1033,6 +1037,7 @@ public class HydrologyPlannerGlobalInvariantTest {
1D,
1D,
1D,
1D,
"land",
"surface",
"mouth",
@@ -1157,7 +1162,7 @@ public class HydrologyPlannerGlobalInvariantTest {
addString(terrain.surfaceBiomeKey());
addString(terrain.mouthBiomeKey());
addString(terrain.shoreBiomeKey());
addString(terrain.dryBiomeKey());
addString(terrain.bankBiomeKey());
addString(terrain.floodedCaveBiomeKey());
addInt(terrain.preferredProfileKeys().size());
for (String profile : terrain.preferredProfileKeys()) {
@@ -1287,7 +1292,7 @@ public class HydrologyPlannerGlobalInvariantTest {
addString(layer.surfaceBiomeKey());
addString(layer.mouthBiomeKey());
addString(layer.shoreBiomeKey());
addString(layer.dryBiomeKey());
addString(layer.bankBiomeKey());
addString(layer.floodedCaveBiomeKey());
}
@@ -89,7 +89,8 @@ public class HydrologyPlannerSettingsTest {
false,
0,
0
);
,
HydrologyPlannerSettings.Banks.defaults());
HydrologyPlannerSettings.Hydraulics hydraulics = new HydrologyPlannerSettings.Hydraulics(
8,
8,
@@ -139,6 +140,38 @@ public class HydrologyPlannerSettingsTest {
assertEquals(2730, deepFluid.maximumChannelLength());
}
@Test
public void bankSettingsRejectValuesOutsideTheirBounds() {
HydrologyPlannerSettings.Banks banks = HydrologyPlannerSettings.Banks.defaults();
assertEquals(1, banks.inset());
assertEquals(1, banks.freeboard());
assertEquals(3D, banks.blendSlope(), 0D);
assertEquals(4, banks.minimumBlendWidth());
assertEquals(32, banks.maximumBlendWidth());
assertEquals(6, banks.waterfallMinimumDrop());
assertTrue(banks.exposeCutStrata());
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Banks(
0, 1, 3D, 4, 32, 0.25D, 16, 2, 6, 1.6D, true));
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Banks(
1, 0, 3D, 4, 32, 0.25D, 16, 2, 6, 1.6D, true));
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Banks(
1, 1, 0.5D, 4, 32, 0.25D, 16, 2, 6, 1.6D, true));
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Banks(
1, 1, 3D, 40, 32, 0.25D, 16, 2, 6, 1.6D, true));
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Banks(
1, 1, 3D, 4, 32, 0.25D, 16, 2, 1, 1.6D, true));
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Banks(
1, 1, 3D, 4, 32, 0.25D, 16, 0, 6, 1.6D, true));
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Banks(
1, 1, 3D, 4, 32, 1.5D, 16, 2, 6, 1.6D, true));
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Surface(
true,
new HydrologyPlannerSettings.Source(true, 1D, 0, 0, 1, 0),
1, 1, 1, 1, 1, 1, 0, 1D, 0, 0, false, 0, 0,
null));
}
@Test
public void inconsistentHydraulicThresholdsAreRejected() {
assertThrows(IllegalArgumentException.class, () -> new HydrologyPlannerSettings.Hydraulics(
@@ -509,6 +509,7 @@ public class HydrologyPlannerTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -1124,7 +1125,7 @@ public class HydrologyPlannerTest {
assertEquals("surface", layer.surfaceBiomeKey());
assertEquals("mouth", layer.mouthBiomeKey());
assertEquals("shore", layer.shoreBiomeKey());
assertEquals("dry", layer.dryBiomeKey());
assertEquals("dry", layer.bankBiomeKey());
assertEquals("flooded", layer.floodedCaveBiomeKey());
if (layer.grading() && !layer.shore() && !layer.channel()) {
sawGrading = true;
@@ -1204,7 +1205,8 @@ public class HydrologyPlannerTest {
base.surface().ridgeTunnelsEnabled(),
base.surface().maximumRidgeTunnelLength(),
base.surface().ridgeTunnelHeadroom()
);
,
HydrologyPlannerSettings.Banks.defaults());
HydrologyPlannerSettings shaped = new HydrologyPlannerSettings(
base.seaLevel(),
base.routing(),
@@ -1498,7 +1500,8 @@ public class HydrologyPlannerTest {
surface.ridgeTunnelsEnabled(),
32,
surface.ridgeTunnelHeadroom()
),
,
HydrologyPlannerSettings.Banks.defaults()),
base.hydraulics(),
base.underground(),
base.outlets(),
@@ -1850,7 +1853,8 @@ public class HydrologyPlannerTest {
true,
64,
8
),
,
HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(12, 28, 1, 3, 8, 4),
new HydrologyPlannerSettings.Underground(
undergroundDensity > 0D,
@@ -1926,7 +1930,8 @@ public class HydrologyPlannerTest {
surface.ridgeTunnelsEnabled(),
192,
surface.ridgeTunnelHeadroom()
),
,
HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(12, 28, 1, 4, 12, 5),
base.underground(),
new HydrologyPlannerSettings.Outlets(
@@ -2002,6 +2007,7 @@ public class HydrologyPlannerTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -2066,6 +2072,7 @@ public class HydrologyPlannerTest {
1D,
1D,
1D,
1D,
"ocean_parent",
"surface",
"mouth",
@@ -2097,6 +2104,7 @@ public class HydrologyPlannerTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -2137,6 +2145,7 @@ public class HydrologyPlannerTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -2168,6 +2177,7 @@ public class HydrologyPlannerTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -2199,6 +2209,7 @@ public class HydrologyPlannerTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -2233,7 +2244,8 @@ public class HydrologyPlannerTest {
surface.ridgeTunnelsEnabled(),
surface.maximumRidgeTunnelLength(),
surface.ridgeTunnelHeadroom()
),
,
HydrologyPlannerSettings.Banks.defaults()),
settings.hydraulics(),
settings.underground(),
settings.outlets(),
@@ -236,7 +236,8 @@ public class HydrologyStyledGeometryTest {
true,
96,
8
),
,
HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(12, 28, 1, 3, 8, 4),
new HydrologyPlannerSettings.Underground(
undergroundDensity > 0D,
@@ -288,6 +289,7 @@ public class HydrologyStyledGeometryTest {
1D,
1D,
1D,
1D,
"ocean",
"surface",
"mouth",
@@ -319,6 +321,7 @@ public class HydrologyStyledGeometryTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -70,6 +70,7 @@ public final class HydrologyTerrainSampleTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -245,7 +245,7 @@ public class HydrologyTileCacheTest {
63,
new HydrologyPlannerSettings.Routing(64, 16, 4, 128, 64,
new HydrologyPlannerSettings.Branching(0, 0), 0D, 0D, 0D, 0D),
new HydrologyPlannerSettings.Surface(false, disabled, 2, 4, 1, 2, 2, 4, 4, 1D, 2, 4, false, 0, 0),
new HydrologyPlannerSettings.Surface(false, disabled, 2, 4, 1, 2, 2, 4, 4, 1D, 2, 4, false, 0, 0, HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(8, 16, 1, 2, 8, 3),
new HydrologyPlannerSettings.Underground(false, disabled, -32, 32, 2, 4, 1, 2, 3, 4, false),
new HydrologyPlannerSettings.Outlets(
@@ -284,7 +284,7 @@ public class HydrologyTileCacheTest {
63,
new HydrologyPlannerSettings.Routing(64, 16, 4, 128, 96,
new HydrologyPlannerSettings.Branching(16, 8), 0.5D, 12D, 0.5D, 0.1D),
new HydrologyPlannerSettings.Surface(true, surfaceSources, 4, 8, 2, 3, 4, 8, 20, 1.5D, 2, 4, true, 96, 8),
new HydrologyPlannerSettings.Surface(true, surfaceSources, 4, 8, 2, 3, 4, 8, 20, 1.5D, 2, 4, true, 96, 8, HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(8, 16, 1, 2, 8, 3),
new HydrologyPlannerSettings.Underground(false, disabled, -32, 32, 2, 4, 1, 2, 3, 4, false),
new HydrologyPlannerSettings.Outlets(
@@ -327,6 +327,7 @@ public class HydrologyTileCacheTest {
1D,
1D,
1D,
1D,
"parent",
"surface",
"mouth",
@@ -29,10 +29,12 @@ public class RiverPolicyResolverTest {
assertEquals(IrisRiverRoutingMode.ALLOW, policy.routing());
assertTrue(policy.outletAdmission());
assertTrue(policy.profiles().isEmpty());
assertTrue(policy.bankBiomes().isEmpty());
assertEquals(1D, policy.widthMultiplier(), 0D);
assertEquals(1D, policy.depthMultiplier(), 0D);
assertEquals(1D, policy.incisionMultiplier(), 0D);
assertEquals(1D, policy.routingMultiplier(), 0D);
assertEquals(1D, policy.bankMultiplier(), 0D);
assertTrue(policy.allowsSources());
assertTrue(policy.allowsTransit());
assertTrue(policy.allowsRouting());
@@ -49,13 +51,16 @@ public class RiverPolicyResolverTest {
.setProfiles(new KList<>("water"))
.setSurfaceBiomes(new KList<>("river/dimension"))
.setMouthBiomes(new KList<>("river/mouth"))
.setBankBiomes(new KList<>("river/bank-dimension"))
.setWidthMultiplier(1.5D)
.setDepthMultiplier(1.25D);
.setDepthMultiplier(1.25D)
.setBankMultiplier(2D);
IrisRiverPolicy region = new IrisRiverPolicy()
.setRouting(IrisRiverRoutingMode.PREFER)
.setProfiles(new KList<>())
.setSurfaceBiomes(new KList<>("river/region"))
.setShoreBiomes(new KList<>("river/shore"))
.setBankBiomes(new KList<>())
.setWidthMultiplier(0.8D)
.setRoutingMultiplier(2D);
IrisRiverPolicy biome = new IrisRiverPolicy()
@@ -63,10 +68,10 @@ public class RiverPolicyResolverTest {
.setRouting(IrisRiverRoutingMode.BLOCK)
.setOutletAdmission(true)
.setSurfaceBiomes(new KList<>())
.setDryBiomes(new KList<>("river/dry"))
.setFloodedCaveBiomes(new KList<>("river/flooded"))
.setDepthMultiplier(0.75D)
.setIncisionMultiplier(0.5D);
.setIncisionMultiplier(0.5D)
.setBankMultiplier(0.5D);
EffectiveRiverPolicy policy = RiverPolicyResolver.resolve(dimension, region, biome);
@@ -75,14 +80,15 @@ public class RiverPolicyResolverTest {
assertTrue(policy.outletAdmission());
assertTrue(policy.profiles().isEmpty());
assertTrue(policy.surfaceBiomes().isEmpty());
assertTrue(policy.bankBiomes().isEmpty());
assertEquals(List.of("river/mouth"), policy.mouthBiomes());
assertEquals(List.of("river/shore"), policy.shoreBiomes());
assertEquals(List.of("river/dry"), policy.dryBiomes());
assertEquals(List.of("river/flooded"), policy.floodedCaveBiomes());
assertEquals(0.8D, policy.widthMultiplier(), 0D);
assertEquals(0.75D, policy.depthMultiplier(), 0D);
assertEquals(0.5D, policy.incisionMultiplier(), 0D);
assertEquals(2D, policy.routingMultiplier(), 0D);
assertEquals(0.5D, policy.bankMultiplier(), 0D);
assertTrue(policy.allowsSources());
assertTrue(policy.allowsTransit());
assertFalse(policy.allowsRouting());
@@ -90,6 +96,17 @@ public class RiverPolicyResolverTest {
assertTrue(policy.requiresHeadwaters());
}
@Test
public void bankBiomesInheritUntilOverridden() {
IrisRiverPolicy dimension = new IrisRiverPolicy().setBankBiomes(new KList<>("river/bank"));
IrisRiverPolicy region = new IrisRiverPolicy().setRouting(IrisRiverRoutingMode.PREFER);
EffectiveRiverPolicy policy = RiverPolicyResolver.resolve(dimension, region, null);
assertEquals(List.of("river/bank"), policy.bankBiomes());
assertEquals(1D, policy.bankMultiplier(), 0D);
}
@Test
public void resolvesOwnerPoliciesAndSnapshotsMutableLists() {
KList<String> profiles = new KList<>("water");
@@ -19,8 +19,7 @@ public class IrisHydrologyRuntimeSettingsTest {
.setShortChannels(true)
.setSpacing(8192);
IrisRiverRoutingConfig routing = new IrisRiverRoutingConfig()
.setTileSize(256)
.setRefinementSpacing(8);
.setTileSize(256);
assertEquals(128, IrisHydrologyRuntime.maximumDeepChannelLength(deepFluid, routing));
}
@@ -31,8 +30,7 @@ public class IrisHydrologyRuntimeSettingsTest {
.setShortChannels(false)
.setSpacing(8192);
IrisRiverRoutingConfig routing = new IrisRiverRoutingConfig()
.setTileSize(256)
.setRefinementSpacing(8);
.setTileSize(256);
assertEquals(0, IrisHydrologyRuntime.maximumDeepChannelLength(deepFluid, routing));
}
@@ -75,6 +73,57 @@ public class IrisHydrologyRuntimeSettingsTest {
.underground().sources().minimumSpacing());
}
@Test
public void surfaceBankAndFlowConfigurationMapsIntoPlannerSettings() {
IrisDimension dimension = new IrisDimension();
IrisRiverHydrology rivers = dimension.getHydrology().getRivers();
rivers.getSurface().getChannel().setInset(2).setMaximumIncision(12);
rivers.getSurface().getBanks()
.setFreeboard(2)
.setShoreWidth(2.5D)
.setBlendSlope(4D)
.setMinimumBlendWidth(6)
.setMaximumBlendWidth(48)
.setExposeCutStrata(false);
rivers.getSurface().getFlow().setCascadeRun(3).setWaterfallMinimumDrop(8);
rivers.getSurface().getMouths().setFlareRatio(2.2D);
rivers.getUnderground().setMouthLevelingDistance(96);
rivers.getRouting()
.setSampleSpacing(32)
.setMinimumSurfaceCourseLength(500)
.setMinimumUndergroundCourseLength(250)
.setValleyPreference(2.5D)
.setUphillPenalty(30D)
.setSlopePenalty(3D)
.setConfluenceAttraction(0.4D);
HydrologyPlannerSettings settings = IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology());
HydrologyPlannerSettings.Banks banks = settings.surface().banks();
assertEquals(2, banks.inset());
assertEquals(2, banks.freeboard());
assertEquals(4D, banks.blendSlope(), 0D);
assertEquals(6, banks.minimumBlendWidth());
assertEquals(48, banks.maximumBlendWidth());
assertEquals(3, banks.cascadeRun());
assertEquals(8, banks.waterfallMinimumDrop());
assertEquals(2.2D, banks.mouthFlareRatio(), 0D);
assertFalse(banks.exposeCutStrata());
assertEquals(12, settings.surface().maximumIncision());
assertEquals(2.5D, settings.surface().shoreWidth(), 0D);
assertEquals(8, settings.hydraulics().waterfallMinimumDrop());
assertEquals(96, settings.outlets().mouthLevelingDistance());
assertEquals(4, settings.routing().refinementSpacing());
assertEquals(500, settings.routing().branching().minimumSurfaceCourseLength());
assertEquals(250, settings.routing().branching().minimumUndergroundCourseLength());
assertEquals(2.5D, settings.routing().valleyPreference(), 0D);
assertEquals(30D, settings.routing().uphillPenalty(), 0D);
assertEquals(3D, settings.routing().slopePenalty(), 0D);
assertEquals(0.4D, settings.routing().confluenceAttraction(), 0D);
assertEquals(2, IrisHydrologyRuntime.refinementSpacing(50));
assertEquals(1, IrisHydrologyRuntime.refinementSpacing(45));
}
@Test
public void routingOutletLimitControlsDrainageRootCount() {
IrisDimension dimension = new IrisDimension();
@@ -96,10 +145,8 @@ public class IrisHydrologyRuntimeSettingsTest {
.setMaximumOffsetRatio(0.44D)
.setSmoothingPasses(2)
.setMaximumTurnDegrees(76D);
rivers.getGeometry().getSurface()
.setBedRoundness(3.1D)
.setBedRoughness(0.37D)
.setWallRoughness(0.29D)
rivers.getSurface().getChannel()
.setRoughness(0.37D)
.setRoughnessWavelength(13);
rivers.getGeometry().getDrops()
.setCascadeRunPerBlock(4)
@@ -121,9 +168,8 @@ public class IrisHydrologyRuntimeSettingsTest {
assertEquals(0.44D, geometry.meanders().maximumOffsetRatio(), 0D);
assertEquals(2, geometry.meanders().smoothingPasses());
assertEquals(76D, geometry.meanders().maximumTurnDegrees(), 0D);
assertEquals(3.1D, geometry.surface().bedRoundness(), 0D);
assertEquals(0.37D, geometry.surface().bedRoughness(), 0D);
assertEquals(0.29D, geometry.surface().wallRoughness(), 0D);
assertEquals(0.37D, geometry.surface().wallRoughness(), 0D);
assertEquals(13, geometry.surface().roughnessWavelength());
assertEquals(4, geometry.drops().cascadeRunPerBlock());
assertEquals(2.2D, geometry.drops().cascadeExponent(), 0D);
@@ -1541,7 +1541,8 @@ public class MantleHydrologyComponentTest {
false,
0,
0
),
,
HydrologyPlannerSettings.Banks.defaults()),
new HydrologyPlannerSettings.Hydraulics(8, 16, 1, 3, 8, 4),
new HydrologyPlannerSettings.Underground(
false,
@@ -1597,6 +1598,7 @@ public class MantleHydrologyComponentTest {
1D,
1D,
1D,
1D,
ocean ? "ocean" : "land",
"surface",
"mouth",
@@ -148,7 +148,7 @@ public class IrisDimensionReachableBiomesTest {
.setChildren(new KList<>("dimension-child"));
IrisBiome dimensionChild = biome("dimension-child");
IrisBiome regionMouth = biome("region-mouth").setRiverPolicy(new IrisRiverPolicy()
.setDryBiomes(new KList<>("nested-dry")));
.setBankBiomes(new KList<>("nested-dry")));
IrisBiome biomeShore = biome("biome-shore");
IrisBiome nestedDry = biome("nested-dry");
@@ -222,7 +222,7 @@ public class IrisDimensionReachableBiomesTest {
IrisRegion reachable = new IrisRegion()
.setLandBiomes(new KList<>("root"))
.setRiverPolicy(new IrisRiverPolicy()
.setDryBiomes(new KList<>("region-dry")));
.setBankBiomes(new KList<>("region-dry")));
IrisBiome root = biome("root").setRiverPolicy(new IrisRiverPolicy()
.setFloodedCaveBiomes(new KList<>("biome-flooded")));
@@ -32,9 +32,14 @@ public class IrisRiverConfigurationTest {
IrisRiverRoutingConfig routing = dimension.getHydrology().getRivers().getRouting();
assertEquals(2048, routing.getTileSize());
assertEquals(64, routing.getSampleSpacing());
assertEquals(16384, routing.getMaximumRouteLength());
assertEquals(384, routing.getBranching().getMinimumSurfaceCourseLength());
assertEquals(192, routing.getBranching().getMinimumUndergroundCourseLength());
assertEquals(384, routing.getMinimumSurfaceCourseLength());
assertEquals(192, routing.getMinimumUndergroundCourseLength());
assertEquals(1.5D, routing.getValleyPreference(), 0D);
assertEquals(24D, routing.getUphillPenalty(), 0D);
assertEquals(2D, routing.getSlopePenalty(), 0D);
assertEquals(0.2D, routing.getConfluenceAttraction(), 0D);
IrisSurfaceRiverConfig surface = dimension.getHydrology().getRivers().getSurface();
assertTrue(surface.isEnabled());
@@ -43,19 +48,22 @@ public class IrisRiverConfigurationTest {
assertEquals(384, surface.getSources().getMinimumSpacing());
assertEquals(4D, surface.getChannel().getWidth().getMin(), 0D);
assertEquals(8D, surface.getChannel().getWidth().getMax(), 0D);
assertEquals(1D, surface.getChannel().getDepth().getMin(), 0D);
assertEquals(2D, surface.getChannel().getDepth().getMin(), 0D);
assertEquals(4D, surface.getChannel().getDepth().getMax(), 0D);
assertEquals(2D, surface.getChannel().getDepth().getStyle().getExponent(), 0D);
assertEquals(3D, surface.getChannel().getSurfaceInset().getMin(), 0D);
assertEquals(7D, surface.getChannel().getSurfaceInset().getMax(), 0D);
assertEquals(2D, surface.getChannel().getSurfaceInset().getStyle().getExponent(), 0D);
assertEquals(6, surface.getChannel().getMaximumIncision());
assertEquals(2D, surface.getChannel().getShoreWidth(), 0D);
assertEquals(64, surface.getMouths().getLevelingDistance());
assertEquals(1, surface.getChannel().getInset());
assertEquals(10, surface.getChannel().getMaximumIncision());
assertEquals(0.25D, surface.getChannel().getRoughness(), 0D);
assertEquals(16, surface.getChannel().getRoughnessWavelength());
assertEquals(1, surface.getBanks().getFreeboard());
assertEquals(1.5D, surface.getBanks().getShoreWidth(), 0D);
assertEquals(3D, surface.getBanks().getBlendSlope(), 0D);
assertEquals(4, surface.getBanks().getMinimumBlendWidth());
assertEquals(32, surface.getBanks().getMaximumBlendWidth());
assertTrue(surface.getBanks().isExposeCutStrata());
assertEquals(2, surface.getFlow().getCascadeRun());
assertEquals(6, surface.getFlow().getWaterfallMinimumDrop());
assertEquals(1.6D, surface.getMouths().getFlareRatio(), 0D);
assertEquals(8, surface.getMouths().getMaximumOceanApron());
assertEquals(80D, surface.getHydraulics().getTargetPoolLength().getMin(), 0D);
assertEquals(180D, surface.getHydraulics().getTargetPoolLength().getMax(), 0D);
assertEquals(8, surface.getHydraulics().getWaterfallMinimumDrop());
IrisRiverDropShapeConfig drops = dimension.getHydrology().getRivers().getGeometry().getDrops();
assertEquals(2, drops.getCascadeRunPerBlock());
assertEquals(1.4D, drops.getCascadeExponent(), 0D);
@@ -75,6 +83,7 @@ public class IrisRiverConfigurationTest {
assertEquals(3D, underground.getChannelWidth().getMin(), 0D);
assertEquals(8D, underground.getChannelWidth().getMax(), 0D);
assertTrue(underground.isConnectToExistingCaves());
assertEquals(64, underground.getMouthLevelingDistance());
IrisCoastalRiverGrottoConfig coastal = dimension.getHydrology().getRivers().getGrottos().getCoastal();
IrisInlandRiverGrottoConfig inland = dimension.getHydrology().getRivers().getGrottos().getInland();
@@ -101,6 +110,7 @@ public class IrisRiverConfigurationTest {
assertNull(dimension.getRiverPolicy().getPlacement());
assertNull(dimension.getRiverPolicy().getRouting());
assertNull(dimension.getRiverPolicy().getOutletAdmission());
assertNull(dimension.getRiverPolicy().getBankMultiplier());
assertNull(new IrisRegion().getRiverPolicy());
assertNull(new IrisBiome().getRiverPolicy());
}
@@ -116,15 +126,16 @@ public class IrisRiverConfigurationTest {
"routing": {
"tileSize": 4096,
"sampleSpacing": 96,
"refinementSpacing": 6,
"branching": {
"minimumSurfaceCourseLength": 640,
"minimumUndergroundCourseLength": 480
},
"maximumRouteLength": 32768,
"minimumSurfaceCourseLength": 640,
"minimumUndergroundCourseLength": 480,
"maximumOutletsPerTile": 3,
"oceanOutlets": true,
"inlandOutlets": ["SINKHOLE_GROTTO"]
"inlandOutlets": ["SINKHOLE_GROTTO"],
"valleyPreference": 2.5,
"uphillPenalty": 30,
"slopePenalty": 3,
"confluenceAttraction": 0.4
},
"geometry": {
"drops": {
@@ -143,20 +154,21 @@ public class IrisRiverConfigurationTest {
"channel": {
"width": {"min": 5, "max": 24},
"depth": {"min": 2, "max": 6},
"surfaceInset": {"min": 5, "max": 9},
"inset": 2,
"maximumIncision": 14,
"shoreWidth": 1.5,
"terrainBlendWidth": {"min": 8, "max": 10}
"roughness": 0.4,
"roughnessWavelength": 24
},
"hydraulics": {
"targetPoolLength": {"min": 64, "max": 192},
"riffleDrop": 1,
"maximumGradualDrop": 4,
"maximumGradualLength": 12,
"waterfallMinimumDrop": 5
"banks": {
"freeboard": 2,
"shoreWidth": 2.5,
"blendSlope": 4,
"minimumBlendWidth": 6,
"maximumBlendWidth": 48,
"exposeCutStrata": false
},
"ridgeTunnels": {"enabled": true, "maximumLength": 224, "headroom": 12},
"mouths": {"levelingDistance": 80, "maximumOceanApron": 1}
"flow": {"cascadeRun": 3, "waterfallMinimumDrop": 8},
"mouths": {"flareRatio": 2.2, "maximumOceanApron": 1}
},
"underground": {
"sources": {"density": 0.4, "minimumPerTile": 3, "minimumSpacing": 896},
@@ -164,7 +176,8 @@ public class IrisRiverConfigurationTest {
"channelWidth": {"min": 4, "max": 16},
"depth": {"min": 2, "max": 4},
"headroom": {"min": 7, "max": 15},
"connectToExistingCaves": false
"connectToExistingCaves": false,
"mouthLevelingDistance": 80
},
"grottos": {
"coastal": {
@@ -211,8 +224,10 @@ public class IrisRiverConfigurationTest {
"profiles": ["underworld"],
"surfaceBiomes": ["river/surface"],
"shoreBiomes": ["river/shore"],
"bankBiomes": ["river/bank"],
"widthMultiplier": 1.5,
"incisionMultiplier": 0.75
"incisionMultiplier": 0.75,
"bankMultiplier": 2
}
}
""", IrisDimension.class);
@@ -236,14 +251,31 @@ public class IrisRiverConfigurationTest {
IrisRiverHydrology rivers = dimension.getHydrology().getRivers();
assertTrue(rivers.isEnabled());
assertEquals(4096, rivers.getRouting().getTileSize());
assertEquals(96, rivers.getRouting().getSampleSpacing());
assertEquals(32768, rivers.getRouting().getMaximumRouteLength());
assertEquals(3, rivers.getRouting().getMaximumOutletsPerTile());
assertEquals(640, rivers.getRouting().getBranching().getMinimumSurfaceCourseLength());
assertEquals(480, rivers.getRouting().getBranching().getMinimumUndergroundCourseLength());
assertEquals(640, rivers.getRouting().getMinimumSurfaceCourseLength());
assertEquals(480, rivers.getRouting().getMinimumUndergroundCourseLength());
assertEquals(2.5D, rivers.getRouting().getValleyPreference(), 0D);
assertEquals(30D, rivers.getRouting().getUphillPenalty(), 0D);
assertEquals(3D, rivers.getRouting().getSlopePenalty(), 0D);
assertEquals(0.4D, rivers.getRouting().getConfluenceAttraction(), 0D);
assertEquals(new KList<>(IrisRiverInlandOutlet.SINKHOLE_GROTTO), rivers.getRouting().getInlandOutlets());
assertEquals(24D, rivers.getSurface().getChannel().getWidth().getMax(), 0D);
assertEquals(9D, rivers.getSurface().getChannel().getSurfaceInset().getMax(), 0D);
assertEquals(5, rivers.getSurface().getHydraulics().getWaterfallMinimumDrop());
assertEquals(2, rivers.getSurface().getChannel().getInset());
assertEquals(14, rivers.getSurface().getChannel().getMaximumIncision());
assertEquals(0.4D, rivers.getSurface().getChannel().getRoughness(), 0D);
assertEquals(24, rivers.getSurface().getChannel().getRoughnessWavelength());
assertEquals(2, rivers.getSurface().getBanks().getFreeboard());
assertEquals(2.5D, rivers.getSurface().getBanks().getShoreWidth(), 0D);
assertEquals(4D, rivers.getSurface().getBanks().getBlendSlope(), 0D);
assertEquals(6, rivers.getSurface().getBanks().getMinimumBlendWidth());
assertEquals(48, rivers.getSurface().getBanks().getMaximumBlendWidth());
assertFalse(rivers.getSurface().getBanks().isExposeCutStrata());
assertEquals(3, rivers.getSurface().getFlow().getCascadeRun());
assertEquals(8, rivers.getSurface().getFlow().getWaterfallMinimumDrop());
assertEquals(2.2D, rivers.getSurface().getMouths().getFlareRatio(), 0D);
assertEquals(1, rivers.getSurface().getMouths().getMaximumOceanApron());
assertEquals(768, rivers.getSurface().getSources().getMinimumSpacing());
assertEquals(5, rivers.getGeometry().getDrops().getCascadeRunPerBlock());
assertEquals(2.4D, rivers.getGeometry().getDrops().getCascadeExponent(), 0D);
@@ -252,10 +284,10 @@ public class IrisRiverConfigurationTest {
assertEquals(4, rivers.getGeometry().getDrops().getMaximumFlowDepth());
assertEquals(2.2D, rivers.getGeometry().getDrops().getBasinWidthRatio(), 0D);
assertEquals(11, rivers.getGeometry().getDrops().getMaximumBasinDepth());
assertEquals(224, rivers.getSurface().getRidgeTunnels().getMaximumLength());
assertEquals(-96D, rivers.getUnderground().getFluidLevel().getMin(), 0D);
assertEquals(896, rivers.getUnderground().getSources().getMinimumSpacing());
assertFalse(rivers.getUnderground().isConnectToExistingCaves());
assertEquals(80, rivers.getUnderground().getMouthLevelingDistance());
assertEquals(40, rivers.getGrottos().getCoastal().getHorizontalRadius());
assertTrue(rivers.getGrottos().getInland().isEnabled());
assertTrue(rivers.getGrottos().getInland().isConnectSurfaceRivers());
@@ -273,7 +305,8 @@ public class IrisRiverConfigurationTest {
assertEquals(IrisRiverPlacementMode.PREFERRED_HEADWATER, dimension.getRiverPolicy().getPlacement());
assertEquals(IrisRiverRoutingMode.PREFER, dimension.getRiverPolicy().getRouting());
assertFalse(dimension.getRiverPolicy().getOutletAdmission());
assertEquals(Set.of("river/surface", "river/shore"), dimension.getRiverPolicy().getAllBiomeIds());
assertEquals(2D, dimension.getRiverPolicy().getBankMultiplier(), 0D);
assertEquals(Set.of("river/surface", "river/shore", "river/bank"), dimension.getRiverPolicy().getAllBiomeIds());
assertEquals(IrisRiverPlacementMode.TRANSIT_ONLY, region.getRiverPolicy().getPlacement());
assertEquals(new KList<>("river/mouth"), region.getRiverPolicy().getMouthBiomes());
assertEquals(IrisRiverPlacementMode.REQUIRED_HEADWATER, biome.getRiverPolicy().getPlacement());