mojira.dev
MC-120986

Comparators do not update correctly in some cases

This is a compilation of instances were comparators do not update their power level correctly when a block with a comparator input override changed.

Affected blocks

  • beehive / bee nest

    • placed (behind block)

    • broken (behind block)

  • brewing stand

    • placed (behind block) using command /setblock x y z brewing_stand{Items:[{Slot:0b,id:"potion",Count:1b}]}

    • broken (behind block)

  • cake

    • placed (behind block) using command /setblock x y z cake (Does update if placed manually)

    • broken (behind block)

    • completely eaten up (behind block)

  • cauldron

    • placed (behind block) using command /setblock x y z cauldron[level=3]

    • removed (behind block)

    • filled by rain

  • chest

    • placed (behind block) using command /setblock x y z chest{Items:[{Slot:0b,id:"stone",Count:1b}]}

  • command block

    • placed (behind block) using command /setblock x y z command_block{SuccessCount:1}

    • broken (behind block)

  • compost

    • removed (behind block)

  • detector rail

    • broken (behind block)

  • dispenser

    • placed (behind block) using command /setblock x y z dispenser{Items:[{Slot:0b,id:"stone",Count:1b}]}

  • dropper

    • placed (behind block) using command /setblock x y z dropper{Items:[{Slot:0b,id:"stone",Count:1b}]}

  • end portal frame

    • placed (behind block) using command /setblock x y z end_portal_frame[eye=true]

    • broken (behind block)

  • furnace

    • placed (behind block) using command /setblock x y z furnace{Items:[{Slot:0b,id:"iron_ore",Count:1b}]}

  • hopper

    • placed (behind block) using command /setblock x y z hopper{Items:[{Slot:0b,id:"stone",Count:1b}]}

  • item frame

    • broken (by piston or command, left click would first remove the item)

    • In case MC-45619 is intended: If a block inside of the item frame is removed

  • jukebox

    • broken (behind block)

  • respawn anchors

    • explodes (behind block)

  • sculk sensors

Explanations:
  • (behind block): The comparator must detect the affected block through a solid block to not update in the described situation.

  • placed: Comparator does not update when the affected block is placed.

  • broken: Comparator does not update when the affected block is broken. Also applies for being moved away by a piston.

  • changed: Comparator does not update when the affected block changes its comparator input override.

Here is a video with a few examples when this bug happens. Note that it doesn't make any difference whether a block is moved by a piston or removed by a player. Some blocks however cannot be moved by pistons.

https://youtu.be/OZ_P68JvPQQ

That's every block and issue I could find related to this. If I missed something, please let me know down below.

Code Analysis

This is based on a decompiled version of Minecraft 1.12 using mcp 980.

Breaking/Moving block

In net.minecraft.world.World.setBlockState(BlockPos, IBlockState, int) there is some code that is meant to update comparators when a block with a comparator input override is placed and the flag for block updates is set. In there, you could also cause updates if a block with comparator input override is removed, however there are some cases where the update flag is not set and instead the net.minecraft.world.World.notifyNeighborsOfStateChange(BlockPos, Block, boolean) method is called instead.
So my proposed fix would be to remove the following

net.minecraft.world.World.setBlockState(BlockPos, IBlockState, int)

if (!this.isRemote && (flags & 1) != 0)
{
    this.notifyNeighborsRespectDebug(pos, iblockstate.getBlock(), true);

    //remove this
    if (newState.hasComparatorInputOverride())
    {
        this.updateComparatorOutputLevel(pos, block);
    }
}

and instead add this to net.minecraft.world.World.notifyNeighborsOfStateChange(BlockPos, Block, boolean)

net.minecraft.world.World.notifyNeighborsOfStateChange(BlockPos, Block, boolean)

IBlockState newState = getBlockState(pos);
if(blockType.getDefaultState().hasComparatorInputOverride() || newState.hasComparatorInputOverride())
{
	updateComparatorOutputLevel(pos, newState.getBlock());
}

Some code that becomes redundant after applying that fix also should be removed. That would be to remove worldIn.updateComparatorOutputLevel(pos, this); :in the following methodes

  • net.minecraft.block.BlockChest.breakBlock(World, BlockPos, IBlockState)

  • net.minecraft.block.BlockDispenser.breakBlock(World, BlockPos, IBlockState)

  • net.minecraft.block.BlockFurnace.breakBlock(World, BlockPos, IBlockState)

  • net.minecraft.block.BlockHopper.breakBlock(World, BlockPos, IBlockState)

  • net.minecraft.block.BlockShulkerBox.breakBlock(World, BlockPos, IBlockState)

An alternative would be to override the net.minecraft.block.Block.breakBlock(World, BlockPos, IBlockState) in all the classes that have a comparator input override as proposed by @unknown in this comment. But it might be cleaner to apply the fix above since you don't need to remember to override the method when adding a new block with a comparator override.

Another alternative might be to add a class that all blocks with a comparator input override need to extend in which the net.minecraft.block.Block.breakBlock(World, BlockPos, IBlockState) method is already overridden.

Cauldron being filled by rain

Code analysis by @unknown can be found in this comment

Linked issues

MC-11919 Comparator does not update properly with minecart on a detector rail, stays on Resolved MC-16716 Comparator powered from a cake/cauldron through a block, doesn't update when cauldron is removed by a piston. Resolved MC-18461 comparator stays activated when powered by detector rail through a block and detector rail is displaced by piston Resolved MC-18770 Cauldron Comparator Update Resolved MC-19230 Comparator not updating when Endportal frame with ender eye is destroyed Resolved

Attachments

Comments 20

For the moderators, these are tickets I found that are contained in this compilation:
MC-11919, MC-16716, MC-19451, MC-48017 (MC-19230, but was marked as incomplete so does not really matter)

Hey! Just noticed that the issues I have compiled here are still not linked as duplicates like it usually happens in that case.

That's because I wasn't sure what to do about it. Either we leave all the reports seperated as they are now, or they all are merged into this one.

Either way, it would be good if you could attach a short gif or a screenshot of a contraption showcasing this bug (or providing exact reproduction steps).

I think "Breaking blocks or moving them by pistons" should be pretty clear already, however I added a video with some examples: https://youtu.be/OZ_P68JvPQQ

Additionally I added code analysis that would fix all breaking or moving cases. It would not fix the issue for breaking an item frame or a cauldron being filled with rain (since that does not cause block updates in general). This may make it easier to decide whether these are indeed different issues.
I also think that it makes sense to have the other cases in that ticket since it really is all the same issue: comparators missing block updates. It is however a different location in the code for these issues and it might make sense to leave them split up as they are currently.

Thank you very much!

✔ Done merging, won't relink all the other duplicates tho, that's simply too much work.

See also the code analysises by @unknown here and here.

10 more comments
ThawingBaton546

It also occur with cauldron being pushed by piston behind a block

Also present with empty chiseled bookshelves broken behind a block.

Can confirm, 1.20.2

[media]

This also affects the copper bulb. See MC-266278

Also occurs when target blocks redirects redstone away from comparators behind block.

NeunEinser

(Unassigned)

Confirmed

Platform

Normal

Redstone

block-update, redstone-update, redstone_comparator

Minecraft 1.12.1, Minecraft 1.12.2 Pre-Release 1, Minecraft 1.12.2 Pre-Release 2, Minecraft 1.12.2, Minecraft 17w43a, ..., 1.20.2, 23w43a, 23w43b, 1.21, 1.21.3

Retrieved