Cubitect
- Cubitect
- cubitect
- Europe/London
- Yes
- No
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0
{NoAI:1}/summon Giant 0 64.02 0
{NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0
{NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
Also, this is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone
/summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item CANNOT fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.
Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */
packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D);
packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D);
packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */
double posX = (double)packetIn.getPosX() / 32.0D;
double posY = (double)packetIn.getPosY() / 32.0D;
double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the itemCAN fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e.MC-4)But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix:
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java
Entity.java
EntityTrackerEntry.java
S0EPacketSpawnObject.java
S2CPacketSpawnGlobalEntity.java
S0CPacketSpawnPlayer.java
S18PacketEntityTeleport.java
S0FPacketSpawnMob.java
S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
Also, this is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.
Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java
Entity.java
EntityTrackerEntry.java
S0EPacketSpawnObject.java
S2CPacketSpawnGlobalEntity.java
S0CPacketSpawnPlayer.java
S18PacketEntityTeleport.java
S0FPacketSpawnMob.java
S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
Also, this is probably the most common cause for MC-4. This can easily be reproduced with the following commands:/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.
Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java
Entity.java
EntityTrackerEntry.java
S0EPacketSpawnObject.java
S2CPacketSpawnGlobalEntity.java
S0CPacketSpawnPlayer.java
S18PacketEntityTeleport.java
S0FPacketSpawnMob.java
S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.
Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.
Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at(floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).
But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates(0.9, 81, 0.9). The itemcannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at(floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875)
. At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}or alternatively in a commandblock:
For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}or alternatively in a commandblock:
For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably also the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
Many of the packets concerning the communication about entities between server and client store integers with a conversion factor instead of the exact real numbers.
This causes a variety of issues in (to my knowledge) all versions of Minecraft up to now.
Examples of the implications are:1) It is impossible to specify the position of an entity using commands to any precision better than 1/32 of a block.
This can be seen for instance after:/summon Giant 0 64.00 0 {NoAI:1} /summon Giant 0 64.02 0 {NoAI:1}Both Giants will appear to be in the same position. However, a third Giant summoned at:
/summon Giant 0 64.04 0 {NoAI:1}will appear to hover 1/32 of a block higher than the other two giants.
2) This is probably also the most common cause for MC-4. This can easily be reproduced with the following commands:
/setblock 1 80 1 stone /summon Item 0.9 81 0.9 {Item:{id:1,Count:1}}For the client, the summoned item will visually appear to fall off the block. It then appears to teleport back to the top of the block every other second, only to start falling again.
The reason for this is that the sever knows that the item is at the given coordinates (0.9, 81, 0.9). The item cannot fall down from there as the item's hitbox touches the stone block. In mathematical terms this is: 0.9 + 0.125 > 1.0, where 0.125 is half the width of the item's hitbox.Now the client only knows what the server tells it via packets. However, the packets are created in the following manner:
/* pseudo java code */ packetOut.posX = (int)MathHelper.floor_double(entity.posX * 32.0D); packetOut.posY = (int)MathHelper.floor_double(entity.posY * 32.0D); packetOut.posZ = (int)MathHelper.floor_double(entity.posZ * 32.0D);The information is then recovered from the packet by the client with:
/* pseudo java code */ double posX = (double)packetIn.getPosX() / 32.0D; double posY = (double)packetIn.getPosY() / 32.0D; double posZ = (double)packetIn.getPosZ() / 32.0D;Thus, the client can only know about the position of the item (and any other entity) to a precision of 1/32 of a block.
So the client thinks the item is at (floor(0.9 * 32), 81, floor(0.9 * 32)) = (0.875, 81, 0.875). At this position the item can fall down, as the item's hitbox does just about not touch the stone block. In mathematical terms, 0.875 + 0.125 ≯ 1.0. As a result, the item appears to fall down for the client while the server keeps it on top of the block (i.e. MC-4).But it is not just the position of entities that is affected. Entity rotations are only stored to the nearest 1/256 of a full rotation (~1.41°). Also velocities are stored to the nearest 1/8000 block per tick. Furthermore, fixing this bug would allow map makers to use high precision entity manipulation to get rid of the Z-Fighting effect in their creations, by choosing small differences in positions.
Possible Fix
As a test I wrote a mod to mostly fix this issue by changing the variable types in the entity packets (see below for a list) from ints to doubles/floates and got rid of all occurences of multiplication/division factors involved. This means that rather than storing some discrete data, the packets contain the exact values used in the rest of the game code. As a result MC-4 seemed to be fixed as I could no longer reproduce it, and I was able to get rid of Z-fighting effects by teleporting/summoning entities to very slightly different coordinates.
I changed the following classes in my fix-mod (I only made it for 1.8.0 and single player, using MCP):
NetHandlerPlayClient.java Entity.java EntityTrackerEntry.java S0EPacketSpawnObject.java S2CPacketSpawnGlobalEntity.java S0CPacketSpawnPlayer.java S18PacketEntityTeleport.java S0FPacketSpawnMob.java S14PacketEntity.javaI noticed that in NetHandlerPlayClient.java the code that processes the S11PacketSpawnExperienceOrb packets (around line 456) does not have the '/ 32.0D' conversion (which I removed everywhere else by writing this mod). This is a bug that seems to be described by
MC-11601.
When you have a world with seed zero, i.e. when
/seedoutputs 0, then it cannot be recreated using the "Re-Create" option, because it will be interpreted as a random seed. To be clear, I know that putting "0" in the seed option is supposed to create a random world. However, I would expect that copying an existing world with seed 0 would also generate a world with seed 0.
To reproduce:
As mentioned, putting '0' in the seed option on the "Create New World" screen will be interpreted as a random seed (Personally I find this unintuitive behavior, but this has been resolved as intended:MC-1820). However, a world with the seed 0 can be generated either through external tools, or by choosing the seed text very carefully. Here are sometexts for theseed option, that will gernerate a world with seed 0:tainsntoh f5a5a608 af4e962cdWhen you have a world with seed zero, i.e. when
/seedoutputs 0, then it cannot be recreated using the "Re-Create" option, because it will be interpreted as a random seed. To be clear, I know that putting "0" in the seed option is supposed to create a random world. However, I would expect that copying an existing world with seed 0 would also generate a world with seed 0.
To reproduce:
As mentioned, putting '0' in the seed option on the "Create New World" screen will be interpreted as a random seed (Personally I find this unintuitive behavior, but this has been resolved as intended:MC-1820). However, a world with the seed 0 can be generated either through external tools, or by choosing the seed text very carefully. Here are some options for the text, that will gernerate a world with seed 0:tainsntoh f5a5a608 af4e962cd
A world with seed 0 cannot be copied using the "Re-Create" option
Noise to biome mapping depends on previous sampling position
While doing a code analysis of the new biome generation, I ran into inconsistent biome placement with the MultiNoiseBiomeSource. This will cause discrepancies between worlds with the same seed that are most likely to cause headaches in the future.
The problem is easiest to demonstrate with a small test function
, as the discrepancies are difficult to demonstrate with in-game functionality:public void inconsistentBiomeSampling() { // Get an overworld biome source MultiNoiseBiomeSource bs = MultiNoiseBiomeSource.Preset.OVERWORLD .getBiomeSource(BuiltinRegistries.BIOME); // Get a noise sampler for a seed long seed = 7; ChunkGeneratorSettings gen = ChunkGeneratorSettings.getInstance(); NoiseColumnSampler noise = new NoiseColumnSampler( gen.getGenerationShapeConfig(), gen.hasNoiseCaves(), seed, BuiltinRegistries.NOISE_PARAMETERS, gen.getRandomProvider()); // Example of biome coordinates for this seed where the sampling // is inconsistent. int x = 116, y = 15, z = 0; // First sample the biome when no previous result is cached. // (This is a local optimum.) Biome b1 = bs.getBiomeAtPoint(noise.sample(x, y, z)); // Now sample a position nearby that may be a better fit to the // first sampling point. bs.getBiomeAtPoint(noise.sample(x, y, z+1)); // Checking the first sampling point again gets the cached result // from the last call, if that node was a better fit. Biome b2 = bs.getBiomeAtPoint(noise.sample(x, y, z)); if (b1 != b2) { System.out.println( "seed:"+seed+"@["+x+","+y+","+z+"] "+ "can have biomes: "+b1+" or "+b2); } }Which outputs:
seed:7@[116,15,0] can have biomes: minecraft:ocean or minecraft:cold_oceanThe inconsistency arises from the SearchTree that is used to map noise points to biomes. In its current form, it does not always find the biome with the smallest distance in the noise parameter space. This may be a sacrifice that has been made for performance, which is not pretty, but not necessarily a problem as long as there remains a unique mapping from noise values to biomes. However, another optimization that has been done, is caching the
node of the last resultfrom the lasscall. Reusing this node is incorrect, as it might result in a biome that isacloser to the sampling noise point than what the SearchTree would normally find.Below is a graphic with a 2D example outlining why this is the case.
The relevant methods are located in MultiNoiseUtil.java:
public T get(NoiseValuePoint point, NodeDistanceFunction<T> distanceFunction) { long[] ls = point.getNoiseValueList(); // Caching previousResultNode is problematic TreeLeafNode<T> treeLeafNode = this.firstNode.getResultingNode(ls, this.previousResultNode.get(), distanceFunction); this.previousResultNode.set(treeLeafNode); return treeLeafNode.value; } @Override protected TreeLeafNode<T> getResultingNode(long[] otherParameters, @Nullable TreeLeafNode<T> alternative, NodeDistanceFunction<T> distanceFunction) { // Suggestion: the distance for 'alternative' is already known by the recursive caller and could be passed as an argument. long l = alternative == null ? Long.MAX_VALUE : distanceFunction.getDistance(alternative, otherParameters); TreeLeafNode<T> treeLeafNode = alternative; for (TreeNode<T> treeNode : this.subTree) { long n; long m = distanceFunction.getDistance(treeNode, otherParameters); if (l <= m) continue; TreeLeafNode<T> treeLeafNode2 = treeNode.getResultingNode(otherParameters, treeLeafNode, distanceFunction); long l2 = n = treeNode == treeLeafNode2 ? m : distanceFunction.getDistance(treeLeafNode2, otherParameters); if (l <= n) continue; l = n; treeLeafNode = treeLeafNode2; } return treeLeafNode; }Remark:
Discrepancies of biomes inside the anvil chunk storage between multiple generations of the same world will be very rare since the generator iterates over the biome points inside each chunk in the same order. This means the wrong biomes will at least be more or less consistent across different worlds with the same seed. However, biome sampling anywhere else in the code, such as in structure generation etc., that don't read directly from the chunk storage, will often disagree with the saved biomes near biome borders.
Noise to biome mapping depends on previous sampling position
While doing a code analysis of the new biome generation, I ran into inconsistent biome placement with the MultiNoiseBiomeSource. This will cause discrepancies between worlds with the same seed that are most likely to cause headaches in the future. For example, this affects structure generation near biome borders and a fix will completely change stronghold positions! (Strongholds are highly dependent on generation order and biome positions.)
The problem is easiest to demonstrate with a small test function:
public void inconsistentBiomeSampling() { // Get an overworld biome source MultiNoiseBiomeSource bs = MultiNoiseBiomeSource.Preset.OVERWORLD .getBiomeSource(BuiltinRegistries.BIOME); // Get a noise sampler for a seed long seed = 7; ChunkGeneratorSettings gen = ChunkGeneratorSettings.getInstance(); NoiseColumnSampler noise = new NoiseColumnSampler( gen.getGenerationShapeConfig(), gen.hasNoiseCaves(), seed, BuiltinRegistries.NOISE_PARAMETERS, gen.getRandomProvider()); // Example of biome coordinates for this seed where the sampling // is inconsistent. int x = 116, y = 15, z = 0; // First sample the biome when no previous result is cached. // (This is a local optimum.) Biome b1 = bs.getBiomeAtPoint(noise.sample(x, y, z)); // Now sample a position nearby that may be a better fit to the // first sampling point. bs.getBiomeAtPoint(noise.sample(x, y, z+1)); // Checking the first sampling point again gets the cached result // from the last call, if that node was a better fit. Biome b2 = bs.getBiomeAtPoint(noise.sample(x, y, z)); if (b1 != b2) { System.out.println( "seed:"+seed+"@["+x+","+y+","+z+"] "+ "can have biomes: "+b1+" or "+b2); } }Which outputs:
seed:7@[116,15,0] can have biomes: minecraft:ocean or minecraft:cold_oceanThe inconsistency arises from the SearchTree that is used to map noise points to biomes. In its current form, it does not always find the biome with the smallest distance in the noise parameter space. This may be a sacrifice that has been made for performance, which is not pretty, but not necessarily a problem as long as there remains a unique mapping from noise values to biomes. However, another optimization that has been done, is caching the resulting node from the last call. Reusing this node is incorrect, as it might result in a biome that is closer to the sampling noise point than what the SearchTree would normally find.
Below is a graphic with a 2D example outlining why this is the case.
The relevant methods are located in MultiNoiseUtil.java:
public T get(NoiseValuePoint point, NodeDistanceFunction<T> distanceFunction) { long[] ls = point.getNoiseValueList(); // Caching previousResultNode is problematic TreeLeafNode<T> treeLeafNode = this.firstNode.getResultingNode(ls, this.previousResultNode.get(), distanceFunction); this.previousResultNode.set(treeLeafNode); return treeLeafNode.value; } @Override protected TreeLeafNode<T> getResultingNode(long[] otherParameters, @Nullable TreeLeafNode<T> alternative, NodeDistanceFunction<T> distanceFunction) { // Suggestion: the distance for 'alternative' is already known by the recursive caller and could be passed as an argument. long l = alternative == null ? Long.MAX_VALUE : distanceFunction.getDistance(alternative, otherParameters); TreeLeafNode<T> treeLeafNode = alternative; for (TreeNode<T> treeNode : this.subTree) { long n; long m = distanceFunction.getDistance(treeNode, otherParameters); if (l <= m) continue; TreeLeafNode<T> treeLeafNode2 = treeNode.getResultingNode(otherParameters, treeLeafNode, distanceFunction); long l2 = n = treeNode == treeLeafNode2 ? m : distanceFunction.getDistance(treeLeafNode2, otherParameters); if (l <= n) continue; l = n; treeLeafNode = treeLeafNode2; } return treeLeafNode; }Remark:
The bug primarily causes different parts of the code to disagree about the biomes, especially near biome borders. This has potential, among other things, to make the population of chunks depend on the order in which the world is generated. However, biomes inside the anvil chunk storage between multiple generations of the same world will most likely be consistent (although wrong) since the generator iterates over the biome points inside each chunk in the same order.
Noise to biome mapping depends on previous sampling position
While doing a code analysis of the new biome generation, I ran into inconsistent biome placement with the MultiNoiseBiomeSource. This will cause discrepancies between worlds with the same seed that are most likely to cause headaches in the future. For example, this affects structure generation near biome borders and a fix will completely change stronghold positions! (Strongholds are highly dependent on
generation order and biome positions.)The problem is easiest to demonstrate with a small test function:
public void inconsistentBiomeSampling() { // Get an overworld biome source MultiNoiseBiomeSource bs = MultiNoiseBiomeSource.Preset.OVERWORLD .getBiomeSource(BuiltinRegistries.BIOME); // Get a noise sampler for a seed long seed = 7; ChunkGeneratorSettings gen = ChunkGeneratorSettings.getInstance(); NoiseColumnSampler noise = new NoiseColumnSampler( gen.getGenerationShapeConfig(), gen.hasNoiseCaves(), seed, BuiltinRegistries.NOISE_PARAMETERS, gen.getRandomProvider()); // Example of biome coordinates for this seed where the sampling // is inconsistent. int x = 116, y = 15, z = 0; // First sample the biome when no previous result is cached. // (This is a local optimum.) Biome b1 = bs.getBiomeAtPoint(noise.sample(x, y, z)); // Now sample a position nearby that may be a better fit to the // first sampling point. bs.getBiomeAtPoint(noise.sample(x, y, z+1)); // Checking the first sampling point again gets the cached result // from the last call, if that node was a better fit. Biome b2 = bs.getBiomeAtPoint(noise.sample(x, y, z)); if (b1 != b2) { System.out.println( "seed:"+seed+"@["+x+","+y+","+z+"] "+ "can have biomes: "+b1+" or "+b2); } }Which outputs:
seed:7@[116,15,0] can have biomes: minecraft:ocean or minecraft:cold_oceanThe inconsistency arises from the SearchTree that is used to map noise points to biomes. In its current form, it does not always find the biome with the smallest distance in the noise parameter space. This may be a sacrifice that has been made for performance, which is not pretty, but not necessarily a problem as long as there remains a unique mapping from noise values to biomes. However, another optimization that has been done, is caching the resulting node from the last call. Reusing this node is incorrect, as it might result in a biome that is closer to the sampling noise point than what the SearchTree would normally find.
Below is a graphic with a 2D example outlining why this is the case.
The relevant methods are located in MultiNoiseUtil.java:
public T get(NoiseValuePoint point, NodeDistanceFunction<T> distanceFunction) { long[] ls = point.getNoiseValueList(); // Caching previousResultNode is problematic TreeLeafNode<T> treeLeafNode = this.firstNode.getResultingNode(ls, this.previousResultNode.get(), distanceFunction); this.previousResultNode.set(treeLeafNode); return treeLeafNode.value; } @Override protected TreeLeafNode<T> getResultingNode(long[] otherParameters, @Nullable TreeLeafNode<T> alternative, NodeDistanceFunction<T> distanceFunction) { // Suggestion: the distance for 'alternative' is already known by the recursive caller and could be passed as an argument. long l = alternative == null ? Long.MAX_VALUE : distanceFunction.getDistance(alternative, otherParameters); TreeLeafNode<T> treeLeafNode = alternative; for (TreeNode<T> treeNode : this.subTree) { long n; long m = distanceFunction.getDistance(treeNode, otherParameters); if (l <= m) continue; TreeLeafNode<T> treeLeafNode2 = treeNode.getResultingNode(otherParameters, treeLeafNode, distanceFunction); long l2 = n = treeNode == treeLeafNode2 ? m : distanceFunction.getDistance(treeLeafNode2, otherParameters); if (l <= n) continue; l = n; treeLeafNode = treeLeafNode2; } return treeLeafNode; }Remark:
The bug primarily causes different parts of the code to disagree about the biomes, especially near biome borders. This has potential, among other things, to make the population of chunks depend on the order in which the world is generated. However, biomes inside the anvil chunk storage between multiple generations of the same world will most likely be consistent (although wrong) since the generator iterates over the biome points inside each chunk in the same order.
Noise to biome mapping depends on previous sampling position
While doing a code analysis of the new biome generation, I ran into inconsistent biome placement with the MultiNoiseBiomeSource. This will cause discrepancies between worlds with the same seed that are most likely to cause headaches in the future. For example, this affects structure generation near biome borders and a fix will completely change outer stronghold positions! (Strongholds are highly dependent on biome positions, and each stronghold depends on those generated before it.)
The problem is easiest to demonstrate with a small test function:
public void inconsistentBiomeSampling() { // Get an overworld biome source MultiNoiseBiomeSource bs = MultiNoiseBiomeSource.Preset.OVERWORLD .getBiomeSource(BuiltinRegistries.BIOME); // Get a noise sampler for a seed long seed = 7; ChunkGeneratorSettings gen = ChunkGeneratorSettings.getInstance(); NoiseColumnSampler noise = new NoiseColumnSampler( gen.getGenerationShapeConfig(), gen.hasNoiseCaves(), seed, BuiltinRegistries.NOISE_PARAMETERS, gen.getRandomProvider()); // Example of biome coordinates for this seed where the sampling // is inconsistent. int x = 116, y = 15, z = 0; // First sample the biome when no previous result is cached. // (This is a local optimum.) Biome b1 = bs.getBiomeAtPoint(noise.sample(x, y, z)); // Now sample a position nearby that may be a better fit to the // first sampling point. bs.getBiomeAtPoint(noise.sample(x, y, z+1)); // Checking the first sampling point again gets the cached result // from the last call, if that node was a better fit. Biome b2 = bs.getBiomeAtPoint(noise.sample(x, y, z)); if (b1 != b2) { System.out.println( "seed:"+seed+"@["+x+","+y+","+z+"] "+ "can have biomes: "+b1+" or "+b2); } }Which outputs:
seed:7@[116,15,0] can have biomes: minecraft:ocean or minecraft:cold_oceanThe inconsistency arises from the SearchTree that is used to map noise points to biomes. In its current form, it does not always find the biome with the smallest distance in the noise parameter space. This may be a sacrifice that has been made for performance, which is not pretty, but not necessarily a problem as long as there remains a unique mapping from noise values to biomes. However, another optimization that has been done, is caching the resulting node from the last call. Reusing this node is incorrect, as it might result in a biome that is closer to the sampling noise point than what the SearchTree would normally find.
Below is a graphic with a 2D example outlining why this is the case.
The relevant methods are located in MultiNoiseUtil.java:
public T get(NoiseValuePoint point, NodeDistanceFunction<T> distanceFunction) { long[] ls = point.getNoiseValueList(); // Caching previousResultNode is problematic TreeLeafNode<T> treeLeafNode = this.firstNode.getResultingNode(ls, this.previousResultNode.get(), distanceFunction); this.previousResultNode.set(treeLeafNode); return treeLeafNode.value; } @Override protected TreeLeafNode<T> getResultingNode(long[] otherParameters, @Nullable TreeLeafNode<T> alternative, NodeDistanceFunction<T> distanceFunction) { // Suggestion: the distance for 'alternative' is already known by the recursive caller and could be passed as an argument. long l = alternative == null ? Long.MAX_VALUE : distanceFunction.getDistance(alternative, otherParameters); TreeLeafNode<T> treeLeafNode = alternative; for (TreeNode<T> treeNode : this.subTree) { long n; long m = distanceFunction.getDistance(treeNode, otherParameters); if (l <= m) continue; TreeLeafNode<T> treeLeafNode2 = treeNode.getResultingNode(otherParameters, treeLeafNode, distanceFunction); long l2 = n = treeNode == treeLeafNode2 ? m : distanceFunction.getDistance(treeLeafNode2, otherParameters); if (l <= n) continue; l = n; treeLeafNode = treeLeafNode2; } return treeLeafNode; }Remark:
The bug primarily causes different parts of the code to disagree about the biomes, especially near biome borders. This has potential, among other things, to make the population of chunks depend on the order in which the world is generated. However, biomes inside the anvil chunk storage between multiple generations of the same world will most likely be consistent (although wrong) since the generator iterates over the biome points inside each chunk in the same order.
To reproduce:
- Create New World.
- Select "Customized" World type.
- Click on "Customize".
- Choose any biome after "River", click "Done".
- Re-click on "Customize", see the slider has moved forward 2 ticks.
Also:
- If "Mesa Plateau F" or "Mesa Plateau" biome is chosen,
- Re-click on "Customize", see the slider is graphically off its track, and the label simply reads "Biome: ?".
- (Does not crash in 1.11.2 and forward, but has previously caused a crash, see attachment)
Code analysis by Cubitect can be found in this comment.
Cubitect Please do not hit save when making constant edits, all watchers will get repeated emails each time. There is a preview button you can use if you are unsure of what the edits will look like.
Please link in the description to Cubitect's code analysis

I just did some more testing and code digging and as far as I can tell there are two types of packets that are called rather often:
The S14PacketEntity packets do indeed contain size optimised data. Single bytes represent an offset to the current position in 1/32 blocks (which allows for changes of about +-4 blocks).
Assuming a boolean is one byte, then a S14PacketEntity packet would (probably) have a size of 11 bytes.
The S18PacketEntityTeleport seems to be called rather often as well, in particular it seems to be called when an entity moves fairly quickly, e.g. whenever it jumps. This packet contains the absolute positions in 1/32 blocks in the form of ints. Again assuming a boolean is one byte, then a S18PacketEntityTeleport packet would (probably) have a size of 19 bytes.
The ints in the S18PacketEntityTeleport class could easily be replaced with floats, which for the most part would already fix the issues I described, without increasing the packet sizes at all. Furthermore one could use a form of half-precision floats (2 bytes) or other minifloats instead of the one-byte integers, which would increase the resolution considerably, without increasing the packet sizes too much.
All the other packets concerned (S0FPacketSpawnMob, S0EPacketSpawnObject etc.) are called less often and use ints, just like S18PacketEntityTeleport. So they should probably also use doubles or at least floats instead.
This line of code causes the server to sleep for a minimum of 1 ms.
I can confirm this for both java 7 and 8 under Ubuntu 15.04.
Using the internal representation would be preferable to making it harder to reproduce.
Bundling the packets to the chunks seems like a good option to me. The grid-snapping might cause problems with the motion (assuming ints are used for the motion as well). This would become especially noticeable at slow speed and small angles.
Also I just did a few tests and it seems that about three quarters of the S15PacketEntityRelMove packets store a Y-change of zero. This is probably due to all the mobs that are moving while staying on the ground. It would be unnecessary to store the full 8 bytes of a double for this very common case. So separating ground motion and other motion could be an option to consider.
This bug is caused from dealing with the Hell and Sky biomes in a bad manner. The intended behavior was apparently to remove those biomes from the list in the biome selector. However, this offset in biomeIDs is dealt with in the wrong bit of code: in the preset string interpretation, which is often executed multiple times (e.g. when the "Customize World Settings" are opened). Instead, the offset calculation should be done immediately where the value of the slider is evaluated.
There are two easy fixes that could be done here. The first option is the simplest and my favorite, which is simply to keep the Hell and Sky in the biome selector. They don't really harm anyone. The second option would be to do the offset management right at the slider read out, just as I mentioned.
I will also try to explain this bug and fixes in terms of code. I got the original code through MCP, but I will only show the key bits here, with a bunch of variables renamed, to help convey the information (also so I'm not posting actual source code).
Current code:
As I mentioned, this bit of code is in totally the wrong place! Nothing in this class should deal with any sort of offset, as it may be called multiple times.
An implementation of the the first fix would be:
An implementation of the the second fix would be:
Also, in order to get the right position of the slider upon reload, one has to change the default value of the slider, to revert the offset.
After "createWorld.customize.custom.fixedBiome" in GuiCustomizeWorldScreen.java, change
to
After this overkill of a comment I should mention that I can confirm this bug (not the crash, but the offsets) in versions 1.8, 1.8.8 and 15w49b
P.S.
I tested the all the fixes in MCP for 1.8.
I agree. The seed text should be left empty for a random seed. If I specify that I want my seed to be '0' then it should be zero. I found it a little irritating that I couldn't even copy the world once I actually had one with seed zero.
No, this just causes the game thinks that a location has a different biome, depending on which part of the code is looking. Also it affects mostly just the location of biome borders, not the generation as a whole.
Regarding the large biomes in 1.18-pre1, the random number generators now get initialized with an MD5 hash of the generator name. This noise generator name is "minecraft:temperature" for normal generation and "minecraft:temperature_large" with large biomes and similar for the other noise parameters. This means the noise generation is completely different for large biomes.
This is probably caused by the change that the noise sources now get initialized with an MD5 hash of the noise generator name, which are different for large biomes (e.g. "minecraft:temperature" and "minecraft:temperature_large"). In previous versions the layered biome generation was (almost) just an up-scaling of the normal generation.
Added a warning that this has a major affect on stronghold positions and should preferably be fixed before the main release.