Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-257069

Trapped villager can prevent any other villagers from claiming a jobsite

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.19.2, 22w43a
    • None
    • Plausible
    • Mob behaviour, Village system
    • Normal
    • Gameplay

      Setup

      Create a pen, maybe 10×10. Spawn one villager in the pen, and trap them in a minecart on one side. Spawn a second villager in the pen, allowed to run around. Place a job site block in the pen on the other side from the minecart. See first attached image.

      Alternatively, trap one villager with trapdoors such that it can path out but can't actually leave. See second attached image.

      Expected result

      The free-running villager will claim the jobsite reasonably quickly.

      Actual result

      Half the time, the free-running villager will claim it immediately.

      The other half of the time, the trapped villager will stare intently at the jobsite while the free-running villager ignores it for a long time. The free-running villager may finally claim it after many minutes; at a guess this is probably a result of a ~1/30 chance rolled once per minute.

      Analysis

      I think what's going on here is something like this

      1. Both villagers are running AcquirePoi for POTENTIAL_JOB_SITE once every 20–39 ticks.
      2. The jobsite is placed. In the failure case, the trapped villager's AcquirePoi runs first.
      3. Since the villager can path to it, they take the POI. This prevents the other villager from even considering it.
      4. The villager's GoToPotentialJobSite begins running to try to get the villager to the job site, but since the villager can't actually move they just stare. Meanwhile, AcquirePoi no longer runs as it is inhibited by the POTENTIAL_JOB_SITE memory being set.
      5. After 1200 ticks, GoToPotentialJobSite times out. Its stop method erases the POTENTIAL_JOB_SITE memory and release the POI.
      6. Since the trapped villager's AcquirePoi has not been run in 1200 ticks, it runs right away next tick and we're back at step 2. The "~1/30 chance" mentioned above would be the chance that the free-running villager's AcquirePoi's20–39 tick delay expires exactly when the POI is released.

      If that's right, one fix could be to set nextScheduledStart in AcquirePoi to 0 when taking the POI. That would trigger the if (this.nextScheduledStart == 0L) case in checkExtraStartConditions to delay step 6 by 20 ticks, giving the other villager a chance (~25% I think) to grab the POI before the trapped villager claims it again.

      Or each instance of AcquirePoi could remember the last taken POI and not take that specific POI again for something longer than 1240 ticks. It already has the JitteredLinearRetry thing, but that's only 400 ticks max.

      But both of those could probably still be problematic if there are multiple trapped villagers in range.

      Another could be to not have AcquirePoi actually take the POI in this case, instead have that happen by AssignProfessionFromJobSite when the villager actually reaches it and sets the JOB_SITE memory (with an extra check in there in case some other villager just claimed it in the same tick).

      That last could also enable "villager races": trap several villagers, place one jobsite, then use redstone to release them all at once and see which manages to claim it.

      I wouldn't recommend changing the path-finding to avoid the trapped villager being able to path to the jobsite in the first place. That seems too likely to break existing villager trading halls, and maybe other mob farms too.

            Unassigned Unassigned
            anomie x Anomie X
            Votes:
            4 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              CHK: