When an entity moves, it's supposed to trigger pressure plates and interact with such blocks along its path of motion.
In 24w33a a collision raycast was introduced to create that behavior, however, 25w09a changed it in a bad way.
• Previously (25w08a-) entities moving along all 3 axes in a single tick checked these blocks along their movement path:
(see attached screenshot called 25w08a), in it you can see that the interacted blocks lie all along a diagonal path from start to finish of the single tick movement of an entity. All of the blocks lie along the diagonal path (except the center is cut out, which was done to fix a crash issue MC-275437)
• Currently (25w09a+) entities, while moving along all 3 axes in a single tick, check the blocks along their corkscrew path, like in this picture:
(see attached screenshot called 25w09b), in it you can see that the interacted blocks lie along the corkscrew path of the entity, however the parts of the corkscrew path are missing. This is because now each separate cardinal movement is handled separately and the collision raycast is performed separately for each axis, and as stated above, said raycast is capped to not cause game crashes, thus it skips the middles of the movements along cardinal directions.
How to replicate:
download the attached world, enter it in whichever version you want to observe the behavior (25w08a / 25w09b / 1.21.5-rc2).
run/tp -2.53 76.00 5.53 to get to the setup.
At the setup youll see 2 command blocks, one will spawn a fast tnt entity and highlight in red all of the strings it collided with in 1 tick. The second command block will clear the volume from red wool, in case you want to trigger the setup a second time, clear the volume before doing it.
Observe the red wool blocks, they indicate which strings were successfully triggered by fast tnt.
Observed behavior:
interactive collision checks follow a corkscrew path, with gaps in it
Expected behavior:
Either: fast entities check their path along a diagonal for interactive collisions as they did in 25w08a
Or: fast entities check their path along a corkscrew for interactive collisions, but without gaps in it (and the total length of the edges of the corckscrew path is capped to prevent reintroduction of MC-275437), while still calling the interactive collisions at the movement destination point, regardless of the cap, as it did previously in 25w08a (this is important, as some redstone contraptions rely on entities being able to press pressure plates at the destination of their movement). Please notice, that implementing corckscrew path where each separate arm is in itself a raycast (as it is done now 25w09a+) is very wastefull of performance as they can easily be replaced with much simpler logic while retaining the exact same behavior.
Both these options sound valid, unlike whatever it is currently doing in 1.21.5-rc2
Implications of current behavior(why its bad):
Currently (1.21.5-rc2) the entities will load the chunks outside the loaded area if shot fast enough (because one of the collision checks happens on the corner of the corckscrew, which lies outside render distance, when entity is shot far enough diagonally), they wont load their entire path, so it wont immideately crash the server as it did in MC-275437, but it drastically increases the lag from tnt warping cannons nonetheless :(
Current;y (1.21.5-rc2) the interactive collisions (of non projectile entities) are only ever checked in lines that are aligned with the coordinate axis, yet they still use the raycast logic to process each line. The raycast was specifically written to handle diagonal movements, and is incredibly expensive compared to just a loop interating over a single coordinate which will suffice to cover an axis aligned line without loss of the behavior.
As now im unable to edit my own reports, please check the comments to see if i added any additional info to the report.
Code Analysis and Proposed Solution:
https://gist.github.com/VelizarBG/053a5590cc28413b7abb28c6b3704481
Credits:
Velizar (@VelizarBG) - Code Analysis and Proposed Solution
Update 1.21.6-pr1
Some refactoring was done in 1.21.6-pr1 which worsened this issue.
Now instead of using the Movement vector to determine which direction the corkscrew of the raycast is twisted, it uses the dispplacement vector to do that, which obviously leads to the Interactive-collision-raycast-corcwcrew to twist in the opposite direction compared to direction in which the regular block face collision of the movement is twisted. This makes it so that the Interactive blocks are triggered far away from the actual path taken by the entity
(see the screenshot attached in the comment from 28.05.25). In it the entity block face collision goes in order: +y, +x, +z. But the interactive collision cast goes in order: +y, +z, +x. which makes is go though a wall which it isnt supposed to be even close to. Thus it goes through a wall.
Attachments
Comments 7
As of 25w32a:
The interactive collision check path still evaluates the corners of the corkscrew, which it should not do for the reasons outlined in the report above.
The interactive collision path sometimes fails to visit the end position of the movement.
The interactive collision path uses a movement vector that is not adjusted for block face collisions, causing it to differ from the actual direction of the entity's movement.
The
Entity.Movement#axisIndependant
field appears to be misspelled in the official Mojang mappings. It should be “axisIndependent, although based on the implementation, “axisDependent” sounds more appropriate.
The replication setup provided in this report still behaves almost identically to how it did in 25w31a and earlier. This suggests the fix may not have been fully verified before the issue was marked as resolved.
This would be the 11th time we (TMC) have to re-report issues related to interactive collisions, and it’s becoming increasingly frustrating - for us, and likely for you as well. We would be happy to provide a working fix to help ensure the issue is resolved correctly and prevent further back-and-forth. If you’re open to accepting a fix from our side, please let us know by replying to this comment.
Hey @Savvvage_, we would very much like to see this being resolved properly as well. Sorry to hear that there are still some issues remaining. We have a pending fix for not visiting the corkscrew corners. But it would be great to get some clarity on the other two issues you mention.
Could you expand on when the end position is not visited? Would be great to have a repro case for this. Could you also expand on the third point as well?
If you have any suggestions, that would also work great as an explanation.
The corkscrew path of interactive collision checks was likely implemented to fix the MC-276861 in 25w09a, which makes sense, so it would make sense to continue with it using a corkscrew path instead of a diagonal, but without gaps, capped and triggering the endmost point of the motion regardless of the cap.
If you are interested, the current cap is hardcoded within the
addCollisionsAlongTravel()
method within theBlockGetter
class. The cap is right now set to 16 iterations of the cast.