mojira.dev
MC-301841

Some implementations of Random#nextInt seem to have slight directional biases

A bit before MC-240121 was resolved, I began looking through the decompiled code to see if other places used Random#nextInt in unexpected ways (not accounting that the upper value passed is exclusive), and it turns out that some places that use that method seem to cause slight directional biases (though the analysis here may not be entirely correct). This is unlikely to have any relation with other, more general directional biases.

Probably the most observable one is in FleeSunGoal, used by skeletons to search for a safe place when they’re on fire due to sunlight. By placing a skeleton in the center of the world and placing four pillars in above the floor in the cardinal directions 10 blocks away, skeletons tend to strongly prefer heading towards the negative direction, which does not occur when they’re not on fire or there are no nearby safe blocks.

Affected methods (all number ranges below are both inclusive):

  • FleeSunGoal#getHidePos

BlockPos $$3 = $$1.offset($$0.nextInt(20) - 10, $$0.nextInt(6) - 3, $$0.nextInt(20) - 10);

Goes from -10 to 9 (bias towards negative)

  • Drowned.DrownedGoToWaterGoal#getWaterPos

BlockPos $$3 = $$1.offset($$0.nextInt(20) - 10, 2 - $$0.nextInt(8), $$0.nextInt(20) - 10);

Goes from -10 to 9 (bias towards negative)

  • StrollThroughVillageGoal#moveRandomly

BlockPos $$1 = this.mob.level().getHeightmapPos(Heightmap.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.mob.blockPosition().offset(-8 + $$0.nextInt(16), 0, -8 + $$0.nextInt(16)));

Goes from -8 to 7 (bias towards negative). Also affects PatrollingMonster.LongDistancePatrolGoal#moveRandomly.

  • MoveToSkySeeingSpot#getOutdoorPosition

BlockPos $$5 = $$3.offset($$2.nextInt(20) - 10, $$2.nextInt(6) - 3, $$2.nextInt(20) - 10);

Seems to be used by villagers in raid victory celebrations. Goes from -10 to 9 (bias towards negative)

  • PatrollingMonster#findPatrolTarget

this.patrolTarget = this.blockPosition().offset(-500 + this.random.nextInt(1000), 0, -500 + this.random.nextInt(1000));

Goes from -500 to 499 (negligible bias)

  • VillageSiege#findRandomSpawnPos (tracked in MC-113979)

int $$3 = $$1.getX() + $$0.random.nextInt(16) - 8;
int $$4 = $$1.getZ() + $$0.random.nextInt(16) - 8;
int $$5 = $$0.getHeight(Heightmap.Heightmap.Types.WORLD_SURFACE, $$3, $$4);
BlockPos $$6 = new BlockPos($$3, $$5, $$4);

Goes from -8 to 7 (bias towards negative)

  • EnderMan#teleport

double $$1 = this.getY() + (double)(this.random.nextInt(64) - 32);

Goes from -32 to 31 (very slight bias towards negative; could be intentional). Seems to be the only one with a Y bias instead of an X/Z one!

I’ve probably missed some, but this seems to be overall mostly unimportant for gameplay.

Linked issues

Attachments

Comments 0

No comments.

ampolive

(Unassigned)

Plausible

Mob behaviour, Mob spawning

1.21.8, 25w36b

Retrieved