// TODO check if data is correct/makes sense
        static public ValheimEngine.Character CharacterReadData(string path)
        {
            // Read header
            var character  = new ValheimEngine.Character();
            var byteAccess = LoadDataFromPath(path);

            if (byteAccess.Length() == 0)
            {
                MessageBox.Show("Could not read file.", "ERROR", MessageBoxButtons.OK);
            }
            character.CharacterVersion = byteAccess.ReadInt32(); // shouldn't be below 30
            character.Kills            = byteAccess.ReadInt32();
            character.Deaths           = byteAccess.ReadInt32();
            character.Crafts           = byteAccess.ReadInt32();
            character.Builds           = byteAccess.ReadInt32();
            var numberOfWorlds = byteAccess.ReadInt32();

            // Read worlds information
            for (var i = 0; i < numberOfWorlds; i++)
            {
                var worldId = byteAccess.ReadInt64();
                var world   = new ValheimEngine.Character.World
                {
                    HasCustomSpawnPoint = byteAccess.ReadBoolean(),
                    SpawnPoint          = byteAccess.ReadVector3(),
                    HasLogoutPoint      = byteAccess.ReadBoolean(),
                    LogoutPoint         = byteAccess.ReadVector3(),
                    HasDeathPoint       = byteAccess.ReadBoolean(),
                    DeathPoint          = byteAccess.ReadVector3(),
                    HomePoint           = byteAccess.ReadVector3(),
                };
                if (byteAccess.ReadBoolean())
                {
                    world.MapData = byteAccess.ReadBytes();
                }

                character.WorldsData.Add(worldId, world);
            }

            // Read main character info
            character.Name      = byteAccess.ReadString();
            character.Id        = byteAccess.ReadInt64();
            character.StartSeed = byteAccess.ReadString();

            // Check if character has more player data
            // Should be false for new characters
            if (!byteAccess.ReadBoolean())
            {
                return(character);
            }

            var dataLength = byteAccess.ReadInt32();

            character.DataVersion = byteAccess.ReadInt32();

            character.MaxHp                 = byteAccess.ReadSingle();
            character.Hp                    = byteAccess.ReadSingle();
            character.Stamina               = byteAccess.ReadSingle();
            character.IsFirstSpawn          = byteAccess.ReadBoolean();
            character.TimeSinceDeath        = byteAccess.ReadSingle();
            character.GuardianPower         = byteAccess.ReadString();
            character.GuardianPowerCooldown = byteAccess.ReadSingle();

            // Read inventory info
            character.Inventory        = new List <ValheimEngine.Character.Item>();
            character.InventoryVersion = byteAccess.ReadInt32();
            var numberOfItems = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfItems; i++)
            {
                var item = new ValheimEngine.Character.Item
                {
                    Name        = byteAccess.ReadString(),
                    Stack       = byteAccess.ReadInt32(),
                    Durability  = byteAccess.ReadSingle(),
                    Pos         = new Tuple <int, int>(byteAccess.ReadInt32(), byteAccess.ReadInt32()),
                    Equipped    = byteAccess.ReadBoolean(),
                    Quality     = byteAccess.ReadInt32(),
                    Variant     = byteAccess.ReadInt32(),
                    CrafterId   = byteAccess.ReadInt64(),
                    CrafterName = byteAccess.ReadString()
                };

                if (item.Name != "")
                {
                    character.Inventory.Add(item);
                }
            }

            // Read character info like recipes, trophies, tutorials, etc
            character.Recipes        = new HashSet <string>();
            character.KnownMaterials = new HashSet <string>();
            character.ShownTutorials = new HashSet <string>();
            character.Uniques        = new HashSet <string>();
            character.Trophies       = new HashSet <string>();
            character.Biomes         = new HashSet <ValheimEngine.Character.Biome>();

            var numberOfRecipes = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfRecipes; i++)
            {
                character.Recipes.Add(byteAccess.ReadString());
            }

            var numberOfStations = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfStations; i++)
            {
                character.Stations.Add(byteAccess.ReadString(), byteAccess.ReadInt32());
            }

            var numberOfKnownMaterials = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfKnownMaterials; i++)
            {
                character.KnownMaterials.Add(byteAccess.ReadString());
            }

            var numberOfShownTutorials = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfShownTutorials; i++)
            {
                character.ShownTutorials.Add(byteAccess.ReadString());
            }

            var numberOfUniques = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfUniques; i++)
            {
                character.Uniques.Add(byteAccess.ReadString());
            }

            var numberOfTrophies = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfTrophies; i++)
            {
                character.Trophies.Add(byteAccess.ReadString());
            }

            var numberOfBiomes = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfBiomes; i++)
            {
                character.Biomes.Add((ValheimEngine.Character.Biome)byteAccess.ReadInt32());
            }

            var numberOfTexts = byteAccess.ReadInt32();

            for (var i = 0; i < numberOfTexts; i++)
            {
                character.Texts.Add(byteAccess.ReadString(), byteAccess.ReadString());
            }

            // Read character appearance
            character.Beard     = byteAccess.ReadString();
            character.Hair      = byteAccess.ReadString();
            character.SkinColor = byteAccess.ReadVector3();
            character.HairColor = byteAccess.ReadVector3();
            character.Gender    = byteAccess.ReadInt32();

            // Read character state like food consumed, skills, etc.
            var numberOfConsumedFood = byteAccess.ReadInt32();

            character.Foods = new List <ValheimEngine.Character.Food>();
            for (var i = 0; i < numberOfConsumedFood; i++)
            {
                var food = new ValheimEngine.Character.Food
                {
                    Name        = byteAccess.ReadString(),
                    HpLeft      = byteAccess.ReadSingle(),
                    StaminaLeft = byteAccess.ReadSingle()
                };
                character.Foods.Add(food);
            }

            character.SkillsVersion = byteAccess.ReadInt32();
            var numberOfSkills = byteAccess.ReadInt32();

            character.Skills = new List <ValheimEngine.Character.Skill>();
            for (var i = 0; i < numberOfSkills; i++)
            {
                var skill = new ValheimEngine.Character.Skill
                {
                    SkillName = (ValheimEngine.Character.SkillName)byteAccess.ReadInt32(),
                    Level     = byteAccess.ReadSingle(),
                    Something = byteAccess.ReadSingle()
                };
                character.Skills.Add(skill);
            }

            return(character);
        }
        static public byte[] CharacterWriteData(ValheimEngine.Character character)
        {
            var byteAccess = new ByteAccess();

            byteAccess.Write(character.CharacterVersion);
            byteAccess.Write(character.Kills);
            byteAccess.Write(character.Deaths);
            byteAccess.Write(character.Crafts);
            byteAccess.Write(character.Builds);
            byteAccess.Write(character.WorldsData.Count);
            foreach (var world in character.WorldsData)
            {
                byteAccess.Write(world.Key);
                byteAccess.Write(world.Value.HasCustomSpawnPoint);
                byteAccess.Write(world.Value.SpawnPoint);
                byteAccess.Write(world.Value.HasLogoutPoint);
                byteAccess.Write(world.Value.LogoutPoint);
                byteAccess.Write(world.Value.HasDeathPoint);
                byteAccess.Write(world.Value.DeathPoint);
                byteAccess.Write(world.Value.HomePoint);
                byteAccess.Write(world.Value.MapData != null);
                if (world.Value.MapData != null)
                {
                    byteAccess.Write(world.Value.MapData);
                }
            }
            byteAccess.Write(character.Name);
            byteAccess.Write(character.Id);
            byteAccess.Write(character.StartSeed);
            byteAccess.Write(character.DataVersion != 0);   // didn't save the check so have to create one

            //player data
            //need to turn data into hex, calculate size and put it before actual data
            var byteAccess2 = new ByteAccess();

            if (character.MaxHp != 0)
            {
                byteAccess2.Write(character.DataVersion);
                byteAccess2.Write(character.MaxHp);
                byteAccess2.Write(character.Hp);
                byteAccess2.Write(character.Stamina);
                byteAccess2.Write(character.IsFirstSpawn);
                byteAccess2.Write(character.TimeSinceDeath);
                byteAccess2.Write(character.GuardianPower);
                byteAccess2.Write(character.GuardianPowerCooldown);
                byteAccess2.Write(character.InventoryVersion);
                byteAccess2.Write(character.Inventory.Count);

                foreach (var item in character.Inventory)
                {
                    byteAccess2.Write(item.Name);
                    byteAccess2.Write(item.Stack);
                    byteAccess2.Write(item.Durability);
                    byteAccess2.Write(item.Pos.Item1);
                    byteAccess2.Write(item.Pos.Item2);
                    byteAccess2.Write(item.Equipped);
                    byteAccess2.Write(item.Quality);
                    byteAccess2.Write(item.Variant);
                    byteAccess2.Write(item.CrafterId);
                    byteAccess2.Write(item.CrafterName);
                }

                byteAccess2.Write(character.Recipes.Count);
                foreach (var recipe in character.Recipes)
                {
                    byteAccess2.Write(recipe);
                }

                byteAccess2.Write(character.Stations.Count);
                foreach (var station in character.Stations)
                {
                    byteAccess2.Write(station.Key);
                    byteAccess2.Write(station.Value);
                }

                byteAccess2.Write(character.KnownMaterials.Count);
                foreach (var material in character.KnownMaterials)
                {
                    byteAccess2.Write(material);
                }

                byteAccess2.Write(character.ShownTutorials.Count);
                foreach (var tutorial in character.ShownTutorials)
                {
                    byteAccess2.Write(tutorial);
                }

                byteAccess2.Write(character.Uniques.Count);
                foreach (var unique in character.Uniques)
                {
                    byteAccess2.Write(unique);
                }

                byteAccess2.Write(character.Trophies.Count);
                foreach (var trophy in character.Trophies)
                {
                    byteAccess2.Write(trophy);
                }

                byteAccess2.Write(character.Biomes.Count);
                foreach (var biome in character.Biomes)
                {
                    byteAccess2.Write((int)biome);
                }

                byteAccess2.Write(character.Texts.Count);
                foreach (var text in character.Texts)
                {
                    byteAccess2.Write(text.Key);
                    byteAccess2.Write(text.Value);
                }

                byteAccess2.Write(character.Beard);
                byteAccess2.Write(character.Hair);
                byteAccess2.Write(character.SkinColor);
                byteAccess2.Write(character.HairColor);
                byteAccess2.Write(character.Gender);
                byteAccess2.Write(character.Foods.Count);
                foreach (var food in character.Foods)
                {
                    byteAccess2.Write(food.Name);
                    byteAccess2.Write(food.HpLeft);
                    byteAccess2.Write(food.StaminaLeft);
                }

                byteAccess2.Write(character.SkillsVersion);
                byteAccess2.Write(character.Skills.Count);
                foreach (var skill in character.Skills)
                {
                    byteAccess2.Write((int)skill.SkillName);
                    byteAccess2.Write(skill.Level);
                    byteAccess2.Write(skill.Something);
                }
            }
            byte[] playerData = byteAccess2.ToArray();

            // order:
            // length of (playerData + data) + data + playerData + length of hash + hash
            byteAccess.Write(playerData.Length);
            byte[] data       = byteAccess.ToArray();
            byte[] final      = data.Concat(playerData).ToArray();
            byte[] length     = BitConverter.GetBytes(final.Length);
            byte[] hashLength = BitConverter.GetBytes(64);          // 512/8
            byte[] hash       = SHA512.Create().ComputeHash(final); // Unused but want to keep it
            byteAccess.Clear();
            byteAccess2.Clear();

            return(length.Concat(final).ToArray().Concat(hashLength).ToArray().Concat(hash).ToArray());
        }