fix entity archetype positions - #4303
Open
whimxiqal wants to merge 1 commit into
Open
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.
Fix entity archetype positions in archetype volumes
Problem
ServerWorld#createArchetypeVolumethrows whenever any entity stands in the minimum-x, -y, or -z plane of the requested region:Reproduced on SpongeVanilla 1.21.1-12.0.4-RC0 by copying a single chunk column (
min = (-16, -64, 16),origin = min) that contained an entity at block(-16, 67, 31)— squarely inside the region, on its minimum-x face.Root cause
createArchetypeVolumepairsVolumePositionTranslators.offset(Vector3i)withVolumeApplicators.applyEntityArchetypes().offset(Vector3i)delegates tooffset(min.toDouble().add(BLOCK_OFFSET)), so every element position becomespos - min - 0.5. That half-block bias is a block-space convention:applyBlocks,applyBiomesandapplyBlockEntityArchetypesall callelement.position().round().toInt(), andMath.round(-0.5) == 0, so it cancels out.applyEntityArchetypes()does not round — it stores the raw position — andObjectArrayMutableEntityArchetypeBuffer#addEntitybounds-checks withentry.position().toInt(), which floors.floor(-0.5) == -1, hence the exception.Two consequences beyond the crash:
SpongeArchetypeVolume#applyToWorldhas the same mismatch mirrored:relativeTo(Vector3i)also subtractsBLOCK_OFFSET, which the block applicators undo by rounding andapplyEntityArchetype()does not. A save → paste round trip therefore lands entities a full block off, not half.Separately,
AbstractReferentArchetypeVolume#addEntityflattened positions throughVector3ibefore delegating, discarding sub-block precision thatentityArchetypesByPosition()on the same class preserves.Fix
All three changes are implementation-side; SpongeAPI is untouched.
LevelMixin_API#createArchetypeVolume— entity leg switched to theVector3doverload ofrelativeTo, so entities are placed atstoredPosition + placement.SpongeArchetypeVolume#applyToWorld— entity leg switched to theVector3doverload ofrelativeTo, so entities are placed atstoredPosition + placement.AbstractReferentArchetypeVolume#addEntity— transforms the position as aVector3dinstead of flattening it to a block coordinate.This settles the convention that the rest of the codebase already assumes: an entity archetype's position is a real position relative to the volume origin, not a block position.
SchematicTranslatorwritesentry.position()straight into the schematic'sPosdoubles and reads them back unchanged, andStructureTemplateMixin_API#addEntityconverts the position to aVec3and floors it separately for theBlockPos. The-0.5was only ever meaningful for block-shaped elements.Testing
./gradlew compileJavapasses for SpongeCommon and SpongeVanilla. I haven't added an automated test — the failure is in aLevelmixin and needs a live world;VolumeTransformationTestis the nearest existing harness and doesn't reach this path. Verified by hand: chunk copies that previously threw now succeed, and entities land on their original blocks on paste.Notes
Written against
api-12, butapi-13throughapi-16carry the identicaloffset(origin)+applyEntityArchetypes()pairing and need the same fix.