Conversation
d7e9f26 to
66b42a3
Compare
# Conflicts: # core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java # core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java # core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java
# Conflicts: # core/src/main/java/org/geysermc/geyser/entity/type/Entity.java # core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java # core/src/main/java/org/geysermc/geyser/session/cache/WorldBorder.java # core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockPlayerAuthInputTranslator.java
core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Refactors entity coordinate handling to consistently store Java (unmodified) positions internally while deriving Bedrock (offset-applied) positions via a dedicated accessor, reducing ad-hoc offset math across translators and entity logic.
Changes:
- Introduces
Entity#bedrockPosition()(offset-applied) and updates packet sending/collision logic to useposition()(Java) vsbedrockPosition()(Bedrock) appropriately. - Updates many translators and caches to stop manually adding/subtracting entity offsets and instead use the new position accessors.
- Updates vehicle and display-entity movement to compute deltas/packets using Bedrock positions while storing Java positions internally.
Reviewed changes
Copilot reviewed 57 out of 58 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java | Uses Bedrock position accessor for world-space checks; adjusts placement math. |
| core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java | Sends empty chunks based on Java position accessor. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java | Targets vibration particles using Bedrock entity position. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java | Updates chunk position tracking based on Java player position. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java | Uses Bedrock position/rotation accessors for move/sound packets. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java | Respawn packet now uses Bedrock player position. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java | Removes manual player offset math; uses Java vs Bedrock accessors. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java | Computes look-at deltas from Java positions; clarifies origin handling. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java | XP pickup sound uses Bedrock collected-entity position. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java | Entity-attached sounds use Bedrock entity position. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java | Teleport confirmation now uses Java player position accessor. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java | Particles/sounds/motion updated to use Java vs Bedrock positions consistently. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockPlayerAuthInputTranslator.java | Vehicle input path updated to convert Bedrock packet pos -> Java pos via entity offset. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockMovePlayer.java | Player movement validation and state updates use Bedrock vs Java positions explicitly. |
| core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java | Interaction range checks use Java position + eye height; entity click math updated. |
| core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java | Non-relative sounds now play at Bedrock player position; simplifies vec conversion. |
| core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java | Uses Java player position for interaction-distance checks. |
| core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java | Inventory open/close packets use Bedrock player block position. |
| core/src/main/java/org/geysermc/geyser/session/cache/WorldBorder.java | World border checks and corrections now use Java player position accessor. |
| core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java | Skull culling uses Java player movement comparisons. |
| core/src/main/java/org/geysermc/geyser/session/cache/BossBar.java | Bossbar helper entity positioned relative to Java player position. |
| core/src/main/java/org/geysermc/geyser/session/cache/BlockBreakHandler.java | Block-break interaction range uses Java position + eye height. |
| core/src/main/java/org/geysermc/geyser/session/GeyserSession.java | Updates session docs and uses Bedrock player position where required by Bedrock packets. |
| core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java | Formatting/indentation adjustment in NBT collision box conversion. |
| core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java | Recalculation/movement packets use Bedrock position/rotation accessors. |
| core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java | Interaction-distance check uses Java player position accessor. |
| core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java | Vehicle delta movement compares old/new Bedrock positions while storing Java pos. |
| core/src/main/java/org/geysermc/geyser/entity/vehicle/BoatVehicleComponent.java | Boat delta movement updated to new Bedrock position derivation model. |
| core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java | Stops storing offset-applied position; adds Bedrock->Java setter for auth input. |
| core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java | Removes overridden position() offset adjustment (position is now Java). |
| core/src/main/java/org/geysermc/geyser/entity/type/player/AvatarEntity.java | Uses Bedrock position/rotation accessors for spawn/move; stores Java pos. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java | Heartbeat sound plays at Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java | Stare sound plays at Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonPartEntity.java | Movement packet uses Bedrock position/rotation accessors. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java | Updates part movement and effects to use Java vs Bedrock positions correctly. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java | Ignite sound uses Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreakingEntity.java | Beam particle tag uses Bedrock position values. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java | Relative movement uses Java position math; packet pos includes offset. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/animal/farm/CowEntity.java | Milk sound uses Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java | Dig particles computed from Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java | Interaction distance checks use Java player position. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java | Milk sound uses Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java | Renames rotation accessor to bedrockRotation(). |
| core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java | Converts y-offset handling to entity offset field; fixes onGround argument usage. |
| core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java | Visibility logic updated to compare against Java positions. |
| core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java | Delta packets now emit Bedrock positions after setting Java position; rotation sync updated. |
| core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java | Moves line-centering to offset field; updates secondary armor-stand positioning. |
| core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java | Removes special moveAbsoluteRaw offset override in favor of offset accessor. |
| core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java | Lerp and delta packets emit Bedrock position via accessor while storing Java pos. |
| core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java | Lerp delta packets now set X/Y/Z from bedrockPosition(). |
| core/src/main/java/org/geysermc/geyser/entity/type/LightningEntity.java | Thunder/impact sounds play at Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java | Frame cache position uses Java position() (toInt) consistently. |
| core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java | Spawn/move uses bedrockPosition() and offset field for water adjustments. |
| core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java | Splash sound plays at Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/EvokerFangsEntity.java | Attack sound plays at Bedrock position. |
| core/src/main/java/org/geysermc/geyser/entity/type/Entity.java | Adds offset state, bedrockPosition(), renames rotation accessor, and standardizes Java position storage. |
| core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java | Boat movement now stores Java pos and emits Bedrock pos via accessor; removes adjustment helper. |
| core/src/main/java/org/geysermc/geyser/entity/spawn/EntitySpawnContext.java | Stores Java spawn position and a separate initial offset value. |
Comments suppressed due to low confidence (3)
core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java:242
flatPlayerPosition.down(3)changes the fallback placement from Y-4 (previoussub(0, 4, 0)) to Y-3. If the intent is to preserve existing behavior, this should bedown(4)(or equivalent) so the fake block search checks the same block below the player as before.
core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockPlayerAuthInputTranslator.java:337- When the vehicle would pass into the world border, the code moves the vehicle back via
moveAbsoluteRaw(...)but then continues on tovehicle.setPosition(vehiclePosition)and sends aServerboundMoveVehiclePacket, effectively re-applying the out-of-bounds position. This should likelyreturnimmediately after reverting (or otherwise skip updating/sending movement) to prevent border bypass/desync.
core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java:175 TextDisplayEntitynow applies line centering viasetOffset(calculateLineOffset()), which affectsbedrockPosition()for this entity, but the secondary armor stand (custom-name renderer) is still moved/spawned using the un-offset Javaposition(only adjusted byLINE_HEIGHT_OFFSET). This will desync the relative placement between the text display and the secondary nametag when the line count changes. The secondary entity should incorporate the same centering offset (e.g., adjust its position by the offset or apply the offset to the second entity) so both stay aligned.
public void moveAbsoluteRaw(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
if (secondEntity != null) {
secondEntity.moveAbsoluteRaw(position.down(LINE_HEIGHT_OFFSET), yaw, pitch, headYaw, isOnGround, teleported);
}
super.moveAbsoluteRaw(position, yaw, pitch, headYaw, isOnGround, teleported);
}
public void setText(EntityMetadata<Component, ?> entityMetadata) {
this.dirtyMetadata.put(EntityDataTypes.NAME, MessageTranslator.convertMessage(entityMetadata.getValue(), session.locale()));
int oldLineCount = this.lineCount;
this.lineCount = calculateLineCount(entityMetadata.getValue());
// If the line count changed, update the position to account for the new offset
if (this.lineCount != oldLineCount) {
setOffset(calculateLineOffset());
moveAbsoluteRaw(position, yaw, pitch, headYaw, onGround, false);
}
}
private int calculateLineCount(@Nullable Component text) {
if (text == null) {
return 0;
}
return PlainTextComponentSerializer.plainText().serialize(text).split("\n").length;
}
@Override
public void updateBedrockMetadata() {
// Bundle metadata updates to ensure they aren't ignored
if (secondEntity != null) {
if (!secondEntity.valid) { // Spawn the entity once
secondEntity.spawnEntity();
} else {
secondEntity.updateBedrockMetadata();
}
}
super.updateBedrockMetadata();
}
public void updateNameTag() {
// Text displays are special: customNameVisible must be set for the custom name to ever show
if (this.nametag.isBlank() || isInvisible || !customNameVisible) {
if (secondEntity != null) {
secondEntity.despawnEntity();
secondEntity = null;
}
return;
}
if (this.secondEntity == null) {
secondEntity = new ArmorStandEntity(EntitySpawnContext.inherited(session, EntityDefinitions.ARMOR_STAND, this, position.down(LINE_HEIGHT_OFFSET)));
}
secondEntity.getDirtyMetadata().put(EntityDataTypes.NAME, this.nametag);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
core/src/main/java/org/geysermc/geyser/entity/vehicle/BoatVehicleComponent.java
Outdated
Show resolved
Hide resolved
…nto throwable entity movement prediction
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 57 out of 58 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (4)
core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockPlayerAuthInputTranslator.java:337
isPassingIntoBorderBoundaries(vehiclePosition, false)returns true when the move would cross the border, but the code still continues and setsvehicle.setPosition(vehiclePosition)(and sends the move packet) using the out-of-bounds position. This effectively undoes the border rollback. Return immediately after reverting, or updatevehiclePositionto the reverted position before continuing.
core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java:242flatPlayerPosition.sub(0, 4, 0)was replaced withflatPlayerPosition.down(3), which changes the fallback Y offset by 1 block. If the intent was a direct API swap, this should bedown(4)to preserve the previous placement location for the virtual inventory block.
core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java:220- For Bedrock packets, this should likely use the entity's Bedrock position (offset applied). Most other sound/particle packets in this translator were updated to
entity.bedrockPosition(), but this branch usesentity.position()which can be incorrect for entities with a non-zero offset.
core/src/main/java/org/geysermc/geyser/session/cache/BossBar.java:121 AddEntityPacketis sent to the Bedrock client, but this usessession.getPlayerEntity().position()(Java position). To keep Bedrock-side coordinates consistent with the rest of this refactor, use the player'sbedrockPosition()(and then apply the -10 Y offset) so the bossbar entity spawns at the correct Bedrock Y when the player offset is non-zero.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| vehicle.moveAbsoluteRaw(position, vehicle.getYaw(), vehicle.getPitch(), vehicle.getHeadYaw(), | ||
| vehicle.isOnGround(), true); | ||
| } | ||
|
|
||
| vehicle.setPosition(vehiclePosition); |
There was a problem hiding this comment.
In this block, after calculating vehicleRotation, the code builds a ServerboundMoveVehiclePacket using vehiclePosition.getX() as the third constructor argument (immediately after vehicle.setPosition(vehiclePosition)). Given other call sites use (javaPos, yaw, pitch, onGround), this appears to send X-position as pitch. Use the pitch component from vehicleRotation instead.
This refactor cleans up handling of Bedrock's entity offset. Specifically, Geyser currently stores the Bedrock position of an entity, which requires special handling for entities that have an offset. This PR splits up both positions cleanly to always store the unmodified Java position, and the Bedrock position which may contain an offset.