Foreword: I used mods and launched the game with a modified version of the source code to find the origin of the bug more easily but it can be reproduced in vanilla.
Problem:
The maximum range of a nether portal (PR) should be 128 blocks in the overworld, and 16 in the nether.
But it's actually 135 in the overworld instead of 128.
Reproduce the my test scenario:
These steps apply only to teleportation toward west, but I personally tested all the directions and obtained the same results.
Map setup:
Place two nether_portal block at (0,1,0) and (0,2,0) and in the overworld
Place two nether_portal block at (0,1,0) and (0,2,0) and in the nether.
These portals are equivalent to each other in both dimensions. They are our points of reference.
Steps to test the range of nether portals teleportation range for a number of blocks N:
Place two nether_portal block at (N,1,0) and (N,2,0) and in the overworld
Go through the portal
If you teleport to the reference portal at (0,1,0) in the nether, N <= PR. Else, if a new portal is generated, N > PR.
Don't forget to delete the new generated portal if needed.
You can also use my test map, all the portal are placed with explications:
Test map (I can't upload it directly, it's too big).
Results:
Expected results, limit at 128:
For N = 128: In range
For N = 129: Out of range
For N = 135: Out of range
For N = 136: Out of range
Real results, limit at 135:
For N = 128: In range
For N = 129: In range
For N = 135: In range
For N = 136: Out of range
Origin of the bug:
I generated the code using the most recent release of MCP Reborn.
I searched for the distance filter that defines the max teleportation range and found this function.
PoiManager.java
public Stream<PoiRecord> getInSquare(Predicate<Holder<PoiType>> predicate, BlockPos blockPos, int radius, PoiManager.Occupancy status) {
int i = Math.floorDiv(radius, 16) + 1;
return ChunkPos.rangeClosed(new ChunkPos(blockPos), i).flatMap((chunk) -> { // return all the portals in the chunks around blockPos
return this.getInChunk(predicate, chunk, status);
}).filter((portal) -> {
BlockPos portalPos = portal.getPos();
return Math.abs(portalPos.getX() - blockPos.getX()) <= radius && Math.abs(portalPos.getZ() - blockPos.getZ()) <= radius; // distance filter here
});
}
'blockPos' is the ideal position arrival portal. If you teleport from (128,1,0) in the overwolrd, 'blockPos' will be equal to (128/8, 1, 0/8) = (16, 1, 0) (ideal arrival coordinates in the nether).
'radius' will be equal 16 when teleporting form overworld to nether, and 128 when teleporting from nether to overworld.
It will first search all the portals in the chunks around that ideal coordinate, and then filter with the difference between 'radius' and the distance between the portal and 'blockPos'.
The problem come from 'blockPos': the values are integers.
I tested with a modified version of the game and printed the values when entering a portal (we have a portal at (0,1,0) in the nether):
Teleport from (128,1,0) | 128 / 8 = 16.000 | blockPos = (16,1,0) | 16 - 0 = 16 <= 16 | In range
Teleport from (129,1,0) | 129 / 8 = 16.125 | blockPos = (16,1,0) | 16 - 0 = 16 <= 16 | In range
Teleport from (135,1,0) | 135 / 8 = 16.875 | blockPos = (16,1,0) | 16 - 0 = 16 <= 16 | In range
Teleport from (136,1,0) | 136 / 8 = 17.000 | blockPos = (17,1,0) | 17 - 0 = 17 > 16 | Out of range
We can see here that 'blockPos' is the result of the floor division of your coordinate when you pass thought the portal in the overworld by 8. The problem is here: all 16.XX distance value in the nether bring us back to 16.
Suggested fix:
Add an 'idealOpposite' variable to the portal object to represent the ideal teleportation position in the arrival dimension.
Then, use this variable to always compare the range in the depart dimension.
@[[Mod] ampolive|https://bugs.mojang.com/secure/ViewProfile.jspa?name=ampolive] , I've seen this issue too and it's not a duplicate. MC-183103 refers to the portal mechanic introduced in 1.15. The range was too large because the search for the game was looking for the portal in the surrounding chunks, in a box of 17*17 chunks centered on the chunk containing the ideal block portal of arrival. It means that if your portal block was on the bordure of a chunk, the maximal teleportation distance was 8 * 16 + 15 = 143. You can see the diagram illustrating this below.
1.15 teleportation limit:
[media]In 1.16.2, they implemented a filter which acts after the detection of portals and which is supposed to bring the limit back to 128.
I represent it as a circle:
1.16.2 teleportation limit:
And the issue I reported is about this filter. It should be 128 blocks like on the schema, but it's 135 instead. So I think these issues are not the same.