Search code examples
c#monogamefile-storage

Saving/Loading multiple chunks into one file?


So a project I'm working on is a voxel based game and will have large 3d array chunks, the problem comes in saving them, I can't seem to figure out how to save multiple chunks of an array into one file and only load the required chunk from the file when needed. Any ideas as to how to go about doing this? Ideally I can make multiple smaller files but that could be inconvenient.


Solution

  • You can use a Header at the start of the file to tell the program where the chunks are located in the file

    something like

    Chunk1=256,Chunk2=512
    

    and so on.

    or you can store chunks with BinaryFormatter

    using System;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace Helpr
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] Chunks = new int[10 * 10]; //Created this dummy chunk array to show that it works
                for(int x = 0; x < 10; ++x)     
                {
                    for(int y = 0; y < 10; ++y)
                    {
                        Chunks[x + (10 * y)] = x * y;       //Set the data
                    }
                }
    
                SaveChunks(Chunks, "Chunks.world"); //Save the chunks with a file name to refer too later
    
                for(int i = 0; i < 100; ++i)
                {
                    Console.WriteLine(Chunks[i] + " "); //Write the data to the console so we can compare
                }
    
                Console.WriteLine(" ");
    
                Chunks = (int[])LoadChunks("Chunks.world"); //Load the file back into the chunk
    
                for (int i = 0; i < 100; ++i)
                {
                    Console.WriteLine(Chunks[i] + " "); //Log to see if it has worked
                }
    
                Console.ReadKey();                      //Pause so you can even read it!
            }
    
            public static void SaveChunks(object Chunks, string filePath)
            {
                BinaryFormatter bf = new BinaryFormatter();                             //Create a BinaryFormatter to change the chunks into a binary string
                FileStream fs = new FileStream(filePath, FileMode.Create);              //Create a filestream to create a new file to store the string
    
                try
                {
                    bf.Serialize(fs, Chunks);                                           //Serialize the data into a file
                }
                catch (Exception e)                                                     //if an error occurs Post it!
                {
                    Console.WriteLine("Failed to create Chunk file! " + e);
                }
                finally
                {
                    fs.Close();                                                         //Then close the filestream to prevent memory leaks
                }
            }
    
            public static object LoadChunks(string filePath)
            {
                BinaryFormatter bf = new BinaryFormatter();                             //Create a BinaryFormatter to convert the binary string to an object
                FileStream fs = new FileStream(filePath, FileMode.Open);                //Create a filestream to create a new file to provide the string
    
                try
                {
                    return bf.Deserialize(fs);                                          //Deserialize the data into an object
                }
                catch (Exception e)                                                     //Catch any errors if they occur
                {
                    Console.WriteLine("Chunk load failed! " + e);
                    return null;
                }
                finally
                {
                    fs.Close();                                                         //Then close the filestream to prevent memory leaks
                }
            }
        }
    }
    

    The key loading and saving parts are here

    public static void SaveChunks(object Chunks, string filePath)
            {
                BinaryFormatter bf = new BinaryFormatter();                             //Create a BinaryFormatter to change the chunks into a binary string
                FileStream fs = new FileStream(filePath, FileMode.Create);              //Create a filestream to create a new file to store the string
    
                try
                {
                    bf.Serialize(fs, Chunks);                                           //Serialize the data into a file
                }
                catch (Exception e)                                                     //if an error occurs Post it!
                {
                    Console.WriteLine("Failed to create Chunk file! " + e);
                }
                finally
                {
                    fs.Close();                                                         //Then close the filestream to prevent memory leaks
                }
            }
    
            public static object LoadChunks(string filePath)
            {
                BinaryFormatter bf = new BinaryFormatter();                             //Create a BinaryFormatter to convert the binary string to an object
                FileStream fs = new FileStream(filePath, FileMode.Open);                //Create a filestream to create a new file to provide the string
    
                try
                {
                    return bf.Deserialize(fs);                                          //Deserialize the data into an object
                }
                catch (Exception e)                                                     //Catch any errors if they occur
                {
                    Console.WriteLine("Chunk load failed! " + e);
                    return null;
                }
                finally
                {
                    fs.Close();                                                         //Then close the filestream to prevent memory leaks
                }
            }
    

    Hope this helps!