--- ../src-base/minecraft/net/minecraft/server/MinecraftServer.java
+++ ../src-work/minecraft/net/minecraft/server/MinecraftServer.java
@@ -99,7 +99,7 @@
     @SideOnly(Side.SERVER)
     private String field_71320_r;
     private int field_71319_s = -1;
-    public WorldServer[] field_71305_c;
+    public WorldServer[] field_71305_c = new WorldServer[0];
     private ServerConfigurationManager field_71318_t;
     private boolean field_71317_u = true;
     private boolean field_71316_v;
@@ -116,7 +116,8 @@
     private int field_71280_D;
     private int field_143008_E = 0;
     public final long[] field_71311_j = new long[100];
-    public long[][] field_71312_k;
+    //public long[][] timeOfLastDimensionTick;
+    public java.util.Hashtable<Integer, long[]> worldTickTimes = new java.util.Hashtable<Integer, long[]>();
     private KeyPair field_71292_I;
     private String field_71293_J;
     private String field_71294_K;
@@ -222,8 +223,6 @@
     {
         this.func_71237_c(p_71247_1_);
         this.func_71192_d("menu.loadingLevel");
-        this.field_71305_c = new WorldServer[3];
-        this.field_71312_k = new long[this.field_71305_c.length][100];
         ISaveHandler isavehandler = this.field_71310_m.func_75804_a(p_71247_1_, true);
         this.func_175584_a(this.func_71270_I(), isavehandler);
         WorldInfo worldinfo = isavehandler.func_75757_d();
@@ -254,47 +253,21 @@
             worldsettings = new WorldSettings(worldinfo);
         }
 
-        for (int j = 0; j < this.field_71305_c.length; ++j)
+        WorldServer overWorld = (WorldServer)(func_71242_L() ? new DemoWorldServer(this, isavehandler, worldinfo, 0, field_71304_b).func_175643_b() : new WorldServer(this, isavehandler, worldinfo, 0, field_71304_b).func_175643_b());
+        overWorld.func_72963_a(worldsettings);
+        for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs())
         {
-            byte b0 = 0;
+            WorldServer world = (dim == 0 ? overWorld : (WorldServer)new WorldServerMulti(this, isavehandler, dim, overWorld, field_71304_b).func_175643_b());
+            world.func_72954_a(new WorldManager(this, world));
 
-            if (j == 1)
-            {
-                b0 = -1;
-            }
-
-            if (j == 2)
-            {
-                b0 = 1;
-            }
-
-            if (j == 0)
-            {
-                if (this.func_71242_L())
-                {
-                    this.field_71305_c[j] = (WorldServer)(new DemoWorldServer(this, isavehandler, worldinfo, b0, this.field_71304_b)).func_175643_b();
-                }
-                else
-                {
-                    this.field_71305_c[j] = (WorldServer)(new WorldServer(this, isavehandler, worldinfo, b0, this.field_71304_b)).func_175643_b();
-                }
-
-                this.field_71305_c[j].func_72963_a(worldsettings);
-            }
-            else
-            {
-                this.field_71305_c[j] = (WorldServer)(new WorldServerMulti(this, isavehandler, b0, this.field_71305_c[0], this.field_71304_b)).func_175643_b();
-            }
-
-            this.field_71305_c[j].func_72954_a(new WorldManager(this, this.field_71305_c[j]));
-
             if (!this.func_71264_H())
             {
-                this.field_71305_c[j].func_72912_H().func_76060_a(this.func_71265_f());
+                world.func_72912_H().func_76060_a(this.func_71265_f());
             }
+            net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world));
         }
 
-        this.field_71318_t.func_72364_a(this.field_71305_c);
+        this.field_71318_t.func_72364_a(new WorldServer[]{ overWorld });
         this.func_147139_a(this.func_147135_j());
         this.func_71222_d();
     }
@@ -309,7 +282,7 @@
         this.func_71192_d("menu.generatingTerrain");
         byte b0 = 0;
         field_147145_h.info("Preparing start region for level " + b0);
-        WorldServer worldserver = this.field_71305_c[b0];
+        WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(b0);
         BlockPos blockpos = worldserver.func_175694_M();
         long j = func_130071_aq();
 
@@ -371,6 +344,7 @@
         if (!this.field_71290_O)
         {
             WorldServer[] aworldserver = this.field_71305_c;
+            if (aworldserver == null) return; //Forge: Just in case, NPE protection as it has been encountered.
             int i = aworldserver.length;
 
             for (int j = 0; j < i; ++j)
@@ -423,8 +397,15 @@
                 for (int i = 0; i < this.field_71305_c.length; ++i)
                 {
                     WorldServer worldserver = this.field_71305_c[i];
+                    net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(worldserver));
                     worldserver.func_73041_k();
                 }
+
+                WorldServer[] tmp = field_71305_c;
+                for (WorldServer world : tmp)
+                {
+                    net.minecraftforge.common.DimensionManager.setWorld(world.field_73011_w.func_177502_q(), null);
+                }
             }
 
             if (this.field_71307_n.func_76468_d())
@@ -681,15 +662,18 @@
         }
 
         this.field_71304_b.func_76318_c("levels");
+        net.minecraftforge.common.chunkio.ChunkIOExecutor.tick();
         int j;
 
-        for (j = 0; j < this.field_71305_c.length; ++j)
+        Integer[] ids = net.minecraftforge.common.DimensionManager.getIDs(this.field_71315_w % 200 == 0);
+        for (int x = 0; x < ids.length; x++)
         {
+            int id = ids[x];
             long i = System.nanoTime();
 
-            if (j == 0 || this.func_71255_r())
+            if (id == 0 || this.func_71255_r())
             {
-                WorldServer worldserver = this.field_71305_c[j];
+                WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id);
                 this.field_71304_b.func_76320_a(worldserver.func_72912_H().func_76065_j());
 
                 if (this.field_71315_w % 20 == 0)
@@ -733,9 +717,11 @@
                 this.field_71304_b.func_76319_b();
             }
 
-            this.field_71312_k[j][this.field_71315_w % 100] = System.nanoTime() - i;
+            worldTickTimes.get(id)[this.field_71315_w % 100] = System.nanoTime() - i;
         }
 
+        this.field_71304_b.func_76318_c("dim_unloading");
+        net.minecraftforge.common.DimensionManager.unloadWorlds(worldTickTimes);
         this.field_71304_b.func_76318_c("connection");
         this.func_147137_ag().func_151269_c();
         this.field_71304_b.func_76318_c("players");
@@ -774,7 +760,13 @@
 
     public WorldServer func_71218_a(int p_71218_1_)
     {
-        return p_71218_1_ == -1 ? this.field_71305_c[1] : (p_71218_1_ == 1 ? this.field_71305_c[2] : this.field_71305_c[0]);
+        WorldServer ret = net.minecraftforge.common.DimensionManager.getWorld(p_71218_1_);
+        if (ret == null)
+        {
+            net.minecraftforge.common.DimensionManager.initDimension(p_71218_1_);
+            ret = net.minecraftforge.common.DimensionManager.getWorld(p_71218_1_);
+        }
+        return ret;
     }
 
     public String func_71249_w()
@@ -1025,6 +1017,7 @@
 
             if (worldserver != null)
             {
+                net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(worldserver));
                 worldserver.func_73041_k();
             }
         }
@@ -1607,7 +1600,6 @@
         this.field_71319_s = p_71208_1_;
     }
 
-    @SideOnly(Side.SERVER)
     public boolean func_71241_aa()
     {
         return this.field_71316_v;
