From 577c14b6ea72fd8a191658a4f5438336b587968e Mon Sep 17 00:00:00 2001 From: George Date: Sun, 7 Jun 2026 17:13:57 +0100 Subject: [PATCH] Lower world effect thresholds to achievable levels; add water pollution to furnaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous thresholds (grass=60, smoke=70) required pollutionScore > 60. pollutionScore is a weighted average, so even if air pollution caps at 100 the score only reaches 40 from air alone — the thresholds were physically unreachable from furnace burning. New thresholds: grass degradation fires at pollutionScore > 15 (soilQuality gate raised to 75 so it doesn't block — soil defaults to 60), smoke particles fire at > 10. With 4 furnaces the score reaches ~15 in about 20 real simulation ticks (~2 minutes of play). Also added acid-rain water pollution (0.1/furnace/scan) — coal burning emits SO₂ which contributes to the weighted score alongside the existing air and ground components. Co-Authored-By: Claude Sonnet 4.6 --- src/main/java/com/livingworld/LivingWorldMod.java | 10 ++++++---- .../livingworld/bootstrap/LivingWorldBootstrap.java | 6 ++++-- .../modules/worldeffects/WorldEffectsModule.java | 9 ++++++--- .../modules/worldeffects/WorldEffectsModuleTest.java | 4 ++-- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/livingworld/LivingWorldMod.java b/src/main/java/com/livingworld/LivingWorldMod.java index a72c31e..55d6463 100644 --- a/src/main/java/com/livingworld/LivingWorldMod.java +++ b/src/main/java/com/livingworld/LivingWorldMod.java @@ -38,9 +38,10 @@ public class LivingWorldMod { public static final String MOD_ID = LivingWorldConstants.MOD_ID; - private static final int FURNACE_SCAN_INTERVAL = 100; - private static final double AIR_POLLUTION_PER_FURNACE = 0.5; - private static final double SOIL_POLLUTION_PER_FURNACE = 0.1; + private static final int FURNACE_SCAN_INTERVAL = 100; + private static final double AIR_POLLUTION_PER_FURNACE = 0.5; + private static final double GROUND_POLLUTION_PER_FURNACE = 0.1; + private static final double WATER_POLLUTION_PER_FURNACE = 0.1; private final LivingWorldBootstrap bootstrap; private MinecraftServer minecraftServer; @@ -95,7 +96,8 @@ public class LivingWorldMod { if (litCount > 0) { bootstrap.handleFurnaceActivity(region, litCount * AIR_POLLUTION_PER_FURNACE, - litCount * SOIL_POLLUTION_PER_FURNACE); + litCount * GROUND_POLLUTION_PER_FURNACE, + litCount * WATER_POLLUTION_PER_FURNACE); } } } diff --git a/src/main/java/com/livingworld/bootstrap/LivingWorldBootstrap.java b/src/main/java/com/livingworld/bootstrap/LivingWorldBootstrap.java index e3d873a..309d779 100644 --- a/src/main/java/com/livingworld/bootstrap/LivingWorldBootstrap.java +++ b/src/main/java/com/livingworld/bootstrap/LivingWorldBootstrap.java @@ -206,13 +206,15 @@ public final class LivingWorldBootstrap { /** * Records pollution produced by burning activity (e.g. furnaces) in a region. * Called from the platform layer once per simulation interval. + * + * @param waterAmount acid-rain component — SO₂ from coal dissolves in atmospheric moisture */ - public void handleFurnaceActivity(Region region, double airAmount, double groundAmount) { + public void handleFurnaceActivity(Region region, double airAmount, double groundAmount, double waterAmount) { if (!serverReady || region == null) return; PollutionRegionData data = region.getModuleData() .get(PollutionModule.MODULE_ID, PollutionRegionData.class) .orElseGet(PollutionRegionData::defaults); - data.addPollution(airAmount, groundAmount, 0.0); + data.addPollution(airAmount, groundAmount, waterAmount); region.getModuleData().put(PollutionModule.MODULE_ID, data); regionManager.markDirty(region); } diff --git a/src/main/java/com/livingworld/modules/worldeffects/WorldEffectsModule.java b/src/main/java/com/livingworld/modules/worldeffects/WorldEffectsModule.java index 44dbe2f..23b859a 100644 --- a/src/main/java/com/livingworld/modules/worldeffects/WorldEffectsModule.java +++ b/src/main/java/com/livingworld/modules/worldeffects/WorldEffectsModule.java @@ -54,12 +54,15 @@ public final class WorldEffectsModule implements SimulationModule { public static final String MODULE_ID = "worldeffects"; // Thresholds that trigger effect requests. - private static final double GRASS_DEGRADE_POLLUTION_MIN = 60.0; - private static final double GRASS_DEGRADE_SOIL_MAX = 30.0; + // Grass degradation: pollution score > 15 AND soil quality below the gate. + // Soil defaults to 60 so the gate is set at 75 to avoid blocking early effects. + private static final double GRASS_DEGRADE_POLLUTION_MIN = 15.0; + private static final double GRASS_DEGRADE_SOIL_MAX = 75.0; private static final double VEG_SPREAD_VEG_MIN = 60.0; private static final double VEG_SPREAD_SOIL_MIN = 50.0; private static final double SAPLING_SLOW_LOGGING_MIN = 50.0; - private static final double POLLUTION_INDICATOR_MIN = 70.0; + // Smoke particles appear as soon as any meaningful pollution exists. + private static final double POLLUTION_INDICATOR_MIN = 10.0; private static final ModuleMetadata METADATA = new ModuleMetadata( MODULE_ID, diff --git a/src/test/java/com/livingworld/modules/worldeffects/WorldEffectsModuleTest.java b/src/test/java/com/livingworld/modules/worldeffects/WorldEffectsModuleTest.java index 43c9d2c..1397b50 100644 --- a/src/test/java/com/livingworld/modules/worldeffects/WorldEffectsModuleTest.java +++ b/src/test/java/com/livingworld/modules/worldeffects/WorldEffectsModuleTest.java @@ -97,7 +97,7 @@ class WorldEffectsModuleTest { @Test @DisplayName("GRASS_DEGRADES_TO_DIRT not emitted when pollution is low") void grassDegradeNotEmittedLowPollution() { - metrics.setPollutionScore(30.0); + metrics.setPollutionScore(10.0); metrics.setSoilQuality(15.0); module.updateRegion(new RegionUpdateContext(region)); @@ -204,7 +204,7 @@ class WorldEffectsModuleTest { @Test @DisplayName("POLLUTION_VISUAL_INDICATOR not emitted below threshold") void pollutionVisualNotEmitted() { - metrics.setPollutionScore(50.0); + metrics.setPollutionScore(5.0); module.updateRegion(new RegionUpdateContext(region));