Chunk sections that only contain air and cave air are treated like sections that only contain air.
However, air and cave_air are different blocks. The difference of these blocks can be observed for example in fill commands or with parrot mob spawner blocks (cf MC-232359).
The bug causes parrot mob spawner blocks to see air instead of cave air when the chunk section is empty. The bug only seems to be observable with fill commands in empty chunk sections, e.g. the command
/fill ~ ~ ~ ~ ~ ~ stone replace cave_air
fails when the section is empty, even though there is cave air at the current position.
Linked issues
Attachments
Comments 3
This affects 1.20.4. Specifically, the issue is because AIR, CAVE_AIR, and VOID_AIR all will return true for isAir method. In LevelChunkSection, if all blocks in a chunk section would return true for isAir, then that chunk section's hasOnlyAir method now returns true which will make the chunk's getBlockState now return only AIR. Effectively erasing the existence of CAVE_AIR and VOID_AIR from the chunks. (Chunk sections are a 16x16x16 area in a chunk)
So to reproduce easily, stand in center of a chunk and set a large area to air so there's no solid block interfering.
/fill ~-16 ~-16 ~16 ~16 ~16 ~16 airThen set block at feet to cave air.
/setblock ~ ~ ~ minecraft:cave_airThen try and test if the spot is cave air. (This will fail because chunk section is now all isAir true and will see all spots as AIR. CAVE_AIR is now hidden away)
/execute if block ~ ~ ~ minecraft:cave_airSet the block next to you to stone.
/setblock ~1 ~ ~ minecraft:stoneThen set block at feet to cave air.
/setblock ~ ~ ~ minecraft:cave_airThen try and test if the spot is cave air. (This will succeed because that stone block breaks the hasOnlyAir method and forces the game to not think the chunk section is entirely AIR. Thus preserving the CAVE_AIR)
/execute if block ~ ~ ~ minecraft:cave_air
This is definitely a bug in my opinion as now it is impossible to check for CAVE_AIR or VOID_AIR blocks if a chunk section contains only those 3 air blocks as it all gets converted straight to AIR in a confusing manner without player input. Any datapack that could be using CAVE_AIR or VOID_AIR as markers will hit this bug and break.
A solution is to swap the isAir check in LevelChunkSection to be a .is(Blocks.AIR) check instead since so much of the codebase make the assumption that hasOnlyAir means all the spots in the chunk section must be AIR when that assumption is not always true.
relates to MC-191026