[MC-10046] Random destination routine has a small statistical tendency to move more north west (fix included) Created: 19/Feb/13 Updated: 10/May/20 Resolved: 24/May/16 |
|
| Status: | Resolved |
| Project: | Minecraft: Java Edition |
| Component/s: | None |
| Affects Version/s: | Minecraft 1.4.7, Minecraft 1.5, Minecraft 1.6.1, Minecraft 1.6.2, Minecraft 1.6.4, Minecraft 1.7.2 |
| Fix Version/s: | Minecraft 14w02a, Minecraft 16w21a |
| Type: | Bug | ||
| Reporter: | Markku | Assignee: | [Mojang] Grum (Erik Broes) |
| Resolution: | Fixed | Votes: | 22 |
| Labels: | None | ||
| Attachments: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| CHK: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Confirmation Status: | Plausible | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Game Mode: | Creative | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
Update (see https://bugs.mojang.com/browse/MC-10046?focusedCommentId=304613&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-304613): This bug is somewhat difficult (or at least slow) to reproduce, because it needs a long time and controlled environment to be noticed. While issue It should affect both survival and creative, and any and all activities and mob types that use the same method. Some activities are not affected as badly by this, as they do not accumulate over time.
The bug
2) The result is then added the Math.floor(entity.pos) to make it absolute coordinate. However, this truncation discards any fractional part of entity position (towards north and west), and the thrown away part is never brought back or compensated. The end effect is seen as tendency to move, on the average, about 0.6 to 0.9 blocks per AI activity launched towards north west. I confirmed this by letting the game keep calculating the average relative movements over couple thousand "wanderings", both for villagers and for chickens (separately for each type), and results were indeed values like -0.6 to -0.9 (fits within normal random differences due to "small" set of data). (The expected value would naturally be very near 0.) Showing the original method in complete as the changes are quite spread in it. Using MCP naming and my own renamings. RandomPositionGenerator private static Vec3 findRandomTargetBlock(EntityCreature entity, int hor, int ver, Vec3 inDir) { Random rng = entity.getRNG(); boolean foundTarget = false; int x = 0; int y = 0; int z = 0; float bestValue = -99999.0F; boolean var10; if (entity.hasHome()) { double var11 = (double) (entity.getHomePosition().getDistanceSquared(MathHelper.floor_double(entity.posX), MathHelper.floor_double(entity.posY), MathHelper.floor_double(entity.posZ)) + 4.0F); double var13 = (double) (entity.getMaximumHomeDistance() + (float) hor); var10 = var11 < var13 * var13; } else { var10 = false; } for (int var16 = 0; var16 < 10; ++var16) { int var12 = rng.nextInt(2 * hor) - hor; int var17 = rng.nextInt(2 * ver) - ver; int var14 = rng.nextInt(2 * hor) - hor; if (inDir == null || (double) var12 * inDir.xCoord + (double) var14 * inDir.zCoord >= 0.0D) { var12 += MathHelper.floor_double(entity.posX); var17 += MathHelper.floor_double(entity.posY); var14 += MathHelper.floor_double(entity.posZ); if (!var10 || entity.isWithinHomeDistance(var12, var17, var14)) { float pathValue = entity.getBlockPathWeight(var12, var17, var14); if (pathValue > bestValue) { bestValue = pathValue; x = var12; y = var17; z = var14; foundTarget = true; } } } } if (foundTarget) { return entity.worldObj.getWorldVec3Pool().getVecFromPool((double) x, (double) y, (double) z); } else { return null; } } The fix 2) Use the truncated absolute destination position for checking various things, but then the full value to set where to move. Thus, the effect will be 0. RandomPositionGenerator private static Vec3 findRandomTargetBlock(EntityCreature entity, int hor, int ver, Vec3 inDir) { Random rng = entity.getRNG(); boolean foundTarget = false; double x = 0; double y = 0; double z = 0; float bestValue = -99999.0F; boolean var10; if (entity.hasHome()) { double var11 = (double) (entity.getHomePosition().getDistanceSquared(MathHelper.floor_double(entity.posX), MathHelper.floor_double(entity.posY), MathHelper.floor_double(entity.posZ)) + 4.0F); double var13 = (double) (entity.getMaximumHomeDistance() + (float) hor); var10 = var11 < var13 * var13; } else { var10 = false; } for (int var16 = 0; var16 < 10; ++var16) { int var12 = rng.nextInt(2 * hor + 1) - hor; int var17 = rng.nextInt(2 * ver + 1) - ver; int var14 = rng.nextInt(2 * hor + 1) - hor; if (inDir == null || (double) var12 * inDir.xCoord + (double) var14 * inDir.zCoord >= 0.0D) { int var12b = var12 + MathHelper.floor_double(entity.posX); int var17b = var17 + MathHelper.floor_double(entity.posY); int var14b = var14 + MathHelper.floor_double(entity.posZ); if (!var10 || entity.isWithinHomeDistance(var12b, var17b, var14b)) { float pathValue = entity.getBlockPathWeight(var12b, var17b, var14b); if (pathValue > bestValue) { bestValue = pathValue; x = entity.posX + var12; y = entity.posY + var17; z = entity.posZ + var14; foundTarget = true; } } } } if (foundTarget) { return entity.worldObj.getWorldVec3Pool().getVecFromPool(x, y, z); } else { return null; } } When testing the fixes on 1.4.7, the corresponding results for chickens were now like this: "Average wander delta now (3477): -0,0538, 2,0290, 0,0060". Very decent values, though they do naturally vary randomly from run to run, with small values on both sides of zero (as expected). Ignore the vertical delta of 2; chickens' specialty. The 3477 is how many wanderings were averaged. Minor optimization possibility in the same method, while at it |
| Comments |
| Comment by Anomonous Anomonous [ 08/Jun/16 ] |
|
I'm curious if this bug also affects pocket edition. |
| Comment by [Mojang] Grum (Erik Broes) [ 24/May/16 ] |
|
Please verify it works as it should after the next snapshot! Thanks for the infos |
| Comment by Markku [ 14/May/16 ] |
|
For easier check of its history, I'm just going to strike-through the rest, keeping point 2. I can not reduce the code parts, and most of the description still applies (even if e.g. with slightly different numbers), so it wasn't much of a reduction. Should be clear that point 1 is not in effect, though. |
| Comment by user-f2760 (Inactive) [ 14/May/16 ] |
|
Reopened, bugi74 please reduce the report to point 2 only. |
| Comment by Marcono1234 [ 14/May/16 ] |
|
Please link to this comment in the description The following is based on a decompiled version of Minecraft 1.9 using MCP 9.24 beta. The second part of this bug is not fixed in 1.9
/** * searches 10 blocks at random in a within par1(x,z) and par2 (y) distance, ignores those not in the direction of * par3Vec3, then points to the tile for which creature.getBlockPathWeight returns the highest number */ private static Vec3d findRandomTargetBlock(EntityCreature entitycreatureIn, int xz, int y, Vec3d targetVec3) { PathNavigate pathnavigate = entitycreatureIn.getNavigator(); Random random = entitycreatureIn.getRNG(); boolean flag = false; int i = 0; int j = 0; int k = 0; float f = -99999.0F; boolean flag1; //... for (int j1 = 0; j1 < 10; ++j1) { int l = random.nextInt(2 * xz + 1) - xz; int k1 = random.nextInt(2 * y + 1) - y; int i1 = random.nextInt(2 * xz + 1) - xz; if (targetVec3 == null || (double)l * targetVec3.xCoord + (double)i1 * targetVec3.zCoord >= 0.0D) { //... l = l + MathHelper.floor_double(entitycreatureIn.posX); k1 = k1 + MathHelper.floor_double(entitycreatureIn.posY); i1 = i1 + MathHelper.floor_double(entitycreatureIn.posZ); BlockPos blockpos1 = new BlockPos(l, k1, i1); if ((!flag1 || entitycreatureIn.isWithinHomeDistanceFromPosition(blockpos1)) && pathnavigate.func_188555_b(blockpos1)) { float f1 = entitycreatureIn.getBlockPathWeight(blockpos1); if (f1 > f) { f = f1; i = l; j = k1; k = i1; flag = true; } } } } if (flag) { // Still using floor method return new Vec3d((double)i, (double)j, (double)k); } else { return null; } } Note: A problem is as well that the field net.minecraft.entity.EntityCreature.homePosition is a BlockPos, but its integer values are used to get a vector used for movement without using the center of the block. An example for this is the method net.minecraft.entity.ai.EntityAIMoveTowardsRestriction.shouldExecute(). |
| Comment by Sam Archer [ 18/Dec/13 ] |
|
Hooray! Excited that this is fixed. I couldn't figure out why my villagers were all gathering in one corner of the village; I didn't even think about the fact that it might be a bug. Thanks, Grum! |
| Comment by Jacob S. Reed [ 15/Dec/13 ] |
|
Why are all these comments about a 1.8 bug when it's a non-existent version yet? |
| Comment by [Mojang] Grum (Erik Broes) [ 14/Dec/13 ] |
|
Told them cows to not group in the NorthWest anymore, they didn't even realise they were doing it. The chickens just clucked suspiciously. |
| Comment by Jeuv [ 19/Oct/13 ] |
|
Still in 1.6.4. Very annoying, especially with animal farms. |
| Comment by Griv Eli [ 07/Oct/13 ] |
|
A screenshot of an (artificial) iron golems farm. |
| Comment by GerbilCrab475 [ 13/Jul/13 ] |
|
This is a very annoying glitch. Many of the mobs in my zoo get stick to the North-west corners of each exhibit. If I could post a picture, I would. It's very noticeable with spiders and horses. |
| Comment by Markku [ 11/Jul/13 ] |
|
I checked at the code level, too, and updated the version list. |
| Comment by Daniel King [ 11/Jul/13 ] |
|
I placed a bunch of sheep around me, trying to place them a little south east of where I was standing at the origin. I left it on while I was gone from home for 6 hours and got the picture NWtrend as my result. Just to quantify this, in each quadrant I had the given number of sheep
If you play for any extended period of time I think this is very, very noticeable. |
| Comment by Chris Andrews [ 09/Jul/13 ] |
|
This is the most convincing argument I've seen for these symptoms that I've seen to date, which combined with the animals-escaping-pen (which was recently supposedly fixed), meant animal enclosures were very hard to manage. I run a Bukkit server and have seen evidence of this numerous times; conveniently, there exists a large square pen with sheep, which leave evidence (in the form of eaten grass) which is viewable on DynMap, proving that they have migrated mostly north-west, but also north-east. See attached picture. |
| Comment by Daniel King [ 08/Jul/13 ] |
|
@ANBO Motohiko |
| Comment by ANBO Motohiko [ 08/Jul/13 ] |
|
related?: |
| Comment by Dranitsin Roman [ 08/Jul/13 ] |
|
Well, I can confirm this, due to all my animals stay in one corner of huge farm. |
| Comment by Daniel King [ 18/Jun/13 ] |
|
I have had animals swim off , to (from kilometers away), and past my island home following a northwest path. By and large it seems all the animals in my world migrate northwest unless I enclose them. Actually, if you look at large animal enclosures you can see a slight northwest bias. I hope this gets fixed as it is an annoyance when you have lived in an area a long time. Good work. |