mojira.dev
MC-279326

Lit observers no longer send block updates when moved by a piston

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

Attachments

Comments 7

uploaded bug.png. Replicated in 25w02a

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) 

can confirm 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.

Why the "fix versions" are 25w02a and 25w03a but not only 25w03a?

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.

[media]

kades

gnembon

1353262

Confirmed

Expansion A

Important

Redstone

25w02a

25w02a, 25w03a

Retrieved