title: How to load/Unload tile chunks faster(C#)
body: <p>Ok So basically in my game, The world is made out of tiles and the tiles are split into chunks(50x50 tiles and the tiles are 16x16) so the whole world isn't loaded in memory. The chunks are saved to files and only ones that are needed are loaded(ones on screen and 1 off-screen for each side of the screen(top, left, bottom, right)), and others are unloaded etc.. This all works fine however, When loading chunks that actually contain tiles the game logic freezes for quite a bit(you know to load the file?), Basically my question is how would I make my current methods faster, So there's little to no noticeable lag?</p>
  
  <p>Basically each chunk just contains a 2D array of bytes, Containing the tile type rather than the actual tile class, And That byte array is saved to a file to later be loaded.
  My chunk Loading/Saving functions:</p>
  
  <p>Saving:</p>
  
  <pre><code>    public void SaveChunk(int cx, int cy)
      {
  
          String chunkname = "";
          chunkname = WorldChunks[cx, cy].X + "_" + WorldChunks[cx, cy].Y;
  
          FileStream fileStream = File.Create(Main.ChunkPath + "\\Chunks\\" + chunkname + ".chnk");
          StreamWriter writer = new StreamWriter(fileStream);
          String json = JsonConvert.SerializeObject(WorldChunks[cx, cy].myTiles, Formatting.None);
          writer.Write(json);
          writer.Close();
      }
  </code></pre>
  
  <p>Loading:</p>
  
  <pre><code>    public void LoadChunk(int xx, int yy)
      {
  
          string chunkname = xx + "_" + yy;
          if (File.Exists(Main.ChunkPath + "\\Chunks\\" + chunkname + ".chnk"))
          {
              //If the chunk is not loaded, Create a new chunk and begin loading it's tiles.
              if (WorldChunks[xx, yy] == null)
              {
                  WorldChunks[xx, yy] = new Chunk(xx, yy);
              }
  
              System.Diagnostics.Debug.WriteLine("Loading chunk [" + xx + "," + yy + "]");
              Stream stream = File.Open(Main.ChunkPath + "\\Chunks\\" + chunkname + ".chnk", FileMode.Open);
              StreamReader reader = new StreamReader(stream);
              JsonSerializerSettings settings = new JsonSerializerSettings();
              settings.TypeNameHandling = TypeNameHandling.Objects;
              WorldChunks[xx, yy].myTiles = JsonConvert.DeserializeObject&lt;byte[,]&gt;(reader.ReadToEnd(), settings);
              stream.Close();
              System.Diagnostics.Debug.WriteLine("Chunk loaded.. [" + xx + "," + yy + "]");
              int x, y;
              for (x = 0; x &lt; Main.ChunkSizeX; x++)
              {
                  for (y = 0; y &lt; Main.ChunkSizeY; y++)
                  {
                      byte _Type = WorldChunks[xx, yy].myTiles[x, y];
                      int tx = (xx * ChunkSizeX) + x;
                      int ty = (yy * ChunkSizeY) + y;
                      if (_Type &gt; 0)
                      {
                          if (Tiles[tx, ty] == null &amp;&amp; tx &lt; MaxTilesX &amp;&amp; ty &lt; MaxTilesY)
                          {
                              Tiles[x + (xx * ChunkSizeX), (yy * ChunkSizeY) + y] = new Tile();
                              Tiles[(xx * ChunkSizeX) + x, (yy * ChunkSizeY) + y].Type = _Type;
                              if (ty &gt; GROUND_LEVEL[tx] + 1)
                              {
                                  //System.Diagnostics.Debug.Write("Below level:" + x + "|" + tx);
                                  Tiles[tx, ty].HasBG = true;
                              }
  
                          }
                          else continue;
                      }
  
                  }
              }
  
          }
  
      }
  </code></pre>
  
  <p>I've tried changing the chunksize around, I've tried 25x25, 16x16, 35x35 etc etc.. But still to no avail.
  So How could I make these functions faster? Any other tips/advice would be very much appreciated! Thanks!</p>
  
  <p>EDIT: The bottleneck in my code going from stopwatch and other tests is the actual loading from the file I even removed the placing of the tiles and it still locked up the game logic however I realized the biggest noticeable delays are when I'm in-between chunks and it has to load more chunks than usual like so:
  <a href="https://i.stack.imgur.com/XwcU9.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XwcU9.png" alt="Picturing showing when my game logic takes the biggest hit"></a>
  </p>
  
  <p>Now my may be chunks actually bigger than that, but that same thing is possible.</p>
  
  <p>My save function simply saves 1 byte per tile, My file size is only 2.5kb or so per chunk, As there are 2,500 tiles per chunk and 1 byte per tile (just saves the type of tile).</p>
  
  <p>So I didn't think saving and loading them would be much of an impact, I have setup an async filestream as well earlier on, But the performance was practically the same.</p>
  
  <p>Here's my code for loading/unloading chunks:</p>
  
  <pre><code>    public void CheckChunks()
      {
          int StartX = (int)Math.Floor(ScreenPosition.X / (ChunkSizeX * 16)) - 2;
          int StartY = (int)Math.Floor(ScreenPosition.Y / (ChunkSizeY * 16)) - 2;
  
          if (StartX &lt; 0) StartX = 0;
          if (StartY &lt; 0) StartY = 0;
  
          int EndX = (int)Math.Floor((ScreenPosition.X + GraphicsDevice.Viewport.Width) / (ChunkSizeX * 16)) + 2;
          int EndY = (int)Math.Floor((ScreenPosition.Y + GraphicsDevice.Viewport.Height) / (ChunkSizeY * 16)) + 2;
          if (EndX &gt; MaxChunksX) EndX = MaxChunksX;
          if (EndY &gt; MaxChunksY) EndY = MaxChunksY;
  
          for (int x = StartX; x &lt; EndX; x++)
          {
              for (int y = StartY; y &lt; EndY; y++)
              {
                  if (WorldChunks[x, y] == null)
                  {
  
                      LoadChunk(x, y, true);
  
                      if (WorldChunks[x, y] != null)
                      {
  
                          LoadedChunks.Add(WorldChunks[x, y]);
                      }
                       break;
                  }
  
              }
          }
  
              foreach (Chunk cc in LoadedChunks)
              {
  
                  if (cc.X &lt; StartX  || cc.Y &lt; StartY || cc.X &gt;EndX || cc.Y &gt; EndY)
                  {
                      System.Diagnostics.Debug.WriteLine("Chunk to be unloaded..");
                      ChunkBuffer.Add(cc);
                      UnloadChunk(cc);
  
                  }
              }
  
              foreach (Chunk c in ChunkBuffer)
              {
                  LoadedChunks.Remove(c);
              }
          ChunkBuffer.Clear();
  
      }
  </code></pre>
  
  <p>How do games like minecraft load and unload their chunks so quickly?</p>