axialeaa
- voidredstone
- JIRAUSER517985
- Europe/London
- Yes
- No
TickingAreas don't tick reliably which could be a huge problem for technical maps/Marketplace content that require command blocks to function.
It appears t
o be directly proportional to the size of the tickingArea, and when they fail it affects every chunk in that area.Proof
Download the .mcworld file linked. Areas simulated by the player have a higher value on the scoreboard than that of the tickingArea, both of which should be ticking every gametick.
This code also shows that tickingAreas are separate from the player:
{{public: void __cdecl ChunkLoadActionList::onStaticTickingAreaAdded(class ServerLevel & __ptr64,class LevelStorage & __ptr64,class Dimension & __ptr64,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const & __ptr64) __ptr64public: virtual enum EventResult __cdecl PlayerEventListener::onPlayerTick(class Player & __ptr64) __ptr64
}}In the image, the first value is how many gameticks have been simulated in the tickingArea over the course of an hour. The second value is how many gameticks have been simulated by the player over the same time frame.
TickingAreas don't tick reliably which could be a huge problem for technical maps/Marketplace content that require command blocks to function.
It appears that larger tickingAreas unload more frequently, and when they fail it affects every chunk in that area. More testing needs to be done in order to confirm this, though.
Proof
Download the .mcworld file linked. Areas simulated by the player have a higher value on the scoreboard than that of the tickingArea, both of which should be ticking every gametick.
This code also shows that tickingAreas are separate from the player:{{public: void __cdecl ChunkLoadActionList::onStaticTickingAreaAdded(class ServerLevel & __ptr64,class LevelStorage & __ptr64,class Dimension & __ptr64,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const & __ptr64) __ptr64
public: virtual enum EventResult __cdecl PlayerEventListener::onPlayerTick(class Player & __ptr64) __ptr64
}}In the first image, the first value is how many gameticks have been simulated in the tickingArea over the course of an hour. The second value is how many gameticks have been simulated by the player over the same time frame.
In the second image, the chunks labelled chunk[_] are separate chunks in the same tickingArea. This is evidence that larger tickingAreas unload more often.
TickingAreas don't tick reliably which could be a huge problem for technical maps/Marketplace content that require command blocks to function.
It appears that larger tickingAreas unload more frequently, and when they fail it affects every chunk in that area. More testing needs to be done in order to confirm this, though.
Proof
Download the .mcworld file linked. Areas simulated by the player have a higher value on the scoreboard than that of the tickingArea, both of which should be ticking every gametick.
This code also shows that tickingAreas are separate from the player:{{public: void __cdecl ChunkLoadActionList::onStaticTickingAreaAdded(class ServerLevel & __ptr64,class LevelStorage & __ptr64,class Dimension & __ptr64,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const & __ptr64) __ptr64
public: virtual enum EventResult __cdecl PlayerEventListener::onPlayerTick(class Player & __ptr64) __ptr64
}}In the
first image, the first value is how many gameticks have been simulated in the tickingArea over the course of an hour. The second value is how many gameticks have been simulated by the player over the same time frame.In t
he second image, the chunks labelled chunk[_] are separate chunks in the same tickingArea. This is evidence that larger tickingAreas unload more often.TickingAreas don't tick reliably which could be a huge problem for technical maps/Marketplace content that require command blocks to function.
It appears that larger tickingAreas unload more frequently, and when they fail it affects every chunk in that area. More testing needs to be done in order to confirm this, though.
Proof
Download the .mcworld file linked. Areas simulated by the player have a higher value on the scoreboard than that of the tickingArea, both of which should be ticking every gametick.
This code also shows that tickingAreas are separate from the player:{{public: void __cdecl ChunkLoadActionList::onStaticTickingAreaAdded(class ServerLevel & __ptr64,class LevelStorage & __ptr64,class Dimension & __ptr64,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const & __ptr64) __ptr64
public: virtual enum EventResult __cdecl PlayerEventListener::onPlayerTick(class Player & __ptr64) __ptr64
}}In the tick_testing.png, the first value is how many gameticks have been simulated in the tickingArea over the course of an hour. The second value is how many gameticks have been simulated by the player over the same time frame.
In tick_testing_2.png, the chunks labelled chunk[_] are separate chunks in the same tickingArea. This is evidence that larger tickingAreas unload more often.
TickingAreas don't tick reliably which could be a huge problem for technical maps/Marketplace content that require command blocks to function.
It appears that larger tickingAreas unload more frequently, and when they fail it affects every chunk in that area. More testing needs to be done in order to confirm this, though.
In
, the first value is how many gameticks have been simulated in the tickingArea over the course of an hour. The second value is how many gameticks have been simulated by the player over the same time frame.
In the picture below, the chunks labelled chunk[_] are separate chunks in the same tickingArea. This is evidence that larger tickingAreas unload more often.
![]()
Steps to Reproduce
- Open tick_testing.mcworld
. It contains a scoreboard system that counts ticks in several chunks simulated by the player, and in ticking area.
- /tp -89 1 -128
- Flip the lever.
- Wait for a few minutes, or up to an hour.
Expected result
All scoreboards display the same number.
Actual result
Areas simulated by the player have a higher value on the scoreboard than that of the tickingArea.
Code analysis:
This code also shows that tickingAreas are simulated separately from the chunks simulated around players:
{{public: void __cdecl ChunkLoadActionList::onStaticTickingAreaAdded(class ServerLevel & __ptr64,class LevelStorage & __ptr64,class Dimension & __ptr64,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const & __ptr64) __ptr64
public: virtual enum EventResult __cdecl PlayerEventListener::onPlayerTick(class Player & __ptr64) __ptr64
}}
When fully uncovering an item from inside suspicious sand or gravel, the item entity is spawned too far from the face of the block and too high up. In the case of brushing the top face, the item is created high enough above the block that it falls down onto the top face.
Code Analysis (Official Mojang mappings via Fabric intermediary)
The current code is as shown below, where g, h and i correspond to the spawned item entity's x, y and z positions respectively. Bearing in mind item entities measure 0.25 * 0.25 * 0.25, h assigns to 0.625 blocks above the floor in the adjacent block position, or 10 pixels. Meanwhile, g and i assign to 0.5
+ half ofthe item entity's width, aligning itto the center of the block on those 2 axes. This leaves a significant gap between the item entity and the suspicious block.// BrushableBlockEntity#dropContent(Player)... double d = EntityType.ITEM.getWidth(); double e = 1.0 - d; double f = d / 2.0; Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); BlockPos blockPos = this.worldPosition.relative(direction, 1); double g = (double)blockPos.getX() + 0.5 * e + f; double h = (double)blockPos.getY() + 0.5 + (double)(EntityType.ITEM.getHeight() / 2.0f); double i = (double)blockPos.getZ() + 0.5 * e + f;Provided below is an example of a fix, where vec3 is the item entity spawn position.
// BrushableBlockEntity#dropContent(Player)... Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); float f = direction.getAxis().isVertical() ? EntityType.ITEM.getHeight : EntityType.ITEM.getWidth; Vec3 vec3 = this.worldPosition.getCenter() .relative(Direction.DOWN, EntityType.ITEM.getHeight / 2) .relative(direction, 0.5 + f / 2);When fully uncovering an item from inside suspicious sand or gravel, the item entity is spawned too far from the face of the block and too high up. In the case of brushing the top face, the item is created high enough above the block that it falls down onto the top face.
Code Analysis (Official Mojang mappings via Fabric intermediary)
The current code is as shown below, where g, h and i correspond to the spawned item entity's x, y and z positions respectively. Bearing in mind item entities measure 0.25 * 0.25 * 0.25, h assigns to 0.625 blocks above the floor in the adjacent block position, or 10 pixels. Meanwhile, g and i assign to 0.5, aligning the item entity to the center of the block on those 2 axes. This leaves a significant gap between the item entity and the suspicious block.
// BrushableBlockEntity#dropContent(Player)... double d = EntityType.ITEM.getWidth(); double e = 1.0 - d; double f = d / 2.0; Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); BlockPos blockPos = this.worldPosition.relative(direction, 1); double g = (double)blockPos.getX() + 0.5 * e + f; double h = (double)blockPos.getY() + 0.5 + (double)(EntityType.ITEM.getHeight() / 2.0f); double i = (double)blockPos.getZ() + 0.5 * e + f;Provided below is an example of a fix, where vec3 is the item entity spawn position.
// BrushableBlockEntity#dropContent(Player)... Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); float f = direction.getAxis().isVertical() ? EntityType.ITEM.getHeight : EntityType.ITEM.getWidth; Vec3 vec3 = this.worldPosition.getCenter() .relative(Direction.DOWN, EntityType.ITEM.getHeight / 2) .relative(direction, 0.5 + f / 2);
When fully uncovering an item from inside suspicious sand or gravel, the item entity is spawned too far from the face of the block and too high up. In the case of brushing the top face, the item is created high enough above the block that it falls down onto the top face.
Code Analysis (Official Mojang mappings via Fabric intermediary)
The current code is as shown below, where g, h and i correspond to the spawned item entity's x, y and z positions respectively. Bearing in mind item entities measure 0.25 * 0.25 * 0.25, h assigns to 0.625 blocks above the floor in the adjacent block position, or 10 pixels. Meanwhile, g and i assign to the suspicious block coordinate + 0.5, aligning the item entity to the center of the block on those 2 axes. This leaves a significant gap between the item entity and the suspicious block.
// BrushableBlockEntity#dropContent(Player)... double d = EntityType.ITEM.getWidth(); double e = 1.0 - d; double f = d / 2.0; Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); BlockPos blockPos = this.worldPosition.relative(direction, 1); double g = (double)blockPos.getX() + 0.5 * e + f; double h = (double)blockPos.getY() + 0.5 + (double)(EntityType.ITEM.getHeight() / 2.0f); double i = (double)blockPos.getZ() + 0.5 * e + f;Provided below is an example of a fix, where vec3 is the item entity spawn position.
// BrushableBlockEntity#dropContent(Player)... Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); float f = direction.getAxis().isVertical() ? EntityType.ITEM.getHeight : EntityType.ITEM.getWidth; Vec3 vec3 = this.worldPosition.getCenter() .relative(Direction.DOWN, EntityType.ITEM.getHeight / 2) .relative(direction, 0.5 + f / 2);
When fully uncovering an item from inside suspicious sand or gravel, the item entity is spawned too far from the face of the block and too high up. In the case of brushing the top face, the item is created high enough above the block that it falls down onto the top face.
Code Analysis (Official Mojang mappings via Fabric intermediary)
The current code is as shown below, where g, h and i correspond to the spawned item entity's x, y and z positions respectively. Bearing in mind item entities measure 0.25 * 0.25 * 0.25, h assigns to 0.625 blocks above the floor in the adjacent block position, or 10 pixels. Meanwhile, g and i assign to the suspicious block coordinate + 0.5, aligning the item entity to the center of the block on those 2 axes. This leaves a significant gap between the item entity and the suspicious block.
// BrushableBlockEntity#dropContent(Player)... double d = EntityType.ITEM.getWidth(); double e = 1.0 - d; double f = d / 2.0; Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); BlockPos blockPos = this.worldPosition.relative(direction, 1); double g = (double)blockPos.getX() + 0.5 * e + f; double h = (double)blockPos.getY() + 0.5 + (double)(EntityType.ITEM.getHeight() / 2.0f); double i = (double)blockPos.getZ() + 0.5 * e + f;Provided below is an example of a fix, where vec3 is the item entity spawn position.
// BrushableBlockEntity#dropContent(Player)... Direction direction = Objects.requireNonNullElse(this.hitDirection, Direction.UP); float f = direction.getAxis().isVertical() ? EntityType.ITEM.getHeight() : EntityType.ITEM.getWidth(); Vec3 vec3 = this.worldPosition.getCenter() .relative(Direction.DOWN, EntityType.ITEM.getHeight() / 2) .relative(direction, 0.5 + f / 2);








This also seems to occur when the block is retracted sideways. Am yet to fully confirm
the problem appears to occur due to portal blocks now using pendingTicks rather than instant updates
As far as I know, this is a result of secondary brightness being applied to snow but not grass, since grass has multiple textures.
I have also experienced this.
This is big news for technical players and those who use our designs for their own benefit, because one of the most well-known gold farming mechanics on the platform involves randomTicking portals to spawn zombified piglins at a fast rate.
Removed the inaccurate and incomplete "Code Analysis". Sorry for any confusion.
One way of fixing this is to change the call to this.item.split() inside BrushableBlockEntity#dropContent(Player) to this.item.copyAndClear(). This would also eliminate the need to empty the item stack further down in the method.
Okay thanks for letting me know. When submitting the issue it just said "personal information" which I assumed would cover mention of my disability