When a powered observer is moved by a piston, it should send block updates around the block it is facing so that any block it is strongly powering depowers. This no longer happens.
This will cause many things that uses observers moved by pistons to break; blocks being powered by the observer will be left in an invalid state where they are on but not powered.
How to reproduce:
Build the device shown in the first image and click the note block. The redstone lamp will stay on even though it is no longer powered.
Linked issues
is duplicated by 3
Attachments
Comments 7
uploaded a video (2025-01-09 14-23-55.mp4) of various other examples at the risk of being redundant; may possibly add more insight (also replicated in 25w02a)
This issue appears to be caused by the fact that prior to 25w02a, when LevelChunk#setBlockState was called, given the right conditions, it always called BlockStateBase#onRemoved (now called "affectNeighborsAfterRemoval"), but in 25w02a, there is an additional condition, requiring the inclusion of the "UPDATE_NEIGHBORS" flag.
In PistonBaseBlock#moveBlocks some update flags passed to Level#setBlock(BlockPos, BlockState, int) were changed but still none of them include the "UPDATE_NEIGHBORS" flag.
After mixing into PistonBaseBlock#moveBlocks using the following snippet, the contraptions in this bug report should work as expected:
@Mixin(PistonBaseBlock.class)
public class PistonBaseBlockMixin {
@ModifyConstant(method = "moveBlocks", constant = {
@Constant(intValue = Block.UPDATE_MOVE_BY_PISTON | Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS),
@Constant(intValue = Block.UPDATE_NONE | Block.UPDATE_KNOWN_SHAPE),
@Constant(intValue = Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS),
@Constant(intValue = Block.UPDATE_NONE | Block.UPDATE_MOVE_BY_PISTON)
})
private int fixUpdateFlags(int flags) {
return flags | Block.UPDATE_NEIGHBORS;
}
}
Please note that this issue is not exclusive to pistons. Because of the aforementioned change, all direct and indirect calls to LevelChunk#setBlockState may need to be revisited in order to evaluate whether or not the "UPDATE_NEIGHBORS" flag should be passed.
issue still persists in some cases. For example breaking a powered lever by a piston doesnt send required updates.
here is a demonstration video https://www.bilibili.com/video/BV1avwge2Et2/?share_source=copy_web&vd_source=966badf48a7682d5cf56c2abe89a1898
The issue also persists in the case of a sticky piston retracting(useful for piston doors and instant wires). Demonstration video attached as no_neighbor_updates_on_retraction.mp4
As for the reason the issue still persists - the observer subissue seems to have been fixed by allowing the UPDATE_MOVE_BY_PISTON
flag in alternative to UPDATE_NEIGHBORS
to also cause calling BlockStateBase#affectNeighborsAfterRemoval
but two of the different combinations of flags in PistonBaseBlock#moveBlocks
don't contain the UPDATE_MOVE_BY_PISTON
flag, thus causing the issue to partly persist.
I would encourage fixing this by removing the UPDATE_MOVE_BY_PISTON
flag check in LevelChunk#setBlockState
and instead adding the UPDATE_NEIGHBORS
flag to all the combinations of flags in PistonBaseBlock#moveBlocks
and any other place UPDATE_MOVE_BY_PISTON
is used.
uploaded bug.png. Replicated in 25w02a