--- ../src-base/minecraft/net/minecraft/server/management/PlayerManager.java
+++ ../src-work/minecraft/net/minecraft/server/management/PlayerManager.java
@@ -122,15 +122,24 @@
         int j = (int)p_72683_1_.field_70161_v >> 4;
         p_72683_1_.field_71131_d = p_72683_1_.field_70165_t;
         p_72683_1_.field_71132_e = p_72683_1_.field_70161_v;
+        // Load nearby chunks first
+        List<ChunkCoordIntPair> chunkList = new ArrayList<ChunkCoordIntPair>();
 
         for (int k = i - this.field_72698_e; k <= i + this.field_72698_e; ++k)
         {
             for (int l = j - this.field_72698_e; l <= j + this.field_72698_e; ++l)
             {
-                this.func_72690_a(k, l, true).func_73255_a(p_72683_1_);
+                chunkList.add(new ChunkCoordIntPair(k, l));
             }
         }
 
+        java.util.Collections.sort(chunkList, new net.minecraftforge.common.util.ChunkCoordComparator(p_72683_1_));
+
+        for (ChunkCoordIntPair pair : chunkList)
+        {
+            this.func_72690_a(pair.field_77276_a, pair.field_77275_b, true).func_73255_a(p_72683_1_);
+        }
+
         this.field_72699_b.add(p_72683_1_);
         this.func_72691_b(p_72683_1_);
     }
@@ -232,6 +241,7 @@
             int i1 = this.field_72698_e;
             int j1 = i - k;
             int k1 = j - l;
+            List<ChunkCoordIntPair> chunksToLoad = new ArrayList<ChunkCoordIntPair>();
 
             if (j1 != 0 || k1 != 0)
             {
@@ -241,7 +251,7 @@
                     {
                         if (!this.func_72684_a(l1, i2, k, l, i1))
                         {
-                            this.func_72690_a(l1, i2, true).func_73255_a(p_72685_1_);
+                            chunksToLoad.add(new ChunkCoordIntPair(l1, i2));
                         }
 
                         if (!this.func_72684_a(l1 - j1, i2 - k1, i, j, i1))
@@ -259,6 +269,18 @@
                 this.func_72691_b(p_72685_1_);
                 p_72685_1_.field_71131_d = p_72685_1_.field_70165_t;
                 p_72685_1_.field_71132_e = p_72685_1_.field_70161_v;
+                // send nearest chunks first
+                java.util.Collections.sort(chunksToLoad, new net.minecraftforge.common.util.ChunkCoordComparator(p_72685_1_));
+
+                for (ChunkCoordIntPair pair : chunksToLoad)
+                {
+                    this.func_72690_a(pair.field_77276_a, pair.field_77275_b, true).func_73255_a(p_72685_1_);
+                }
+
+                if (i1 > 1 || i1 < -1 || j1 > 1 || j1 < -1)
+                {
+                    java.util.Collections.sort(p_72685_1_.field_71129_f, new net.minecraftforge.common.util.ChunkCoordComparator(p_72685_1_));
+                }
             }
         }
     }
@@ -334,12 +356,21 @@
         private int field_73262_e;
         private int field_73260_f;
         private long field_111198_g;
+        private final java.util.HashMap<EntityPlayerMP, Runnable> players = new java.util.HashMap<EntityPlayerMP, Runnable>();
+        private boolean loaded = false;
+        private Runnable loadedRunnable = new Runnable()
+        {
+            public void run()
+            {
+                PlayerInstance.this.loaded = true;
+            }
+        };
         private static final String __OBFID = "CL_00001435";
 
         public PlayerInstance(int p_i1518_2_, int p_i1518_3_)
         {
             this.field_73264_c = new ChunkCoordIntPair(p_i1518_2_, p_i1518_3_);
-            PlayerManager.this.func_72688_a().field_73059_b.func_73158_c(p_i1518_2_, p_i1518_3_);
+            PlayerManager.this.func_72688_a().field_73059_b.loadChunk(p_i1518_2_, p_i1518_3_, this.loadedRunnable);
         }
 
         public void func_73255_a(EntityPlayerMP p_73255_1_)
@@ -356,7 +387,24 @@
                 }
 
                 this.field_73263_b.add(p_73255_1_);
+                Runnable playerRunnable = null;
+                if (this.loaded)
+                {
                 p_73255_1_.field_71129_f.add(this.field_73264_c);
+                }
+                else
+                {
+                    final EntityPlayerMP tmp = p_73255_1_;
+                    playerRunnable = new Runnable()
+                    {
+                        public void run()
+                        {
+                            tmp.field_71129_f.add(PlayerInstance.this.field_73264_c);
+                        }
+                    };
+                    PlayerManager.this.func_72688_a().field_73059_b.loadChunk(this.field_73264_c.field_77276_a, this.field_73264_c.field_77275_b, playerRunnable);
+                }
+                this.players.put(p_73255_1_, playerRunnable);
             }
         }
 
@@ -364,6 +412,24 @@
         {
             if (this.field_73263_b.contains(p_73252_1_))
             {
+                // If we haven't loaded yet don't load the chunk just so we can clean it up
+                if (!this.loaded)
+                {
+                    net.minecraftforge.common.chunkio.ChunkIOExecutor.dropQueuedChunkLoad(PlayerManager.this.func_72688_a(), this.field_73264_c.field_77276_a, this.field_73264_c.field_77275_b, this.players.get(p_73252_1_));
+                    this.field_73263_b.remove(p_73252_1_);
+                    this.players.remove(p_73252_1_);
+
+                    if (this.field_73263_b.isEmpty())
+                    {
+                        net.minecraftforge.common.chunkio.ChunkIOExecutor.dropQueuedChunkLoad(PlayerManager.this.func_72688_a(), this.field_73264_c.field_77276_a, this.field_73264_c.field_77275_b, this.loadedRunnable);
+                        long i = (long) this.field_73264_c.field_77276_a + 2147483647L | (long) this.field_73264_c.field_77275_b + 2147483647L << 32;
+                        PlayerManager.this.field_72700_c.func_76159_d(i);
+                        PlayerManager.this.field_111193_e.remove(this);
+                    }
+
+                    return;
+                }
+
                 Chunk chunk = PlayerManager.this.field_72701_a.func_72964_e(this.field_73264_c.field_77276_a, this.field_73264_c.field_77275_b);
 
                 if (chunk.func_150802_k())
@@ -371,9 +437,12 @@
                     p_73252_1_.field_71135_a.func_147359_a(new S21PacketChunkData(chunk, true, 0));
                 }
 
+                this.players.remove(p_73252_1_);
                 this.field_73263_b.remove(p_73252_1_);
                 p_73252_1_.field_71129_f.remove(this.field_73264_c);
 
+                net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.UnWatch(field_73264_c, p_73252_1_));
+
                 if (this.field_73263_b.isEmpty())
                 {
                     long i = (long)this.field_73264_c.field_77276_a + 2147483647L | (long)this.field_73264_c.field_77275_b + 2147483647L << 32;
@@ -411,7 +480,7 @@
 
             this.field_73260_f |= 1 << (p_151253_2_ >> 4);
 
-            if (this.field_73262_e < 64)
+            //Forge; Cache everything, so always run
             {
                 short short1 = (short)(p_151253_1_ << 12 | p_151253_3_ << 8 | p_151253_2_);
 
@@ -423,6 +492,10 @@
                     }
                 }
 
+                if (field_73262_e == field_151254_d.length)
+                {
+                    field_151254_d = java.util.Arrays.copyOf(field_151254_d, field_151254_d.length << 1);
+                }
                 this.field_151254_d[this.field_73262_e++] = short1;
             }
         }
@@ -440,6 +513,7 @@
             }
         }
 
+        @SuppressWarnings("unused")
         public void func_73254_a()
         {
             if (this.field_73262_e != 0)
@@ -456,7 +530,7 @@
                     BlockPos blockpos = new BlockPos(i, j, k);
                     this.func_151251_a(new S23PacketBlockChange(PlayerManager.this.field_72701_a, blockpos));
 
-                    if (PlayerManager.this.field_72701_a.func_180495_p(blockpos).func_177230_c().func_149716_u())
+                    if (PlayerManager.this.field_72701_a.func_180495_p(blockpos).func_177230_c().hasTileEntity(PlayerManager.this.field_72701_a.func_180495_p(blockpos)))
                     {
                         this.func_151252_a(PlayerManager.this.field_72701_a.func_175625_s(blockpos));
                     }
@@ -465,13 +539,14 @@
                 {
                     int i1;
 
-                    if (this.field_73262_e == 64)
+                    if (this.field_73262_e == net.minecraftforge.common.ForgeModContainer.clumpingThreshold)
                     {
                         i = this.field_73264_c.field_77276_a * 16;
                         j = this.field_73264_c.field_77275_b * 16;
                         this.func_151251_a(new S21PacketChunkData(PlayerManager.this.field_72701_a.func_72964_e(this.field_73264_c.field_77276_a, this.field_73264_c.field_77275_b), false, this.field_73260_f));
 
-                        for (k = 0; k < 16; ++k)
+                        // Forge: Grabs ALL tile entities is costly on a modded server, only send needed ones
+                        for (k = 0; false && k < 16; ++k)
                         {
                             if ((this.field_73260_f & 1 << k) != 0)
                             {
@@ -488,7 +563,10 @@
                     else
                     {
                         this.func_151251_a(new S22PacketMultiBlockChange(this.field_73262_e, this.field_151254_d, PlayerManager.this.field_72701_a.func_72964_e(this.field_73264_c.field_77276_a, this.field_73264_c.field_77275_b)));
+                    }
 
+                    { //Forge: Send only the tile entities that are updated, Adding this brace lets us keep the indent and the patch small
+                        WorldServer world = PlayerManager.this.field_72701_a;
                         for (i = 0; i < this.field_73262_e; ++i)
                         {
                             j = (this.field_151254_d[i] >> 12 & 15) + this.field_73264_c.field_77276_a * 16;
@@ -496,7 +574,7 @@
                             i1 = (this.field_151254_d[i] >> 8 & 15) + this.field_73264_c.field_77275_b * 16;
                             BlockPos blockpos1 = new BlockPos(j, k, i1);
 
-                            if (PlayerManager.this.field_72701_a.func_180495_p(blockpos1).func_177230_c().func_149716_u())
+                            if (world.func_180495_p(blockpos1).func_177230_c().hasTileEntity(world.func_180495_p(blockpos1)))
                             {
                                 this.func_151252_a(PlayerManager.this.field_72701_a.func_175625_s(blockpos1));
                             }
