The bug
When entering a tall portal that takes you to a short portal from the top, you take suffocation damage. This also happens when going from a wide portal to a thin portal.
How to reproduce
Download the attached test world
Enter the portal from the very top platform (you should spawn at it; be careful not to fall down inside the portal)
Observe that when you enter the nether, note blocks triggered by pressure plates on top of the portal play, and you take a few hits of suffocation damage. (Also, you spawn at y=46.71429, while the max y you can fly up to under the portal is 45.2)
Code analysis
By @unknown, based on 1.12.2 decompiled using MCP 9.40. The problem is that the player's height and width aren't accounted for in net.minecraft.entity.Entity.setPortal(BlockPos)
when calculating lastPortalVec
. Player height and width then also need to be accounted for in net.minecraft.world.Teleporter.placeInExistingPortal(Entity, float)
.
Related issues
is duplicated by
relates to
Attachments
Comments

here is the partial solution that I implemented (names based on MCP 9.40 pre1)
Location: world/Teletporter.java#placeInExistingPortal
double d5 = (double)blockpos.getX() + 0.5D;
double d7 = (double)blockpos.getZ() + 0.5D;
BlockPattern.PatternHelper blockpattern$patternhelper = Blocks.PORTAL.createPatternHelper(this.worldServerInstance, blockpos);
boolean flag1 = blockpattern$patternhelper.getForwards().rotateY().getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE;
double d2 = blockpattern$patternhelper.getForwards().getAxis() == EnumFacing.Axis.X ? (double)blockpattern$patternhelper.getFrontTopLeft().getZ() : (double)blockpattern$patternhelper.getFrontTopLeft().getX();
double d6 = (double)(blockpattern$patternhelper.getFrontTopLeft().getY() + 1) - entityIn.getLastPortalVec().yCoord * (double)blockpattern$patternhelper.getHeight();
if (flag1)
{
++d2;
}
//CM portalSuffocationFix
//removed offset calculation outside of the if statement
double offset = (1.0D - entityIn.getLastPortalVec().xCoord) * (double)blockpattern$patternhelper.getWidth() * (double)blockpattern$patternhelper.getForwards().rotateY().getAxisDirection().getOffset();
//CarpetSettings.LOG.info("[CM]offset, width: "+offset+", "+blockpattern$patternhelper.getWidth());
if (CarpetSettings.getBool("portalSuffocationFix"))
{
// correcting to fit within 98% of the exit portal to account for FP rounding errors - optional
double entity_corrected_radius = 1.02*(double)entityIn.width/2;
if (entity_corrected_radius >= (double)blockpattern$patternhelper.getWidth()-entity_corrected_radius)
{
//entity is wider than portal, so will suffocate anyways, so place it directly in the middle
entity_corrected_radius = (double)blockpattern$patternhelper.getWidth()/2-0.001;
}
if (offset >= 0) // offset can be positive or negative depending on the portal orientation and world quadrant
//I am here clamping the offset to fit in the portal, other option would be scale in it, but this was easier to implement
{
offset = MathHelper.clamp(offset, entity_corrected_radius, (double)blockpattern$patternhelper.getWidth()-entity_corrected_radius);
}
else
{
offset = MathHelper.clamp(offset, -(double)blockpattern$patternhelper.getWidth()+entity_corrected_radius, -entity_corrected_radius);
}
//CarpetSettings.LOG.info(" [CM]offset corrected to: "+offset);
}
if (blockpattern$patternhelper.getForwards().getAxis() == EnumFacing.Axis.X)
{
d7 = d2 + offset;
}
else
{
d5 = d2 + offset;
}
its a partial fix - fixes offset in X and Z dimentions, not the Y. In essence translated offset in the exit portal doesn't account for enity width/height which may end up it spawning inside obsidian blocks.
Side note - I presented the fix in a video of mine with a poll (along other fixes and QOL improvements and this one got the most upvotes)

This also occurs for wide portals - in a 5 block wide portal, teleporting from the end of either side causes the player to be teleported inside the nether portal frame, taking suffocation damage and being pushed inside the nether portal.

If the portal is 1 tall, it should make you crawl in the 1 tall space instead of taking suffocation damage.

Can confirm, if I enter a 3x3 portal and I am supposed to exit a 2x3 portal, I suffocate.

Cannot reproduce in 1.16.2.
[media]

Is this still an issue in 1.16.3 or later? It might have been fixed with some recent portal changes.

It seems to have been fixed with some portal changes in 20w28a, along with MC-80032.