diff --git a/Runtime/TerrainBuilder.cs b/Runtime/TerrainBuilder.cs
index 4c16d2737761ffbf1eb450d2923300add0681cc9..403e4a058c868397d62eb5cb829ec425b473c8b1 100644
--- a/Runtime/TerrainBuilder.cs
+++ b/Runtime/TerrainBuilder.cs
@@ -21,10 +21,10 @@ namespace Wander
         [ReadOnly] public int nTilesWide;
         [ReadOnly] public int nTilesHigh;
         [ReadOnly] public Dictionary<uint, byte> pixelToLayerIndex;
-        [ReadOnly] public List<TerrainTile> tiles = new List<TerrainTile>();
+        
 
         public Vector2 originWGS84          = new Vector2(51.985365f, 5.664941f); // Copy directly from Google maps. This is Forum on Campus WUR.
-        public Vector2Int numTiles          = new Vector2Int(1,1);
+        public int numRings                 = 1;
         public int controlResolution        = 8192;
         public int heightMapResolution      = 1024;
         public bool loadHeight              = true;
@@ -32,17 +32,26 @@ namespace Wander
         public int zoom                     = 11;
         public int numDLRetries             = 5;
         public bool runOnStart              = false;
+        public int maxDownloads             = 32;
+        public string prefix                = "Terrain";
         public Material terrainMat          = null;
         public List<TerrainLayer2> layers;
+
+
+        private List<TerrainTile> tiles     = new List<TerrainTile>();
 
         internal void CancelAndClean()
         {
-            tiles.ForEach( t => t.CancelAndClean() ); 
+            tiles.ForEach( t =>
+            {
+                if (t!=null) t.CancelAndClean();
+            } );
             tiles = new List<TerrainTile>();
         }
 
         internal void Build()
         {
+            CancelAndClean();
             CalcPreliminaries();
             CreatePixelToLayerIndex();
             CreateTerrain();
@@ -94,24 +103,50 @@ namespace Wander
             }
         }
 
+        Terrain GetNeighbour( string prefix, int x, int y )
+        {
+            var neighbour = GameObject.Find( $"{prefix}_{x}_{y-1}" );
+            if (neighbour != null)
+                return neighbour.GetComponent<Terrain>();
+            return null;
+        }
+
+        void BuildTile( double rdX, double rdY, int x, int y )
+        {
+            GameObject go = new GameObject($"{prefix}_{x}_{y}");
+            var tile = go.AddComponent<TerrainTile>();
+            tiles.Add( tile );
+            tile.builder        = this;
+            tile.tileOrigin     = RDUtils.RD2Tile( new Vector2( (float)rdX+adjustedSize.x * x, (float)rdY+adjustedSize.z * y ), zoom );
+            tile.rdOrigin       = RDUtils.Tile2RD( tile.tileOrigin, zoom );
+            tile.terrainOffset  = new Vector2Int( x, y );
+            tile.Build();
+        }
+
         void CreateTerrain()
         {
             RDUtils.GPS2RD( originWGS84.x, originWGS84.y, out double rdX, out double rdY );
-            for ( int y = -numTiles.y/2; y <= numTiles.y/2; y++ )
+            BuildTile( rdX, rdY, 0, 0 );
+            for (int c = 1;c <= numRings;c++)
             {
-                for (int x = -numTiles.y/2;x <= numTiles.x/2;x++)
-                {
-                    
-                    GameObject go = new GameObject($"GeneratedTerrain_{x}_{y}");
-                    var tile = go.AddComponent<TerrainTile>();
-                    tiles.Add( tile );
-                    tile.builder        = this;
-                    tile.tileOrigin     = RDUtils.RD2Tile( new Vector2( (float)rdX+adjustedSize.x * x, (float)rdY+adjustedSize.z * y ), zoom );
-                    tile.rdOrigin       = RDUtils.Tile2RD( tile.tileOrigin, zoom );
-                    tile.terrainOffset  = new Vector2Int( x, y );
-                    tile.Build();
-                }
+                for (int y2 = -c; y2 <= c; y2++)        BuildTile( rdX, rdY, -c, y2 );
+                for (int y2 = -c; y2 <= c; y2++)        BuildTile( rdX, rdY, c, y2 );
+                for (int x2 = -c+1; x2 <= c-1; x2++)    BuildTile( rdX, rdY, x2, c );
+                for (int x2 = -c+1; x2 <= c-1; x2++)    BuildTile( rdX, rdY, x2, -c );
             }
+            GameObject terrainRoot = new GameObject("TerrainRoot");
+            tiles.ForEach( t =>
+            {
+                var ofs = t.GetComponent<TerrainTile>().terrainOffset;
+                int x = ofs.x;
+                int y = ofs.y;
+                var top = GetNeighbour( prefix, x, y+1 );
+                var bottom = GetNeighbour( prefix, x, y-1 );
+                var left = GetNeighbour( prefix, x-1, y );
+                var right = GetNeighbour( prefix, x+1, y );
+                t.GetComponent<Terrain>().SetNeighbors( left, top, right, bottom );
+                t.transform.SetParent( terrainRoot.transform, true );
+            } );
         }
     }
 
@@ -124,7 +159,8 @@ namespace Wander
         {
             TerrainBuilder builder = (TerrainBuilder)target;
 
-            EditorGUILayout.HelpBox( "Look up a location in Google maps and copy GPS coordinates in Origin WGS84 X, Y.", MessageType.Info, true );
+            EditorGUILayout.HelpBox( "Look up a location in Google maps and copy GPS coordinates in Origin WGS84 X, Y", MessageType.Info, true );
+            EditorGUILayout.HelpBox( "Press CTRL-S when done, otherwise result appears wrong.", MessageType.Warning, true );
 
             GUILayout.BeginHorizontal();
             {
diff --git a/Runtime/TerrainTile.cs b/Runtime/TerrainTile.cs
index c35a9c99b8840bb3e903f5a56528eec8df59e285..ad097c3f77167543fee4ef6561888192505f6906 100644
--- a/Runtime/TerrainTile.cs
+++ b/Runtime/TerrainTile.cs
@@ -9,8 +9,9 @@ using UnityEngine.Networking;
 
 namespace Wander
 {
-    struct MapTile
+    class MapTile
     {
+        internal bool started;
         internal int numRetries;
         internal int deltaTileX; // Relative tile index with respect to origin up left corner. So, 0, -1, etc.
         internal int deltaTileY;
@@ -33,7 +34,7 @@ namespace Wander
         [ReadOnly] public TerrainBuilder builder;
         [ReadOnly] public TerrainData terrainData;
         [ReadOnly] public Terrain terrain;
-        [ReadOnly] public Vector2Int terrainOffset = new Vector2Int(0, 0);
+        [ReadOnly] public Vector2Int terrainOffset;
 
         private List<MapTile> requests;
         private byte[] controlData;
@@ -96,6 +97,7 @@ namespace Wander
                         }
                     }
 
+                    // If want height and height is finished.
                     if ( builder.loadHeight )
                     {
                         if (normalizeHeightTask == null && asyncHeightHandle.IsFinished() && asyncHeightHandle.Valid )
@@ -143,6 +145,8 @@ namespace Wander
 
             gameObject.AddComponent<TerrainCollider>().terrainData = terrainData;
             gameObject.transform.position = new Vector3( terrainOffset.x*builder.adjustedSize.x, 0, terrainOffset.y*builder.adjustedSize.z );
+
+
         }
 
         internal void SyncLayersToMaterial()
@@ -244,7 +248,7 @@ namespace Wander
                     int tileY  = -y + tileOrigin.y;
                     string url = GetMapUrl(tileX, tileY, builder.zoom);
                     UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
-                    www.SendWebRequest();
+                    //www.SendWebRequest();
                     MapTile td = new MapTile();
                     td.www = www;
                     td.deltaTileX = x;
@@ -267,10 +271,16 @@ namespace Wander
             if (requests==null)
                 return;
 
+            int numActive = 0;
             for (int i = 0;i < requests.Count;i++)
             {
                 var tile = requests[i];
                 var www  = tile.www;
+                if (!tile.started)
+                {
+                    tile.started = true;
+                    www.SendWebRequest();
+                }
                 if (www.isDone)
                 {
                     if (www.result != UnityWebRequest.Result.Success)
@@ -301,6 +311,8 @@ namespace Wander
                         i--;
                     }
                 }
+                if (++numActive == builder.maxDownloads)
+                    break;
             }
         }
 
@@ -317,8 +329,8 @@ namespace Wander
 
         float[,] CreateHeightMap( HeightData heightData )
         {
-            var heights = new float[builder.heightMapResolution, builder.heightMapResolution];
-            int height   = heightData.height;
+            var heights = new float[builder.heightMapResolution+1, builder.heightMapResolution+1];
+            int height  = heightData.height;
             for (int y = 0;y<height;y++) 
             {
                 if (state== State.None)
@@ -332,6 +344,11 @@ namespace Wander
                     heights[height-y-1, x] = absHeight;
                 }
             }
+            for (int y = 0;y <height;y++) 
+                heights[y, heightData.width] = heights[y, heightData.width-1];
+            for (int x = 0;x <heightData.width;x++) 
+                heights[height, x] = heights[height-1, x];
+            heights[height, heightData.width] = heights[height, heightData.width-1];
             return heights;
         }
 
diff --git a/TerrainBuilder.prefab b/TerrainBuilder.prefab
index 3cb4f2edc3c57539b720d322a9c4502b7e3c1c29..6f1f2464556d8f425e31ede0b5265f76f2b43e83 100644
--- a/TerrainBuilder.prefab
+++ b/TerrainBuilder.prefab
@@ -44,24 +44,21 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: cd43ca4104daaec4a9d3a76a67972b44, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  rdOrigin: {x: 170214.08, y: 440729.9}
-  tileOrigin: {x: 33900, y: 34424}
   adjustedSize: {x: 215.04, y: 200, z: 215.04}
   tileSize: 13.44
   tilePixelSize: 256
   nTilesWide: 16
   nTilesHigh: 16
-  terrainData: {fileID: 0}
-  terrain: {fileID: 0}
   originWGS84: {x: 51.954845, y: 5.608702}
-  terrainOffset: {x: 0, y: 0}
+  numRings: 1
   controlResolution: 4096
   heightMapResolution: 256
   loadHeight: 1
   terrainHeight: 200
   zoom: 16
-  numDLRetries: 5
+  numDLRetries: 10
   runOnStart: 0
+  maxDownloads: 16
   terrainMat: {fileID: 2100000, guid: 85a6a12772aee984dac2ab9fa88f3370, type: 2}
   layers:
   - layer: {fileID: 8574412962073106934, guid: f963e57374ac1ff44b017a60c3f8ad82, type: 2}