Production-readiness suite fixes

Surface hydrology policy split, native terrain height cache, watched-edit
hotload cancellation, world-save requestSave with tracked ownership flush,
background-task drain that follows saves admitted mid-drain, peaceful spawn
guard, cached-completion terminal state, IO drains off the owner thread.

Studio pregen at scale: detached historical runtimes keep the configured
noise cache instead of the Studio-wide cache; retired runtimes are no longer
pinned by the volumetric fragment filter's per-thread scratch; pregen mantle
cleanup and native region flushes run on per-run threads instead of the
server thread and the shared Iris IO pool (the flush on the IO pool starved
tectonic plate loads and wedged every Paper worker in Mantle.getChunks);
background-task cancellation claims tasks atomically.
This commit is contained in:
Brian Neumann-Fopiano
2026-09-09 16:24:05 -04:00
parent 4de1aea8b9
commit 62e61970f8
150 changed files with 7892 additions and 1341 deletions
@@ -2996,7 +2996,7 @@ public final class HydrologyPackProbe {
throw new IllegalStateException("Dimension '" + configuration.dimensionKey()
+ "' has no active hydrology runtime.");
}
validateRequiredProfiles(runtime, configuration.requiredCoverage());
validateRequiredProfiles(runtime.settings(), runtime.profileKeys(), configuration.requiredCoverage());
requiredConfiguredCoverage.addAll(configuredCoverage(runtime));
validateTileBlockBounds(runtime, configuration);
for (long tileZ = configuration.minimumTileZ(); tileZ <= configuration.maximumTileZ(); tileZ++) {
@@ -3285,22 +3285,32 @@ public final class HydrologyPackProbe {
};
}
private static void validateRequiredProfiles(
IrisHydrologyRuntime runtime,
static void validateRequiredProfiles(
HydrologyPlannerSettings settings,
Set<String> riverProfiles,
List<CoverageSelector> selectors
) {
Set<String> riverProfiles = runtime.profileKeys();
LinkedHashSet<String> deepProfiles = new LinkedHashSet<>();
for (HydrologyPlannerSettings.DeepFluid deepFluid : runtime.settings().deepFluids()) {
for (HydrologyPlannerSettings.DeepFluid deepFluid : settings.deepFluids()) {
if (deepFluid.enabled()) {
deepProfiles.add(deepFluid.id());
}
}
LinkedHashSet<String> poolProfiles = new LinkedHashSet<>();
for (HydrologyPlannerSettings.SurfacePool pool : settings.surfacePools()) {
if (pool.enabled()) {
poolProfiles.add(pool.id());
}
}
for (CoverageSelector selector : selectors) {
if (selector.profileKey().equals("*")) {
continue;
}
Set<String> configuredProfiles = selector.type().isDeepFluid() ? deepProfiles : riverProfiles;
Set<String> configuredProfiles = switch (selector.type()) {
case STANDING_POOL -> poolProfiles;
case DEEP_POOL, DEEP_CHANNEL -> deepProfiles;
default -> riverProfiles;
};
if (!configuredProfiles.contains(selector.profileKey())) {
throw new IllegalArgumentException("Required coverage selector " + selector.label()
+ " references a profile not configured for that feature family.");
@@ -1,5 +1,7 @@
package art.arcane.iris.probe;
import art.arcane.iris.engine.hydrology.policy.SurfaceRiverPolicy;
import art.arcane.iris.engine.hydrology.HydrologyColumnSample;
import art.arcane.iris.engine.hydrology.HydrologyFeatureRef;
import art.arcane.iris.engine.hydrology.HydrologyFeatureType;
@@ -272,7 +274,8 @@ public final class HydrologyPlannerProbe {
HydrologyPlannerSettings.Geometry.defaults(),
List.of(), List.of(),
0D,
HydrologyPlannerSettings.SeaCaves.disabled()
HydrologyPlannerSettings.SeaCaves.disabled(),
HydrologyPlannerSettings.SurfacePolicyBounds.NONE
);
}
@@ -314,7 +317,9 @@ public final class HydrologyPlannerProbe {
List.of("water"), List.of()
,
Double.NaN,
null, Double.NaN, true);
null, Double.NaN, true,
SurfaceRiverPolicy.INHERIT
);
};
}
@@ -367,7 +372,9 @@ public final class HydrologyPlannerProbe {
List.of("water"), List.of()
,
Double.NaN,
null, Double.NaN, true);
null, Double.NaN, true,
SurfaceRiverPolicy.INHERIT
);
};
}
@@ -493,7 +500,8 @@ public final class HydrologyPlannerProbe {
HydrologyPlannerSettings.Geometry.defaults(),
List.of(deepFluid), List.of(),
0D,
HydrologyPlannerSettings.SeaCaves.disabled()
HydrologyPlannerSettings.SeaCaves.disabled(),
HydrologyPlannerSettings.SurfacePolicyBounds.NONE
);
}
@@ -542,7 +550,8 @@ public final class HydrologyPlannerProbe {
Double.NaN,
null,
Double.NaN,
true
true,
SurfaceRiverPolicy.INHERIT
);
};
}
@@ -578,7 +587,9 @@ public final class HydrologyPlannerProbe {
List.of("water"), List.of()
,
Double.NaN,
null, Double.NaN, true);
null, Double.NaN, true,
SurfaceRiverPolicy.INHERIT
);
}
private static long[] parseSeeds(String[] arguments) {
@@ -6,6 +6,7 @@ import art.arcane.iris.engine.hydrology.HydraulicSegment;
import art.arcane.iris.engine.hydrology.HydrologyFeatureRef;
import art.arcane.iris.engine.hydrology.HydrologyFeatureType;
import art.arcane.iris.engine.hydrology.HydrologyPoint;
import art.arcane.iris.engine.hydrology.HydrologyPlannerSettings;
import art.arcane.iris.engine.hydrology.HydrologyTile;
import art.arcane.iris.engine.hydrology.HydrologyTileKey;
import art.arcane.iris.engine.hydrology.RiverFootprint;
@@ -43,6 +44,24 @@ public final class HydrologyPackProbeTest {
@Rule
public final TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void standingPoolSelectorsUsePoolProfilesInsteadOfRiverProfiles() {
HydrologyPlannerSettings defaults = HydrologyPlannerSettings.defaults();
HydrologyPlannerSettings settings = new HydrologyPlannerSettings(
defaults.seaLevel(), defaults.routing(), defaults.surface(), defaults.hydraulics(),
defaults.underground(), defaults.outlets(), defaults.geometry(), defaults.deepFluids(),
List.of(new HydrologyPlannerSettings.SurfacePool("tropical_lake", true, 8D, 160, 8, 16, 3, 8, null)),
defaults.widestShoreBiomeWidth(), defaults.seaCaves(), defaults.surfacePolicyBounds());
HydrologyPackProbe.validateRequiredProfiles(settings, Set.of("water"), List.of(
HydrologyPackProbe.CoverageSelector.parse("STANDING_POOL@tropical_lake"),
HydrologyPackProbe.CoverageSelector.parse("SURFACE_POOL@water")));
assertThrows(IllegalArgumentException.class, () -> HydrologyPackProbe.validateRequiredProfiles(
settings, Set.of("water"), List.of(HydrologyPackProbe.CoverageSelector.parse("STANDING_POOL@water"))));
assertThrows(IllegalArgumentException.class, () -> HydrologyPackProbe.validateRequiredProfiles(
settings, Set.of("water"), List.of(HydrologyPackProbe.CoverageSelector.parse("SURFACE_POOL@tropical_lake"))));
}
@Test
public void parsesExplicitBoundedCoverageInputs() {
HydrologyPackProbe.ProbeConfiguration configuration = HydrologyPackProbe.ProbeConfiguration.parse(