Index: binary-improvements/7dtd-server-fixes/src/FileCache/MapTileCache.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/FileCache/MapTileCache.cs	(revision 330)
+++ binary-improvements/7dtd-server-fixes/src/FileCache/MapTileCache.cs	(revision 331)
@@ -46,5 +46,5 @@
 
 						Profiler.BeginSample ("ReadPng");
-						cacheEntry.pngData = File.ReadAllBytes (filename);
+						cacheEntry.pngData = ReadAllBytes (filename);
 						Profiler.EndSample ();
 					}
@@ -63,6 +63,7 @@
 				lock (cache) {
 					CurrentZoomFile cacheEntry = cache [zoomlevel];
-					
-					if (string.IsNullOrEmpty (cacheEntry.filename)) {
+
+					string file = cacheEntry.filename;
+					if (string.IsNullOrEmpty (file)) {
 						return;
 					}
@@ -71,5 +72,8 @@
 
 					Profiler.BeginSample ("WritePng");
-					File.WriteAllBytes (cacheEntry.filename, contentPng);
+					using (Stream stream = new FileStream (file, FileMode.Create, FileAccess.ReadWrite, FileShare.None,
+						4096)) {
+						stream.Write (contentPng, 0, contentPng.Length);
+					}
 					Profiler.EndSample ();
 				}
@@ -92,5 +96,5 @@
 					}
 
-					return File.ReadAllBytes (filename);
+					return ReadAllBytes (filename);
 				}
 			} catch (Exception e) {
@@ -101,4 +105,24 @@
 		}
 
+		private static byte[] ReadAllBytes (string _path) {
+			using (FileStream fileStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096)) {
+				int bytesRead = 0;
+				int bytesLeft = (int) fileStream.Length;
+				byte[] result = new byte[bytesLeft];
+				while (bytesLeft > 0) {
+					int readThisTime = fileStream.Read (result, bytesRead, bytesLeft);
+					if (readThisTime == 0) {
+						throw new IOException ("Unexpected end of stream");
+					}
+
+					bytesRead += readThisTime;
+					bytesLeft -= readThisTime;
+				}
+
+				return result;
+			}
+		}
+
+
 		private class CurrentZoomFile {
 			public string filename;
Index: binary-improvements/MapRendering/API.cs
===================================================================
--- binary-improvements/MapRendering/API.cs	(revision 330)
+++ binary-improvements/MapRendering/API.cs	(revision 331)
@@ -2,5 +2,5 @@
 using AllocsFixes.NetConnections.Servers.Web.Handlers;
 
-namespace MapRendering {
+namespace AllocsFixes {
 	public class API : IModApi {
 		public void InitMod () {
Index: binary-improvements/MapRendering/MapRendering/Constants.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/Constants.cs	(revision 330)
+++ binary-improvements/MapRendering/MapRendering/Constants.cs	(revision 331)
@@ -1,4 +1,7 @@
+using UnityEngine;
+
 namespace AllocsFixes.MapRendering {
 	public class Constants {
+		public static TextureFormat DEFAULT_TEX_FORMAT = TextureFormat.ARGB32;
 		public static int MAP_BLOCK_SIZE = 128;
 		public static int MAP_CHUNK_SIZE = 16;
Index: binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs	(revision 330)
+++ binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs	(revision 331)
@@ -8,8 +8,8 @@
 namespace AllocsFixes.MapRendering {
 	public class MapRenderBlockBuffer {
-		private readonly Texture2D blockMap = new Texture2D (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, TextureFormat.ARGB32, false);
+		private readonly Texture2D blockMap = new Texture2D (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, Constants.DEFAULT_TEX_FORMAT, false);
 		private readonly MapTileCache cache;
-		private readonly Color nullColor = new Color (0, 0, 0, 0);
-		private readonly Texture2D zoomBuffer = new Texture2D (1, 1, TextureFormat.ARGB32, false);
+		private readonly NativeArray<int> emptyImageData;
+		private readonly Texture2D zoomBuffer = new Texture2D (Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2, Constants.DEFAULT_TEX_FORMAT, false);
 		private readonly int zoomLevel;
 		private readonly string folderBase;
@@ -23,12 +23,23 @@
 			this.cache = cache;
 			folderBase = Constants.MAP_DIRECTORY + "/" + zoomLevel + "/";
+
+			{
+				// Initialize empty tile data
+				Color nullColor = new Color (0, 0, 0, 0);
+				for (int x = 0; x < Constants.MAP_BLOCK_SIZE; x++) {
+					for (int y = 0; y < Constants.MAP_BLOCK_SIZE; y++) {
+						blockMap.SetPixel (x, y, nullColor);
+					}
+				}
+
+				NativeArray<int> blockMapData = blockMap.GetRawTextureData<int> ();
+				emptyImageData = new NativeArray<int> (blockMapData.Length, Allocator.Persistent,
+					NativeArrayOptions.UninitializedMemory);
+				blockMapData.CopyTo (emptyImageData);
+			}
 		}
 
 		public TextureFormat FormatSelf {
 			get { return blockMap.format; }
-		}
-
-		public TextureFormat FormatScaled {
-			get { return zoomBuffer.format; }
 		}
 
@@ -40,15 +51,15 @@
 
 		public void SaveBlock () {
+			Profiler.BeginSample ("SaveBlock");
 			try {
-				if (currentBlockMapFilename.Length > 0) {
-					saveTextureToFile (currentBlockMapFilename);
-				}
+				saveTextureToFile ();
 			} catch (Exception e) {
 				Log.Warning ("Exception in MapRenderBlockBuffer.SaveBlock(): " + e);
 			}
+			Profiler.EndSample ();
 		}
 
 		public bool LoadBlock (Vector2i block) {
-			bool res = false;
+			Profiler.BeginSample ("LoadBlock");
 			lock (blockMap) {
 				if (currentBlockMapPos != block) {
@@ -56,5 +67,5 @@
 					string folder;
 					if (currentBlockMapPos.x != block.x) {
-						folder = folderBase + block.x;
+						folder = folderBase + block.x + '/';
 
 						Profiler.BeginSample ("LoadBlock.Directory");
@@ -65,20 +76,21 @@
 					}
 
-					string fileName = folder + "/" + block.y + ".png";
+					string fileName = folder + block.y + ".png";
 					Profiler.EndSample ();
 					
-					if (!fileName.Equals (currentBlockMapFilename)) {
-						res = true;
-						SaveBlock ();
-						loadTextureFromFile (fileName);
-					}
+					SaveBlock ();
+					loadTextureFromFile (fileName);
 
 					currentBlockMapFolder = folder;
 					currentBlockMapPos = block;
 					currentBlockMapFilename = fileName;
-				}
-			}
-
-			return res;
+
+					Profiler.EndSample ();
+					return true;
+				}
+			}
+
+			Profiler.EndSample ();
+			return false;
 		}
 
@@ -147,26 +159,35 @@
 		public NativeArray<int> GetHalfScaledNative () {
 			Profiler.BeginSample ("HalfScaledNative.ResizeBuffer");
-			zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
-			Profiler.EndSample ();
-
-			Profiler.BeginSample ("HalfScaledNative.CopyPixels");
-			if (blockMap.format == zoomBuffer.format) {
-				Profiler.BeginSample ("Native");
-				NativeArray<byte> dataSrc = blockMap.GetRawTextureData<byte> ();
-				NativeArray<byte> dataZoom = zoomBuffer.GetRawTextureData<byte> ();
-				dataSrc.CopyTo (dataZoom);
-				Profiler.EndSample ();
-			} else {
-				Profiler.BeginSample ("GetSetPixels");
-				zoomBuffer.SetPixels32 (blockMap.GetPixels32 ());
-				Profiler.EndSample ();
+			if (zoomBuffer.format != blockMap.format || zoomBuffer.height != Constants.MAP_BLOCK_SIZE / 2 || zoomBuffer.width != Constants.MAP_BLOCK_SIZE / 2) {
+				zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2, blockMap.format, false);
 			}
 			Profiler.EndSample ();
 
 			Profiler.BeginSample ("HalfScaledNative.Scale");
-			TextureScale.Point (zoomBuffer, Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2);
+			ScaleNative (blockMap, zoomBuffer);
 			Profiler.EndSample ();
 
 			return zoomBuffer.GetRawTextureData<int> ();
+		}
+		
+		private static void ScaleNative (Texture2D _sourceTex, Texture2D _targetTex) {
+			NativeArray<int> srcData = _sourceTex.GetRawTextureData<int> ();
+			NativeArray<int> targetData = _targetTex.GetRawTextureData<int> ();
+			
+			int oldWidth = _sourceTex.width;
+			int oldHeight = _sourceTex.height;
+			int newWidth = _targetTex.width;
+			int newHeight = _targetTex.height;
+			
+			float ratioX = ((float) oldWidth) / newWidth;
+			float ratioY = ((float) oldHeight) / newHeight;
+
+			for (var y = 0; y < newHeight; y++) {
+				var oldLineStart = (int) (ratioY * y) * oldWidth;
+				var newLineStart = y * newWidth;
+				for (var x = 0; x < newWidth; x++) {
+					targetData [newLineStart + x] = srcData [(int) (oldLineStart + ratioX * x)];
+				}
+			}
 		}
 
@@ -192,19 +213,16 @@
 			}
 
-			if (blockMap.height != Constants.MAP_BLOCK_SIZE || blockMap.width != Constants.MAP_BLOCK_SIZE) {
-				blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, TextureFormat.ARGB32, false);
-			}
-
-			for (int x = 0; x < Constants.MAP_BLOCK_SIZE; x++) {
-				for (int y = 0; y < Constants.MAP_BLOCK_SIZE; y++) {
-					blockMap.SetPixel (x, y, nullColor);
-				}
-			}
-			Profiler.EndSample ();
-		}
-
-		private void saveTextureToFile (string _fileName) {
-			Profiler.BeginSample ("SaveTexture");
-
+			if (blockMap.format != Constants.DEFAULT_TEX_FORMAT || blockMap.height != Constants.MAP_BLOCK_SIZE ||
+			    blockMap.width != Constants.MAP_BLOCK_SIZE) {
+				blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, Constants.DEFAULT_TEX_FORMAT,
+					false);
+			}
+
+			blockMap.LoadRawTextureData (emptyImageData);
+
+			Profiler.EndSample ();
+		}
+
+		private void saveTextureToFile () {
 			Profiler.BeginSample ("EncodePNG");
 			byte[] array = blockMap.EncodeToPNG ();
@@ -212,5 +230,4 @@
 
 			cache.SaveTile (zoomLevel, array);
-			Profiler.EndSample ();
 		}
 	}
Index: binary-improvements/MapRendering/MapRendering/MapRendering.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/MapRendering.cs	(revision 330)
+++ binary-improvements/MapRendering/MapRendering/MapRendering.cs	(revision 331)
@@ -246,4 +246,5 @@
 
 			Profiler.BeginSample ("RenderDirtyChunks.Work");
+			// Write all chunks that are in the same image tile of the highest zoom level 
 			Vector2i v_block, v_blockOffset;
 			foreach (Vector2i v in chunksToRender) {
@@ -268,4 +269,5 @@
 			}
 
+			// Update lower zoom levels affected by the change of the highest one
 			RenderZoomLevel (block);
 
@@ -285,7 +287,7 @@
 
 				Profiler.BeginSample ("RenderZoomLevel.Transfer");
-				if ((zoomLevelBuffers [level].FormatScaled == TextureFormat.ARGB32 ||
-				     zoomLevelBuffers [level].FormatScaled == TextureFormat.RGBA32) &&
-				    zoomLevelBuffers [level].FormatScaled == zoomLevelBuffers [level - 1].FormatSelf) {
+				if ((zoomLevelBuffers [level].FormatSelf == TextureFormat.ARGB32 ||
+				     zoomLevelBuffers [level].FormatSelf == TextureFormat.RGBA32) &&
+				    zoomLevelBuffers [level].FormatSelf == zoomLevelBuffers [level - 1].FormatSelf) {
 					zoomLevelBuffers [level - 1].SetPartNative (blockOffset, Constants.MAP_BLOCK_SIZE / 2, zoomLevelBuffers [level].GetHalfScaledNative ());
 				} else {
Index: binary-improvements/MapRendering/WebAndMapRendering.csproj
===================================================================
--- binary-improvements/MapRendering/WebAndMapRendering.csproj	(revision 330)
+++ binary-improvements/MapRendering/WebAndMapRendering.csproj	(revision 331)
@@ -70,5 +70,4 @@
     <Compile Include="Commands\EnableRendering.cs" />
     <Compile Include="API.cs" />
-    <Compile Include="MapRendering\TextureScale.cs" />
     <Compile Include="Web\API\GetAnimalsLocation.cs" />
     <Compile Include="Web\API\GetHostileLocation.cs" />
