Repository navigation
fix: defer profession assignment outside the owning region - #525
Open
PluginsKers wants to merge 1 commit into
Open
PluginsKers wants to merge 1 commit into
PluginsKers wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A villager can retain a
POTENTIAL_JOB_SITEin another dimension.AssignProfessionFromJobSitechecks numeric distance, erases that memory, writesJOB_SITE, and then reads the destination world's POI manager. If the coordinates are nearby but the dimension differs, the POI ownership check throws andLevel.guardEntityTickdiscards the villager.Reject a potential site outside the current dimension or owning region before either memory changes. Local assignment and
VillagerCareerChangeEventhandling remain on the existing path. Deferral preserves the potential site for retry; the existingGoToPotentialJobSite.stoperases it and queues POI release on its owner region when abandoned.VillagerGoalPackages.getCorePackageregisters this behavior. The captured production stack reachesPoiManager.getType -> getOrLoad -> TickThread.ensureTickThreadthrough the villager's Brain. The exception handler inLevel.guardEntityTickdiscards non-player entities. The stack establishes this failure path, but does not establish how the potential-site memory first became stale.Complete captured production call chain (26.2-7-14b7fee, entry to failure)
Original exception stack. These method names and line numbers belong to the captured 26.2 build.
597e41371802648e0455fc1571192ee1c83fca2band this PR's commit for the fixed variant. Use the same probe JAR in fresh, loopback-only server directories and runjava -Xms1G -Xmx2G -Duser.language=en -Dfolia.probe=profession -jar folia.jar --nogui.(2.5, 65, 2.5), disables autonomous AI, erasesJOB_SITE, and setsPOTENTIAL_JOB_SITEto a NetherGlobalPosat(3, 65, 3). Objects and POIs are prepared on their owning regions.AssignProfessionFromJobSite.create().tryStart(level, villager, 0L)insidelevel.guardEntityTick, with the villager as the guarded entity. The unchanged server logsAccessing poi chunk off-mainand removes the villager. With the guard, it returns false, retains the villager and potential-site memory, and leavesJOB_SITEabsent.teleportAsyncand retries on the new owner region, then exercises local assignment, a cancelled career-change event, and the existing 1,200-tick timeout with POI release observed on the POI region.In 26.3,
assignProfessionWhenSpawnedno longer bypasses the distance gate. The fixture's far same-world site is a control, not the failing current-version case. The paired baseline stops at the foreign-dimension failure, so subsequent controls in that recording are fixed-only.The current 26.3 failure stack, baseline log, and fixed log are pinned alongside the fixture. The recorded fixed runtime contains the three independent guards; this PR contains only the profession-assignment change. The reproductions invoke real behaviors on owner threads with autonomous AI disabled; separate single-fix runtime JARs and complete autonomous gameplay runs were not recorded. Read assertion markers in the logs, since the fixture shuts down normally even after an assertion fails.
AI tools assisted the investigation, implementation, reproduction, and this description.