From 7698ee76834907baac016b3acf79d50ae1686bc1 Mon Sep 17 00:00:00 2001 From: Gero Date: Tue, 4 Oct 2022 13:25:55 +0200 Subject: [PATCH] Some minor performance improvements and cleanups (#3134) --- .../api/minecraft/chunks/ChunkSection.java | 12 +++ .../types/version/ChunkSectionType1_8.java | 28 +++---- .../Protocol1_12To1_11_1.java | 43 +++++----- .../blockconnections/ConnectionData.java | 79 +++++++------------ .../packets/WorldPackets.java | 69 +++++++--------- .../packets/WorldPackets.java | 43 +++++----- .../Protocol1_9_3To1_9_1_2.java | 24 +++--- 7 files changed, 140 insertions(+), 158 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/chunks/ChunkSection.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/chunks/ChunkSection.java index 2207a761b..be759b460 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/chunks/ChunkSection.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/chunks/ChunkSection.java @@ -40,6 +40,18 @@ public interface ChunkSection { return y << 8 | z << 4 | x; } + static int xFromIndex(int idx) { + return idx & 0xF; + } + + static int yFromIndex(int idx) { + return idx >> 8 & 0xF; + } + + static int zFromIndex(int idx) { + return idx >> 4 & 0xF; + } + @Deprecated/*(forRemoval = true)*/ default int getFlatBlock(int idx) { return palette(PaletteType.BLOCKS).idAt(idx); diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_8.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_8.java index a8c1c8576..325d70c80 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_8.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_8.java @@ -24,6 +24,8 @@ package com.viaversion.viaversion.api.type.types.version; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl; +import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; +import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.type.Type; import io.netty.buffer.ByteBuf; @@ -38,16 +40,14 @@ public class ChunkSectionType1_8 extends Type { @Override public ChunkSection read(ByteBuf buffer) throws Exception { ChunkSection chunkSection = new ChunkSectionImpl(true); + DataPalette blocks = chunkSection.palette(PaletteType.BLOCKS); + // 0 index needs to be air in 1.9 - chunkSection.addPaletteEntry(0); + blocks.addId(0); ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN); - - for (int i = 0; i < ChunkSection.SIZE; i++) { - int mask = littleEndianView.readShort(); - int type = mask >> 4; - int data = mask & 0xF; - chunkSection.setBlockWithData(i, type, data); + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + blocks.setIdAt(idx, littleEndianView.readShort()); } return chunkSection; @@ -55,15 +55,11 @@ public class ChunkSectionType1_8 extends Type { @Override public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int block = chunkSection.getFlatBlock(x, y, z); - buffer.writeByte(block); - buffer.writeByte(block >> 8); - } - } + DataPalette blocks = chunkSection.palette(PaletteType.BLOCKS); + + ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN); + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + littleEndianView.writeShort(blocks.idAt(idx)); } } - } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java index 946f08d9e..1e60ac5be 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java @@ -25,6 +25,8 @@ import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; +import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; +import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.minecraft.entities.Entity1_12Types; import com.viaversion.viaversion.api.platform.providers.ViaProviders; import com.viaversion.viaversion.api.protocol.AbstractProtocol; @@ -125,33 +127,28 @@ public class Protocol1_12To1_11_1 extends AbstractProtocol { color:14, x:132, y:64, z:222, id:"minecraft:bed" } (Debug output) - CompoundTag tag = new CompoundTag(); - tag.put("color", new IntTag(14)); // Set color to red (Default in previous versions) - tag.put("x", new IntTag(x + (chunk.getX() << 4))); - tag.put("y", new IntTag(y + (i << 4))); - tag.put("z", new IntTag(z + (chunk.getZ() << 4))); - tag.put("id", new StringTag("minecraft:bed")); + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + int id = blocks.idAt(idx) >> 4; + // Is this a bed? + if (id != 26) continue; - // Add a fake block entity - chunk.getBlockEntities().add(tag); - } - } - } + // NBT -> { color:14, x:132, y:64, z:222, id:"minecraft:bed" } (Debug output) + CompoundTag tag = new CompoundTag(); + tag.put("color", new IntTag(14)); // Set color to red (Default in previous versions) + tag.put("x", new IntTag(ChunkSection.xFromIndex(idx) + (chunk.getX() << 4))); + tag.put("y", new IntTag(ChunkSection.yFromIndex(idx) + (s << 4))); + tag.put("z", new IntTag(ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4))); + tag.put("id", new StringTag("minecraft:bed")); + + // Add a fake block entity + chunk.getBlockEntities().add(tag); } } - } }); } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java index 800dbb912..a040cc082 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java @@ -28,6 +28,8 @@ import com.viaversion.viaversion.api.minecraft.BlockFace; import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; +import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; +import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13; @@ -75,31 +77,25 @@ public class ConnectionData { } public static void updateChunkSectionNeighbours(UserConnection user, int chunkX, int chunkZ, int chunkSectionY) { + int chunkMinY = chunkSectionY << 4; + List updates = new ArrayList<>(); for (int chunkDeltaX = -1; chunkDeltaX <= 1; chunkDeltaX++) { for (int chunkDeltaZ = -1; chunkDeltaZ <= 1; chunkDeltaZ++) { - if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 0) continue; + int distance = Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ); + if (distance == 0) continue; - List updates = new ArrayList<>(); - - if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 2) { // Corner - for (int blockY = chunkSectionY * 16; blockY < chunkSectionY * 16 + 16; blockY++) { + int chunkMinX = (chunkX + chunkDeltaX) << 4; + int chunkMinZ = (chunkZ + chunkDeltaZ) << 4; + if (distance == 2) { // Corner + for (int blockY = chunkMinY; blockY < chunkMinY + 16; blockY++) { int blockPosX = chunkDeltaX == 1 ? 0 : 15; int blockPosZ = chunkDeltaZ == 1 ? 0 : 15; - updateBlock(user, - new Position( - ((chunkX + chunkDeltaX) << 4) + blockPosX, - (short) blockY, - ((chunkZ + chunkDeltaZ) << 4) + blockPosZ - ), - updates - ); + updateBlock(user, new Position(chunkMinX + blockPosX, blockY, chunkMinZ + blockPosZ), updates); } } else { - for (int blockY = chunkSectionY * 16; blockY < chunkSectionY * 16 + 16; blockY++) { - int xStart; - int xEnd; - int zStart; - int zEnd; + for (int blockY = chunkMinY; blockY < chunkMinY + 16; blockY++) { + int xStart, xEnd; + int zStart, zEnd; if (chunkDeltaX == 1) { xStart = 0; xEnd = 2; @@ -123,13 +119,7 @@ public class ConnectionData { } for (int blockX = xStart; blockX < xEnd; blockX++) { for (int blockZ = zStart; blockZ < zEnd; blockZ++) { - updateBlock(user, - new Position( - ((chunkX + chunkDeltaX) << 4) + blockX, - (short) blockY, - ((chunkZ + chunkDeltaZ) << 4) + blockZ), - updates - ); + updateBlock(user, new Position(chunkMinX + blockX, blockY, chunkMinZ + blockZ), updates); } } } @@ -145,6 +135,7 @@ public class ConnectionData { } catch (Exception e) { e.printStackTrace(); } + updates.clear(); } } } @@ -178,17 +169,17 @@ public class ConnectionData { } public static void connectBlocks(UserConnection user, Chunk chunk) { - long xOff = chunk.getX() << 4; - long zOff = chunk.getZ() << 4; + int xOff = chunk.getX() << 4; + int zOff = chunk.getZ() << 4; - for (int i = 0; i < chunk.getSections().length; i++) { - ChunkSection section = chunk.getSections()[i]; + for (int s = 0; s < chunk.getSections().length; s++) { + ChunkSection section = chunk.getSections()[s]; if (section == null) continue; + DataPalette blocks = section.palette(PaletteType.BLOCKS); boolean willConnect = false; - - for (int p = 0; p < section.getPaletteSize(); p++) { - int id = section.getPaletteEntry(p); + for (int p = 0; p < blocks.size(); p++) { + int id = blocks.idByIndex(p); if (ConnectionData.connects(id)) { willConnect = true; break; @@ -196,24 +187,14 @@ public class ConnectionData { } if (!willConnect) continue; - long yOff = i << 4; + int yOff = s << 4; - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int block = section.getFlatBlock(x, y, z); - - ConnectionHandler handler = ConnectionData.getConnectionHandler(block); - if (handler != null) { - block = handler.connect(user, new Position( - (int) (xOff + x), - (short) (yOff + y), - (int) (zOff + z) - ), block); - section.setFlatBlock(x, y, z, block); - } - } - } + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + int id = blocks.idAt(idx); + ConnectionHandler handler = ConnectionData.getConnectionHandler(id); + if (handler == null) continue; + id = handler.connect(user, new Position(xOff + ChunkSection.xFromIndex(idx), yOff + ChunkSection.yFromIndex(idx), zOff + ChunkSection.zFromIndex(idx)), id); + blocks.setIdAt(idx, id); } } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index cc5f2f7cd..dc7a329c8 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -27,6 +27,8 @@ import com.viaversion.viaversion.api.minecraft.BlockChangeRecord; import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; +import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; +import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper; @@ -334,77 +336,62 @@ public class WorldPackets { Chunk chunk = wrapper.read(type); wrapper.write(type1_13, chunk); - for (int i = 0; i < chunk.getSections().length; i++) { - ChunkSection section = chunk.getSections()[i]; - if (section == null) - continue; + for (int s = 0; s < chunk.getSections().length; s++) { + ChunkSection section = chunk.getSections()[s]; + if (section == null) continue; + DataPalette blocks = section.palette(PaletteType.BLOCKS); - for (int p = 0; p < section.getPaletteSize(); p++) { - int old = section.getPaletteEntry(p); + for (int p = 0; p < blocks.size(); p++) { + int old = blocks.idByIndex(p); int newId = toNewId(old); - section.setPaletteEntry(p, newId); + blocks.setIdByIndex(p, newId); } storage: { if (chunk.isFullChunk()) { boolean willSave = false; - for (int j = 0; j < section.getPaletteSize(); j++) { - if (storage.isWelcome(section.getPaletteEntry(j))) { + for (int p = 0; p < blocks.size(); p++) { + if (storage.isWelcome(blocks.idByIndex(p))) { willSave = true; break; } } if (!willSave) break storage; } - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int block = section.getFlatBlock(x, y, z); - Position pos = new Position( - (x + (chunk.getX() << 4)), - (y + (i << 4)), - (z + (chunk.getZ() << 4)) - ); - if (storage.isWelcome(block)) { - storage.store(pos, block); - } else if (!chunk.isFullChunk()) { // Update - storage.remove(pos); - } - } + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + int id = blocks.idAt(idx); + if (storage.isWelcome(id)) { + storage.store(new Position(ChunkSection.xFromIndex(idx) + (chunk.getX() << 4), ChunkSection.yFromIndex(idx) + (s << 4), ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4)), id); + } else if (!chunk.isFullChunk()) { // Update + storage.remove(new Position(ChunkSection.xFromIndex(idx) + (chunk.getX() << 4), ChunkSection.yFromIndex(idx) + (s << 4), ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4))); } } } save_connections: { - if (!Via.getConfig().isServersideBlockConnections() - || !ConnectionData.needStoreBlocks()) break save_connections; + if (!Via.getConfig().isServersideBlockConnections() || !ConnectionData.needStoreBlocks()) break save_connections; if (!chunk.isFullChunk()) { // Update - ConnectionData.blockConnectionProvider.unloadChunkSection(wrapper.user(), chunk.getX(), i, chunk.getZ()); + ConnectionData.blockConnectionProvider.unloadChunkSection(wrapper.user(), chunk.getX(), s, chunk.getZ()); } boolean willSave = false; - for (int j = 0; j < section.getPaletteSize(); j++) { - if (ConnectionData.isWelcome(section.getPaletteEntry(j))) { + for (int p = 0; p < blocks.size(); p++) { + if (ConnectionData.isWelcome(blocks.idByIndex(p))) { willSave = true; break; } } if (!willSave) break save_connections; - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int block = section.getFlatBlock(x, y, z); - if (ConnectionData.isWelcome(block)) { - int globalX = x + (chunk.getX() << 4); - int globalY = y + (i << 4); - int globalZ = z + (chunk.getZ() << 4); - ConnectionData.blockConnectionProvider.storeBlock(wrapper.user(), globalX, - globalY, globalZ, block); - } - } + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + int id = blocks.idAt(idx); + if (ConnectionData.isWelcome(id)) { + int globalX = ChunkSection.xFromIndex(idx) + (chunk.getX() << 4); + int globalY = ChunkSection.yFromIndex(idx) + (s << 4); + int globalZ = ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4); + ConnectionData.blockConnectionProvider.storeBlock(wrapper.user(), globalX, globalY, globalZ, id); } } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java index 87942e976..549335aa9 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java @@ -24,7 +24,9 @@ import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.BlockFace; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; +import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray; +import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper; @@ -154,15 +156,16 @@ public class WorldPackets { for (int s = 0; s < chunk.getSections().length; s++) { ChunkSection section = chunk.getSections()[s]; if (section == null) continue; + DataPalette blocks = section.palette(PaletteType.BLOCKS); boolean hasBlock = false; - for (int i = 0; i < section.getPaletteSize(); i++) { - int old = section.getPaletteEntry(i); + for (int i = 0; i < blocks.size(); i++) { + int old = blocks.idByIndex(i); int newId = protocol.getMappingData().getNewBlockStateId(old); if (!hasBlock && newId != air && newId != voidAir && newId != caveAir) { // air, void_air, cave_air hasBlock = true; } - section.setPaletteEntry(i, newId); + blocks.setIdByIndex(i, newId); } if (!hasBlock) { section.setNonAirBlocksCount(0); @@ -170,23 +173,25 @@ public class WorldPackets { } int nonAirBlockCount = 0; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - int id = section.getFlatBlock(x, y, z); - if (id != air && id != voidAir && id != caveAir) { - nonAirBlockCount++; - worldSurface[x + z * 16] = y + s * 16 + 1; // +1 (top of the block) - } - if (protocol.getMappingData().getMotionBlocking().contains(id)) { - motionBlocking[x + z * 16] = y + s * 16 + 1; // +1 (top of the block) - } + int sy = s << 4; + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + int id = blocks.idAt(idx); + if (id == air || id == voidAir || id == caveAir) continue; + nonAirBlockCount++; - // Manually update light for non full blocks (block light must not be sent) - if (Via.getConfig().isNonFullBlockLightFix() && protocol.getMappingData().getNonFullBlocks().contains(id)) { - setNonFullLight(chunk, section, s, x, y, z); - } - } + int xz = idx & 0xFF; + int y = ChunkSection.yFromIndex(idx); + worldSurface[xz] = sy + y + 1; // +1 (top of the block) + + if (protocol.getMappingData().getMotionBlocking().contains(id)) { + motionBlocking[xz] = sy + y + 1; // +1 (top of the block) + } + + // Manually update light for non-full blocks (block light must not be sent) + if (Via.getConfig().isNonFullBlockLightFix() && protocol.getMappingData().getNonFullBlocks().contains(id)) { + int x = ChunkSection.xFromIndex(idx); + int z = ChunkSection.zFromIndex(idx); + setNonFullLight(chunk, section, s, x, y, z); } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3To1_9_1_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3To1_9_1_2.java index 4ee5ec746..ae1ce351d 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3To1_9_1_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3To1_9_1_2.java @@ -25,6 +25,8 @@ import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; +import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; +import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.protocol.AbstractProtocol; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; @@ -104,18 +106,20 @@ public class Protocol1_9_3To1_9_1_2 extends AbstractProtocol tags = chunk.getBlockEntities(); - for (int i = 0; i < chunk.getSections().length; i++) { - ChunkSection section = chunk.getSections()[i]; + for (int s = 0; s < chunk.getSections().length; s++) { + ChunkSection section = chunk.getSections()[s]; if (section == null) continue; + DataPalette blocks = section.palette(PaletteType.BLOCKS); - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int block = section.getBlockWithoutData(x, y, z); - if (FakeTileEntity.isTileEntity(block)) { - tags.add(FakeTileEntity.createTileEntity(x + (chunk.getX() << 4), y + (i << 4), z + (chunk.getZ() << 4), block)); - } - } + for (int idx = 0; idx < ChunkSection.SIZE; idx++) { + int id = blocks.idAt(idx) >> 4; + if (FakeTileEntity.isTileEntity(id)) { + tags.add(FakeTileEntity.createTileEntity( + ChunkSection.xFromIndex(idx) + (chunk.getX() << 4), + ChunkSection.yFromIndex(idx) + (s << 4), + ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4), + id + )); } } }