The Bug:
Frosted ice doesn't hydrate farmland.
It's important to note that sugar cane can rely on frosted ice blocks in order to exist within the world therefore one would expect similar behavior with farmland. If frosted ice can be used to support the existence of sugar cane, one would expect that it would also be able to hydrate farmland.
I believe this could potentially be an issue because it creates a mild inconvenience for the player when they walk near their farms whilst wearing boots enchanted with frost walker. As a result of nearby water sources being converted into frosted ice, nearby farmland blocks will gradually lose their moisture level as frosted ice isn't seen as a valid block that can hydrate farmland. Because of this, the crops above the farmland grow slower, thus creating a minor annoyance.
Steps to Reproduce:
Build the setup as shown in the attachment below.
Set the time to "night" to avoid frosted ice from melting.
Replace the water within the setup with frosted ice by using the command provided below.
/fill ~9 ~-1 ~9 ~-9 ~-4 ~-9 minecraft:frosted_ice replace minecraft:waterWait around thirty seconds and observe the moisture levels of the farmland.
Take note as to whether or not frosted ice hydrates farmland.
Observed Behavior:
Frosted ice doesn't hydrate farmland.
Expected Behavior:
Frosted ice would hydrate farmland.
Code Analysis:
Code analysis by @unknown can be found below.
The following is based on a decompiled version of Minecraft 1.19.2 using MCP-Reborn.
net.minecraft.world.level.block.FarmBlock.java
public class FarmBlock extends Block {
...
private static boolean isNearWater(LevelReader levelReader, BlockPos blockPos) {
for(BlockPos blockpos : BlockPos.betweenClosed(blockPos.offset(-4, 0, -4), blockPos.offset(4, 1, 4))) {
if (levelReader.getFluidState(blockpos).is(FluidTags.WATER)) {
return true;
}
}
return false;
}
...If we look at the above class, we can see that the isNearWater() boolean returns true if water fluid is present near farmland, and within the randomTick() method located elsewhere within the FarmBlock.java class, the isNearWater() boolean must return true in order for farmland blocks to be hydrated. The issue here is that the isNearWater() boolean only checks for the presence of water fluid and not frosted ice blocks before allowing farmland to be hydrated, therefore resulting in this problem occurring.
Fix:
Simply altering the existing "if" statement within this piece of code to also check for the nearby presence of frosted ice blocks before allowing farmland to be hydrated will resolve this problem.
Current "if" statement:
if (levelReader.getFluidState(blockpos).is(FluidTags.WATER))Fixed "if" statement:
if (levelReader.getFluidState(blockpos).is(FluidTags.WATER) || levelReader.getBlockState(blockpos).is(Blocks.FROSTED_ICE))Linked issues
Attachments
Comments 12
I can confirm this behavior in both 1.18.1 and 1.18.2 Pre-release 1.
This could be intentional however, I believe this could potentially be an issue because it creates a mild inconvenience for the player when they walk near their farms whilst wearing boots enchanted with frost walker. As a result of nearby water sources being converted into frosted ice, nearby farmland blocks will gradually lose their moisture level as frosted ice isn't seen as a valid block that can hydrate farmland. Because of this, the crops above the farmland grow slower, thus creating a minor annoyance.
Here's a code analysis along with a potential fix regarding this issue.
Code Analysis:
The following is based on a decompiled version of Minecraft 1.18.1 using MCP-Reborn.
net.minecraft.world.level.block.FarmBlock.java
public class FarmBlock extends Block {
...
public void randomTick(BlockState $bs, ServerLevel $sl, BlockPos $bp, Random $r) {
int i = $bs.getValue(MOISTURE);
if (!isNearWater($sl, $bp) && !$sl.isRainingAt($bp.above())) {
if (i > 0) {
$sl.setBlock($bp, $bs.setValue(MOISTURE, Integer.valueOf(i - 1)), 2);
} else if (!isUnderCrops($sl, $bp)) {
turnToDirt($bs, $sl, $bp);
}
} else if (i < 7) {
$sl.setBlock($bp, $bs.setValue(MOISTURE, Integer.valueOf(7)), 2);
}
}
...If we look at the above class, we can see that only one check is carried out before the game allows a farmland block to be hydrated (to increase its moisture level). This check is that the farmland block must be near water and/or rain must be present above it. This is evident through the following line of code:
if (!isNearWater($sl, $bp) && !$sl.isRainingAt($bp.above()))Since the presence of water or rain is the only requirement for a farmland block to be hydrated, we can therefore safely assume that frosted ice doesn't hydrate farmland.
Potential Fix:
Simply adding or changing some lines of code to register frosted ice as a valid block that can hydrate farmland, should resolve this problem. This can be achieved by altering the isNearWater() method to include this information. The current code within its class looks like the following:
net.minecraft.world.level.block.FarmBlock.java
public class FarmBlock extends Block {
...
private static boolean isNearWater(LevelReader $lr, BlockPos $bp) {
for(BlockPos blockpos : BlockPos.betweenClosed($bp.offset(-4, 0, -4), $bp.offset(4, 1, 4))) {
if ($lr.getFluidState(blockpos).is(FluidTags.WATER)) {
return true;
}
}
return false;
}
...In order to fix this issue, the "if" statement within this piece of code could be altered to include frosted ice as well as water. The fixed line of code should look something like the following:
if ($lr.getFluidState(blockpos).is(FluidTags.WATER) || $lr.getBlockState(blockpos).is(Blocks.FROSTED_ICE)) {Following on from my code analysis, I've double-checked my proposed fix and I can confidently confirm that it's fully functioning and works as expected, so I've attached two screenshots to this report, one of which shows the current code and the other that shows the fixed code. I feel this information may be quite insightful hence my reasoning for providing it. 🙂
Intended.
Water is water, and (Frosted) Ice is Ice