public MyVoxelPathfindingLog(string filename)
        {
            string path = Path.Combine(MyFileSystem.UserDataPath, filename);

            if (MyFakes.REPLAY_NAVMESH_GENERATION)
            {
                StreamReader logFile = new StreamReader(path);
                string line = null;
                String nmopRegex = "NMOP: Voxel NavMesh: (\\S+) (ADD|REM) \\[X:(\\d+), Y:(\\d+), Z:(\\d+)\\]";
                String voxopRegex = "VOXOP: (\\S*) \\[X:(\\d+), Y:(\\d+), Z:(\\d+)\\] \\[X:(\\d+), Y:(\\d+), Z:(\\d+)\\] (\\S+) (\\S+)";

                while ((line = logFile.ReadLine()) != null)
                {
                    var parts = line.Split('[');
                    var matches = Regex.Matches(line, nmopRegex);
                    if (matches.Count == 1)
                    {
                        string navMeshName = matches[0].Groups[1].Value;
                        if (m_navmeshName == null)
                        {
                            m_navmeshName = navMeshName;
                        }
                        else
                        {
                            Debug.Assert(m_navmeshName == navMeshName, "Pathfinding log contains data from more than one mesh!");
                        }

                        bool addition = matches[0].Groups[2].Value == "ADD";
                        int xCoord = Int32.Parse(matches[0].Groups[3].Value);
                        int yCoord = Int32.Parse(matches[0].Groups[4].Value);
                        int zCoord = Int32.Parse(matches[0].Groups[5].Value);
                        Vector3I coord = new Vector3I(xCoord, yCoord, zCoord);

                        m_operations.Add(new NavMeshOp(m_navmeshName, addition, coord));
                        continue;
                    }

                    matches = Regex.Matches(line, voxopRegex);
                    if (matches.Count == 1)
                    {
                        string voxelMapName = matches[0].Groups[1].Value;

                        int xCoord = Int32.Parse(matches[0].Groups[2].Value);
                        int yCoord = Int32.Parse(matches[0].Groups[3].Value);
                        int zCoord = Int32.Parse(matches[0].Groups[4].Value);
                        Vector3I minCoord = new Vector3I(xCoord, yCoord, zCoord);

                        xCoord = Int32.Parse(matches[0].Groups[5].Value);
                        yCoord = Int32.Parse(matches[0].Groups[6].Value);
                        zCoord = Int32.Parse(matches[0].Groups[7].Value);
                        Vector3I maxCoord = new Vector3I(xCoord, yCoord, zCoord);

                        var flags = (MyStorageDataTypeFlags)Enum.Parse(typeof(MyStorageDataTypeFlags), matches[0].Groups[8].Value);
                        string data = matches[0].Groups[9].Value;

                        m_operations.Add(new VoxelWriteOp(voxelMapName, data, flags, minCoord, maxCoord));
                        continue;
                    }
                }
                logFile.Close();
            }
            if (MyFakes.LOG_NAVMESH_GENERATION)
            {
                m_log = new MyLog();
                m_log.Init(path, MyFinalBuildConstants.APP_VERSION_STRING);
            }
        }