minecraft-renderer 0.1.94 → 0.1.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.94",
3
+ "version": "0.1.95",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -655,7 +655,8 @@ export class Entities {
655
655
  applyVehiclePassengerPositions({
656
656
  entities: this.entities,
657
657
  localPlayer: this.playerEntity,
658
- getWorldPosition: target => this.worldRenderer.sceneOrigin.getWorldPosition(target as SceneEntity)
658
+ getWorldPosition: target => this.worldRenderer.sceneOrigin.getWorldPosition(target as SceneEntity),
659
+ version: this.worldRenderer.version
659
660
  })
660
661
  }
661
662
 
@@ -10,6 +10,7 @@ import {
10
10
  getHorsePassengerWorldPosition,
11
11
  getLocalVehicleWorldPosition,
12
12
  getMinecartPassengerWorldPosition,
13
+ getVehiclePassengerFeetOffsetY,
13
14
  resolveLocalVehicleWorldPosition,
14
15
  samePosition,
15
16
  shouldRestartCameraPositionTween,
@@ -244,7 +245,28 @@ test('horse vertical camera lock falls back to raw Y when result is non-finite',
244
245
  })
245
246
 
246
247
  test('minecart passenger feet Y is vehicleY - 0.35', () => {
247
- expect(getMinecartPassengerWorldPosition({ x: 0, y: 64, z: 0 }).y).toBeCloseTo(63.65, 5)
248
+ expect(getMinecartPassengerWorldPosition({ x: 0, y: 64, z: 0 }, '1.17.1', 'minecart', 0.7).y).toBeCloseTo(63.65, 5)
249
+ })
250
+
251
+ test.each([
252
+ ['1.17.1', 'boat', -0.45],
253
+ ['1.20.1', 'boat', -0.45],
254
+ ['1.20.2', 'boat', -0.4125],
255
+ ['1.21.4', 'boat', -0.4125],
256
+ ['1.17.1', 'minecart', -0.35],
257
+ ['1.20.1', 'minecart', -0.35],
258
+ ['1.20.2', 'minecart', -0.4125],
259
+ ['1.21.4', 'minecart', -0.4125],
260
+ ['1.21.4', 'bamboo_raft', -0.1]
261
+ ])('vehicle %s %s seat offset matches vanilla', (version, vehicleName, expected) => {
262
+ const layout = vehicleName === 'minecart' ? 'minecart' : 'boat'
263
+ const height = layout === 'boat' ? 0.5625 : 0.7
264
+ expect(getVehiclePassengerFeetOffsetY(layout, version, vehicleName, height)).toBeCloseTo(expected, 5)
265
+ })
266
+
267
+ test('vehicle seat offset falls back to the default vehicle height', () => {
268
+ expect(getVehiclePassengerFeetOffsetY('boat', '1.20.2', 'oak_boat', undefined)).toBeCloseTo(-0.4125, 5)
269
+ expect(getVehiclePassengerFeetOffsetY('minecart', '1.20.2', 'minecart', undefined)).toBeCloseTo(-0.4125, 5)
248
270
  })
249
271
 
250
272
  test.each([
@@ -1,4 +1,6 @@
1
1
  //@ts-nocheck
2
+ import { versionToNumber } from '../../lib/utils'
3
+
2
4
  export const LOCAL_MOVEMENT_TWEEN_DURATION_MS = 50
3
5
  export const ENTITY_TWEEN_DURATION_MS = 120
4
6
  export const SPECTATING_CAMERA_TWEEN_DURATION_MS = 150
@@ -116,11 +118,6 @@ export function resolveLocalVehicleWorldPosition(args: {
116
118
  return getLocalVehicleWorldPosition(cameraWorldPos, rawVehicleY)
117
119
  }
118
120
 
119
- const BOAT_PASSENGER_RIDING_OFFSET_Y = -0.1
120
- const PLAYER_RIDING_OFFSET_Y = -0.35
121
- /** Vanilla 1.17.1 AbstractMinecart#getPassengersRidingOffset() */
122
- const MINECART_PASSENGER_RIDING_OFFSET_Y = 0
123
-
124
121
  const RIDEABLE_MINECART_ENTITY_NAMES = new Set([
125
122
  'minecart',
126
123
  'chest_minecart',
@@ -148,21 +145,79 @@ export function getBoatPassengerSeatOffset(passengerIndex: number, passengerCoun
148
145
  return passengerIndex === 0 ? 0.2 : -0.6
149
146
  }
150
147
 
151
- /** Vanilla 1.17.1 Boat#positionRider position, without applying the passenger pose. */
152
- export function getBoatPassengerWorldPosition(boatWorldPos: Vec3Like, boatYaw: number, passengerIndex: number, passengerCount: number): Vec3Like {
148
+ const DEFAULT_BOAT_HEIGHT = 0.5625
149
+ const DEFAULT_MINECART_HEIGHT = 0.7
150
+
151
+ // <= 1.20.1: Entity#positionRider = y + vehicle.getPassengersRidingOffset() + passenger.getMyRidingOffset()
152
+ // Vanilla 1.17.1 sources: vehicle/Boat#getPassengersRidingOffset() = -0.1,
153
+ // vehicle/AbstractMinecart#getPassengersRidingOffset() = 0, player/Player#getMyRidingOffset() = -0.35.
154
+ const LEGACY_PLAYER_RIDING_OFFSET_Y = -0.35 // Player#getMyRidingOffset(), <= 1.20.1
155
+ const LEGACY_BOAT_RIDING_OFFSET_Y = -0.1 // Boat#getPassengersRidingOffset(), <= 1.20.1
156
+ const LEGACY_MINECART_RIDING_OFFSET_Y = 0 // AbstractMinecart#getPassengersRidingOffset(), <= 1.20.1
157
+
158
+ // >= 1.20.2: y is based on the vehicle's PASSENGER attachment point.
159
+ // The player's contribution is numerically the same, but the mechanism changed:
160
+ // 1.20.2-1.20.4: PASSENGER.y + Player#ridingOffset() (-0.6)
161
+ // >= 1.20.5: PASSENGER.y - Player.DEFAULT_VEHICLE_ATTACHMENT.y (0.6)
162
+ // Vanilla sources: Entity#positionRider, Boat#getPassengerAttachmentPoint,
163
+ // EntityType.*_MINECART#passengerAttachments and Player#ridingOffset / DEFAULT_VEHICLE_ATTACHMENT.
164
+ const MODERN_PLAYER_RIDING_OFFSET_Y = -0.6
165
+ const MODERN_MINECART_PASSENGER_ATTACHMENT_Y = 0.1875 // EntityType.*_MINECART.passengerAttachments()
166
+ const MODERN_BOAT_RIDE_HEIGHT_FACTOR = 1 / 3 // (Abstract)Boat#rideHeight(), >= 1.20.2
167
+ const MODERN_RAFT_RIDE_HEIGHT_FACTOR = 0.8888889 // Raft#rideHeight(), >= 1.21.2
168
+
169
+ /**
170
+ * Vanilla seat offset for a player passenger in a boat or minecart.
171
+ * Rafts before 1.21.2 are intentionally treated as boats because their entity
172
+ * name is 'boat' and their metadata variant is not read by this project.
173
+ */
174
+ export function getVehiclePassengerFeetOffsetY(
175
+ layout: 'boat' | 'minecart',
176
+ version: string,
177
+ vehicleName: string | undefined,
178
+ vehicleHeight: number | undefined
179
+ ): number {
180
+ const height = Number.isFinite(vehicleHeight) ? vehicleHeight! : layout === 'boat' ? DEFAULT_BOAT_HEIGHT : DEFAULT_MINECART_HEIGHT
181
+
182
+ if (versionToNumber(version) >= versionToNumber('1.20.2')) {
183
+ const isRaft = typeof vehicleName === 'string' && vehicleName.toLowerCase().endsWith('_raft')
184
+ const passengerAttachmentY =
185
+ layout === 'boat' ? height * (isRaft ? MODERN_RAFT_RIDE_HEIGHT_FACTOR : MODERN_BOAT_RIDE_HEIGHT_FACTOR) : MODERN_MINECART_PASSENGER_ATTACHMENT_Y
186
+ return passengerAttachmentY + MODERN_PLAYER_RIDING_OFFSET_Y
187
+ }
188
+
189
+ const vehicleRidingOffset = layout === 'boat' ? LEGACY_BOAT_RIDING_OFFSET_Y : LEGACY_MINECART_RIDING_OFFSET_Y
190
+ return vehicleRidingOffset + LEGACY_PLAYER_RIDING_OFFSET_Y
191
+ }
192
+
193
+ /** Vanilla Boat#positionRider position, without applying the passenger pose. */
194
+ export function getBoatPassengerWorldPosition(
195
+ boatWorldPos: Vec3Like,
196
+ boatYaw: number,
197
+ passengerIndex: number,
198
+ passengerCount: number,
199
+ version: string,
200
+ vehicleName: string | undefined,
201
+ vehicleHeight: number | undefined
202
+ ): Vec3Like {
153
203
  const seatOffset = getBoatPassengerSeatOffset(passengerIndex, passengerCount)
154
204
  return {
155
205
  x: boatWorldPos.x - Math.sin(boatYaw) * seatOffset,
156
- y: boatWorldPos.y + BOAT_PASSENGER_RIDING_OFFSET_Y + PLAYER_RIDING_OFFSET_Y,
206
+ y: boatWorldPos.y + getVehiclePassengerFeetOffsetY('boat', version, vehicleName, vehicleHeight),
157
207
  z: boatWorldPos.z + Math.cos(boatYaw) * seatOffset
158
208
  }
159
209
  }
160
210
 
161
- /** Vanilla 1.17.1 minecart positionRider for a centered player passenger. */
162
- export function getMinecartPassengerWorldPosition(minecartWorldPos: Vec3Like): Vec3Like {
211
+ /** Vanilla minecart positionRider for a centered player passenger. */
212
+ export function getMinecartPassengerWorldPosition(
213
+ minecartWorldPos: Vec3Like,
214
+ version: string,
215
+ vehicleName: string | undefined,
216
+ vehicleHeight: number | undefined
217
+ ): Vec3Like {
163
218
  return {
164
219
  x: minecartWorldPos.x,
165
- y: minecartWorldPos.y + MINECART_PASSENGER_RIDING_OFFSET_Y + PLAYER_RIDING_OFFSET_Y,
220
+ y: minecartWorldPos.y + getVehiclePassengerFeetOffsetY('minecart', version, vehicleName, vehicleHeight),
166
221
  z: minecartWorldPos.z
167
222
  }
168
223
  }
@@ -14,6 +14,10 @@ import {
14
14
 
15
15
  type Vec3 = { x: number; y: number; z: number }
16
16
 
17
+ const TEST_VERSION = '1.17.1'
18
+ const BOAT_HEIGHT = 0.5625
19
+ const MINECART_HEIGHT = 0.7
20
+
17
21
  function staleOffsetVehiclePosition(cameraWorldPos: Vec3, vehiclePosition: Vec3, stalePassengerPosition: Vec3): Vec3 {
18
22
  return {
19
23
  x: cameraWorldPos.x + (vehiclePosition.x - stalePassengerPosition.x),
@@ -74,23 +78,23 @@ test('render frames between press and release keep zero horizontal delta to came
74
78
  test('boat passenger positions use vanilla 1.17.1 riding and seat offsets', () => {
75
79
  const boat = { x: 10, y: 64, z: 20 }
76
80
 
77
- expect(getBoatPassengerWorldPosition(boat, 0, 0, 1)).toEqual({
81
+ expect(getBoatPassengerWorldPosition(boat, 0, 0, 1, TEST_VERSION, 'oak_boat', BOAT_HEIGHT)).toEqual({
78
82
  x: 10,
79
83
  y: 63.55,
80
84
  z: 20
81
85
  })
82
- expect(getBoatPassengerWorldPosition(boat, 0, 0, 2)).toEqual({
86
+ expect(getBoatPassengerWorldPosition(boat, 0, 0, 2, TEST_VERSION, 'oak_boat', BOAT_HEIGHT)).toEqual({
83
87
  x: 10,
84
88
  y: 63.55,
85
89
  z: 20.2
86
90
  })
87
- expect(getBoatPassengerWorldPosition(boat, 0, 1, 2)).toEqual({
91
+ expect(getBoatPassengerWorldPosition(boat, 0, 1, 2, TEST_VERSION, 'oak_boat', BOAT_HEIGHT)).toEqual({
88
92
  x: 10,
89
93
  y: 63.55,
90
94
  z: 19.4
91
95
  })
92
96
 
93
- const rotated = getBoatPassengerWorldPosition(boat, Math.PI / 2, 0, 2)
97
+ const rotated = getBoatPassengerWorldPosition(boat, Math.PI / 2, 0, 2, TEST_VERSION, 'oak_boat', BOAT_HEIGHT)
94
98
  expect(rotated.x).toBeCloseTo(9.8)
95
99
  expect(rotated.y).toBe(63.55)
96
100
  expect(rotated.z).toBeCloseTo(20)
@@ -110,7 +114,15 @@ test('remote player follows the tracked boat each frame and releases from an emp
110
114
  sceneOrigin.track(passenger)
111
115
  passenger.position.set(90, 64, 190)
112
116
 
113
- const firstPassengerPosition = getBoatPassengerWorldPosition(sceneOrigin.getWorldPosition(boat)!, boat.rotation.y, 0, 1)
117
+ const firstPassengerPosition = getBoatPassengerWorldPosition(
118
+ sceneOrigin.getWorldPosition(boat)!,
119
+ boat.rotation.y,
120
+ 0,
121
+ 1,
122
+ TEST_VERSION,
123
+ 'oak_boat',
124
+ BOAT_HEIGHT
125
+ )
114
126
  anchorVehiclePassengerPosition(passenger, firstPassengerPosition, '10')
115
127
 
116
128
  expect(stopPositionTween).toHaveBeenCalledOnce()
@@ -119,7 +131,15 @@ test('remote player follows the tracked boat each frame and releases from an emp
119
131
 
120
132
  boat.position.set(102, 64.2, 203)
121
133
  boat.rotation.y = Math.PI / 2
122
- const movedPassengerPosition = getBoatPassengerWorldPosition(sceneOrigin.getWorldPosition(boat)!, boat.rotation.y, 0, 1)
134
+ const movedPassengerPosition = getBoatPassengerWorldPosition(
135
+ sceneOrigin.getWorldPosition(boat)!,
136
+ boat.rotation.y,
137
+ 0,
138
+ 1,
139
+ TEST_VERSION,
140
+ 'oak_boat',
141
+ BOAT_HEIGHT
142
+ )
123
143
  anchorVehiclePassengerPosition(passenger, movedPassengerPosition, '10')
124
144
  expect(sceneOrigin.getWorldPosition(passenger)?.x).toBe(102)
125
145
  expect(sceneOrigin.getWorldPosition(passenger)?.y).toBeCloseTo(63.75)
@@ -142,7 +162,7 @@ test('remote player follows the tracked boat each frame and releases from an emp
142
162
 
143
163
  test('minecart passenger uses vanilla 1.17.1 riding Y offset', () => {
144
164
  const minecart = { x: 10, y: 64, z: 20 }
145
- expect(getMinecartPassengerWorldPosition(minecart)).toEqual({
165
+ expect(getMinecartPassengerWorldPosition(minecart, TEST_VERSION, 'minecart', MINECART_HEIGHT)).toEqual({
146
166
  x: 10,
147
167
  y: 63.65,
148
168
  z: 20
@@ -163,13 +183,13 @@ test('minecart passenger anchor follows vehicle world position without inheritin
163
183
  sceneOrigin.track(passenger)
164
184
  passenger.position.set(90, 64, 190)
165
185
 
166
- const firstPosition = getMinecartPassengerWorldPosition(sceneOrigin.getWorldPosition(minecart)!)
186
+ const firstPosition = getMinecartPassengerWorldPosition(sceneOrigin.getWorldPosition(minecart)!, TEST_VERSION, 'minecart', MINECART_HEIGHT)
167
187
  anchorVehiclePassengerPosition(passenger, firstPosition, '42')
168
188
  const anchoredYaw = passenger.rotation.y
169
189
 
170
190
  minecart.position.set(103, 64.5, 205)
171
191
  minecart.rotation.y = Math.PI
172
- const movedPosition = getMinecartPassengerWorldPosition(sceneOrigin.getWorldPosition(minecart)!)
192
+ const movedPosition = getMinecartPassengerWorldPosition(sceneOrigin.getWorldPosition(minecart)!, TEST_VERSION, 'minecart', MINECART_HEIGHT)
173
193
  anchorVehiclePassengerPosition(passenger, movedPosition, '42')
174
194
 
175
195
  expect(sceneOrigin.getWorldPosition(passenger)).toEqual({
@@ -234,7 +254,7 @@ test('local minecart passenger anchors to camera-synced vehicle position', () =>
234
254
  for (const camera of cameraFrames) {
235
255
  const syncedMinecart = getLocalVehicleWorldPosition(camera, vehicleY)
236
256
  minecart.position.set(syncedMinecart.x, syncedMinecart.y, syncedMinecart.z)
237
- const seatPosition = getMinecartPassengerWorldPosition(syncedMinecart)
257
+ const seatPosition = getMinecartPassengerWorldPosition(syncedMinecart, TEST_VERSION, 'minecart', MINECART_HEIGHT)
238
258
  anchorVehiclePassengerPosition(passenger, seatPosition, '42')
239
259
  const passengerWorld = sceneOrigin.getWorldPosition(passenger)!
240
260
 
@@ -10,6 +10,8 @@ const REMOTE_PLAYER_ID = 8
10
10
  const MINECART_ID = '42'
11
11
  const EYE_HEIGHT = 1.62
12
12
  const PLAYER_HEIGHT = 1.8
13
+ const TEST_VERSION = '1.17.1'
14
+ const MINECART_HEIGHT = 0.7
13
15
 
14
16
  type PassengerLike = THREE.Group & {
15
17
  playerObject: Record<string, unknown>
@@ -42,7 +44,7 @@ function anchorMinecartPassengers(
42
44
  remotePlayers: Record<number, PassengerLike>
43
45
  ) {
44
46
  const vehicleWorldPos = sceneOrigin.getWorldPosition(minecart)!
45
- const seatPosition = getMinecartPassengerWorldPosition(vehicleWorldPos)
47
+ const seatPosition = getMinecartPassengerWorldPosition(vehicleWorldPos, TEST_VERSION, 'minecart', MINECART_HEIGHT)
46
48
  for (const passengerId of passengerIds) {
47
49
  const passenger = resolveMinecartPassenger(passengerId, localPlayer, remotePlayers)
48
50
  if (!passenger?.playerObject) continue
@@ -196,7 +198,7 @@ test('local boat passenger uses the same anchor as remote passenger', () => {
196
198
  sceneOrigin.track(localPlayer)
197
199
  sceneOrigin.track(remotePlayer)
198
200
 
199
- const boatSeat = getBoatPassengerWorldPosition(sceneOrigin.getWorldPosition(boat)!, boat.rotation.y, 0, 1)
201
+ const boatSeat = getBoatPassengerWorldPosition(sceneOrigin.getWorldPosition(boat)!, boat.rotation.y, 0, 1, TEST_VERSION, 'oak_boat', 0.5625)
200
202
  if (shouldAnchorPassenger(localPlayer, 'boat', true)) {
201
203
  anchorVehiclePassengerPosition(localPlayer, boatSeat, '10')
202
204
  }
@@ -74,7 +74,7 @@ test('minecart passenger anchor preserves head rotation', () => {
74
74
  storeNetworkHeadPitch(userData, 0.45)
75
75
  applyNetworkHeadPitch(playerObject, userData)
76
76
 
77
- const seat = getMinecartPassengerWorldPosition({ x: 10, y: 64, z: 20 })
77
+ const seat = getMinecartPassengerWorldPosition({ x: 10, y: 64, z: 20 }, '1.17.1', 'minecart', 0.7)
78
78
  anchorVehiclePassengerPosition(passenger, seat, '42')
79
79
  simulateAnimationFrames(playerObject, userData, 4)
80
80
 
@@ -21,6 +21,7 @@ const BOAT_YAW = -0.5645049299419149
21
21
  const REMOTE_PLAYER_A = 8
22
22
  const REMOTE_PLAYER_B = 9
23
23
  const BOAT_ID = 10
24
+ const TEST_VERSION = '1.17.1'
24
25
 
25
26
  function makePlayerObject(): PlayerObjectType {
26
27
  return new PlayerObject() as PlayerObjectType
@@ -71,7 +72,8 @@ function createHarness(passengerIds: number[]) {
71
72
  updateVehiclePassengerPositions({
72
73
  entities: entities as Parameters<typeof updateVehiclePassengerPositions>[0]['entities'],
73
74
  localPlayer: null,
74
- getWorldPosition: target => sceneOrigin.getWorldPosition(target as THREE.Object3D)
75
+ getWorldPosition: target => sceneOrigin.getWorldPosition(target as THREE.Object3D),
76
+ version: TEST_VERSION
75
77
  })
76
78
 
77
79
  const runRemoteRotation = () =>
@@ -8,6 +8,7 @@ import { updateVehiclePassengerPositions, type VehiclePassengerSceneEntity, type
8
8
 
9
9
  const LOCAL_PLAYER_ID = 7
10
10
  const REMOTE_PLAYER_ID = 8
11
+ const TEST_VERSION = '1.17.1'
11
12
 
12
13
  type PassengerLike = THREE.Group & VehiclePassengerSceneEntity
13
14
 
@@ -43,7 +44,8 @@ function createHarness() {
43
44
  updateVehiclePassengerPositions({
44
45
  entities,
45
46
  localPlayer,
46
- getWorldPosition: target => sceneOrigin.getWorldPosition(target as THREE.Object3D)
47
+ getWorldPosition: target => sceneOrigin.getWorldPosition(target as THREE.Object3D),
48
+ version: TEST_VERSION
47
49
  })
48
50
 
49
51
  return { sceneOrigin, localPlayer, entities, cameraWorldPos, runUpdate }
@@ -65,7 +67,15 @@ test('updateVehiclePassengerPositions anchors local boat and minecart passengers
65
67
 
66
68
  runUpdate()
67
69
 
68
- const expectedBoatSeat = getBoatPassengerWorldPosition(sceneOrigin.getWorldPosition(boat)!, boat.rotation.y, 0, 1)
70
+ const expectedBoatSeat = getBoatPassengerWorldPosition(
71
+ sceneOrigin.getWorldPosition(boat)!,
72
+ boat.rotation.y,
73
+ 0,
74
+ 1,
75
+ TEST_VERSION,
76
+ 'oak_boat',
77
+ boat.originalEntity.height
78
+ )
69
79
  expect(localPlayer.userData._passengerVehicleId).toBe('10')
70
80
  expect(sceneOrigin.getWorldPosition(localPlayer)).toEqual(expectedBoatSeat)
71
81
 
@@ -77,7 +87,12 @@ test('updateVehiclePassengerPositions anchors local boat and minecart passengers
77
87
 
78
88
  runUpdate()
79
89
 
80
- const expectedMinecartSeat = getMinecartPassengerWorldPosition(sceneOrigin.getWorldPosition(minecart)!)
90
+ const expectedMinecartSeat = getMinecartPassengerWorldPosition(
91
+ sceneOrigin.getWorldPosition(minecart)!,
92
+ TEST_VERSION,
93
+ 'minecart',
94
+ minecart.originalEntity.height
95
+ )
81
96
  expect(localPlayer.userData._passengerVehicleId).toBe('42')
82
97
  expect(sceneOrigin.getWorldPosition(localPlayer)).toEqual(expectedMinecartSeat)
83
98
  })
@@ -119,8 +134,8 @@ test('local and remote boat passengers use the same seat algorithm per index', (
119
134
  const vehicleWorldPos = sceneOrigin.getWorldPosition(boat)!
120
135
  const localWorld = sceneOrigin.getWorldPosition(localPlayer)!
121
136
  const remoteWorld = sceneOrigin.getWorldPosition(remotePlayer)!
122
- expect(localWorld).toEqual(getBoatPassengerWorldPosition(vehicleWorldPos, boat.rotation.y, 0, 2))
123
- expect(remoteWorld).toEqual(getBoatPassengerWorldPosition(vehicleWorldPos, boat.rotation.y, 1, 2))
137
+ expect(localWorld).toEqual(getBoatPassengerWorldPosition(vehicleWorldPos, boat.rotation.y, 0, 2, TEST_VERSION, 'oak_boat', boat.originalEntity.height))
138
+ expect(remoteWorld).toEqual(getBoatPassengerWorldPosition(vehicleWorldPos, boat.rotation.y, 1, 2, TEST_VERSION, 'oak_boat', boat.originalEntity.height))
124
139
  expect(localWorld.y).toBeCloseTo(63.55, 5)
125
140
  expect(remoteWorld.y).toBeCloseTo(63.55, 5)
126
141
  })
@@ -33,6 +33,7 @@ export function updateVehiclePassengerPositions(args: {
33
33
  entities: Record<string, VehiclePassengerSceneEntity | VehiclePassengerVehicle>
34
34
  localPlayer: VehiclePassengerSceneEntity | null
35
35
  getWorldPosition: (target: unknown) => Vec3Like | undefined
36
+ version: string
36
37
  }): Set<VehiclePassengerSceneEntity> {
37
38
  const attachedPassengers = new Set<VehiclePassengerSceneEntity>()
38
39
 
@@ -61,10 +62,18 @@ export function updateVehiclePassengerPositions(args: {
61
62
 
62
63
  const passengerWorldPos =
63
64
  layout === 'minecart'
64
- ? getMinecartPassengerWorldPosition(vehicleWorldPos)
65
+ ? getMinecartPassengerWorldPosition(vehicleWorldPos, args.version, vehicleName, vehicle.originalEntity.height)
65
66
  : layout === 'horse'
66
67
  ? getHorsePassengerWorldPosition(vehicleWorldPos, vehicleName, vehicle.originalEntity.height ?? 1.6)
67
- : getBoatPassengerWorldPosition(vehicleWorldPos, vehicle.rotation.y, passengerIndex, passengerIds.length)
68
+ : getBoatPassengerWorldPosition(
69
+ vehicleWorldPos,
70
+ vehicle.rotation.y,
71
+ passengerIndex,
72
+ passengerIds.length,
73
+ args.version,
74
+ vehicleName,
75
+ vehicle.originalEntity.height
76
+ )
68
77
 
69
78
  if (!isFiniteVec3(passengerWorldPos)) continue
70
79
  anchorVehiclePassengerPosition(passenger, passengerWorldPos, vehicleId)