UPD: I reported this on the bug tracker, vote pls so Mojang fix that - https://bugs.mojang.com/browse/MC-312755
UPD2: they won't fix that cause it's minor or "impossible to change without large architectural changes"✌️😭
Prequel
If you haven't seen it yet, Swight just uploaded a video breaking down how he lost PvP Champs 2 because his crossbow shot went through Coldi, straight through the fire, and broke his TNT minecart instead of exploding it:
https://www.youtube.com/watch?v=fR4_sXA91ks
In the video Swight assumed that hitting a player makes the game think the arrow isn't on fire for "1 pixel worth of time" (spoiler, that's true). I looked into Minecraft source code to see how is this possible, this is just dumb.. like literally..
What actually happened
Normally, a crossbow arrow travels ~3.15 blocks per game tick. Because Swight, Coldi, the fire, and the TNT minecart were all right next to each other, the arrow crossed all of them in the exact same game tick
When a piercing arrow flies, it runs a loop in the code that is supposed to move the arrow from one target to the next, checking any blocks (like fire or lava) in between. Instead of doing things in normal order (hit Coldi -> touch fire -> hit cart), Minecraft’s piercing code freaks out when multiple entities are in the arrow's path during the same tick and does everything out of order:
- First, the arrow moves to the first target (Coldi) and checks for fire blocks along the path up to that point. Since the fire is behind Coldi, the arrow is still not on fire
- Instead of moving forward to check the blocks behind Coldi, the code immediately loops through and damages EVERY entity in that tick's path back-to-back. So while the arrow's actual position is still stuck at Coldi (before the fire), it reaches ahead and hits the TNT minecart as an unlit arrow - instantly breaking it instead of blowing it up..
- Only after both Coldi and the minecart take damage, the arrow finally finishes moving through the rest of its path, crossing the fire block and lighting itself on fire. That’s why the arrow still looks like it's on fire piercing and right after breaking the cart
Why did moving the cart "1 pixel" back fix it?
That 1 pixel is the exact cutoff where the arrow's 1st tick of movement ends right inside the fire block, so the arrow has to wait until the 2nd tick to hit the minecart - and by then, it already registered the fire from the tick 1
The fun part: how to fix that?
Even if you don't know how to code, istg you will see how dumb this is, whoever coded piercing arrows already wrote a loop that goes through targets one-by-one. They just accidentally told the game to damage the whole list of targets at once instead of just the closest target:
// What Mojang wrote (damages every entity in the path BEFORE checking blocks between them):
ProjectileDeflection deflection = this.hitTargetsOrDeflectSelf(entitiesHit);
// The 1-line fix (only hit the first entity, then let the arrow move through the fire to the next one):
ProjectileDeflection deflection = this.hitTargetOrDeflectSelf(firstEntityHit);
Literally a ONE-line change and we would see Swight winning that game and the tournament :)
Multi-billionaire-level coding ladies and mentlegen, just wtf (it's a joke, I love Mojang)