Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-105051

Nether portals (and other world loading) cause lag in low-bandwidth situations.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Awaiting Response
    • None
    • Minecraft 1.10.2
    • None
    • Ubuntu Linux 15.04 (kernel 3.19.0) x86_64
      OpenJDK 1.8.0_45
    • Confirmed
    • (Unassigned)

      Description:

      When someone joins a server, uses a Nether portal on a server, or otherwise causes a large amount of chunk-loading, and the server has low outgoing bandwidth (less than 10 Mb/s or so is noticeable), other players connected to the server will experience seriously increased latency and rubber-banding while the chunks are being loaded.

      To reproduce:

      Start a Minecraft server on a computer whose Internet connection is limited to about 3 Mb/s or so.

      Connect to the Minecraft server from one client. Walk around, break blocks, and do other things that are sensitive to latency.

      Connect again from another client. On the first client, notice increased latency (rubber-banding, no item drops, etc.)

      From the second client, enter a Nether portal. On the other side, immediately walk out of the portal. Notice that, after a few seconds, you are teleported back inside the portal (note: this one happens less regularly. I notice it more with further distance walked and from Nether to Overworld).

      Possible Explanation and Fix:

      Analysis of network traffic (read: watching nload) shows that when these chunks are being loaded, the server's outbound bandwidth becomes completely occupied with the chunk loading. This causes the server to ignore position and block updates from other players for a time.

      I've written a simple mod for 1.10 that fixes this problem. It queues outgoing chunk data packets and sends them at a configurable rate (default 3 per tick per player). Testing has shown that this removes the symptoms described above.

      Using MCP 9.31, the patch is approximately:

      Add to net.minecraft.entity.player.EntityPlayerMP.java:

           private int chunksSinceLastTick = 0;
           private Queue<SPacketChunkData> chunkQueue;
      
           public void queueChunkPacket(SPacketChunkData packet) {
              chunkQueue.add(packet);
          }
          // add to EntityPlayerMP(...)
          this.chunkQueue = new LinkedList<SPacketChunkData>();
          // add to onUpdateEntity(), within the try{} block
          while(chunkQueue.size() > 0 && this.chunksSinceLastTick < ((DedicatedServer) this.mcServer).getIntProperty("chunkrate", 3)) {
              connection.sendPacket(chunkQueue.poll());
              this.chunksSinceLastTick++;
          }
          this.chunksSinceLastTick = 0;
      

      Then, in net.minecraft.server.management.PlayerChunkMapEntry, change any player.connection.sendPacket(...) to player.queueChunkPacket(...) (in sentToPlayers() and sendNearbySpecialEntities()).

      Alternatively, I've attached the updated .java files.

            Unassigned Unassigned
            beebop_wiz Blake Thomas
            Votes:
            5 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: