public void UpdateData(HollowKnightMemory mem, Action <string> logWriter)
        {
            Process program = mem.Program;

            byte[] playerData = mem.GetPlayerData(DataLength);
            foreach (KeyValuePair <string, PlayerKey> pair in Data)
            {
                PlayerKey key = pair.Value;

                switch (key.Name)
                {
                case "scenesVisited":
                case "scenesMapped":
                case "scenesEncounteredBench":
                case "scenesGrubRescued":
                case "scenesEncounteredCocoon":
                case "scenesEncounteredDreamPlant":
                case "scenesEncounteredDreamPlantC":
                case "playerStory":
                case "MPCharge":
                case "MPReserve":
                case "equippedCharms": continue;
                }

                object oldValue = key.Value;

                switch (key.Type)
                {
                case "Vector3": key.Value = new PointF(BitConverter.ToSingle(playerData, key.Index), BitConverter.ToSingle(playerData, key.Index + 4)); break;

                case "Single": key.Value = BitConverter.ToSingle(playerData, key.Index); break;

                case "Int16": key.Value = BitConverter.ToInt16(playerData, key.Index); break;

                case "Int64": key.Value = BitConverter.ToInt64(playerData, key.Index); break;

                case "String": key.Value = program.Read((IntPtr)BitConverter.ToUInt32(playerData, key.Index)); break;

                case "Completion": key.Value = program.Read <bool>((IntPtr)BitConverter.ToUInt32(playerData, key.Index), 0xa); break;

                case "Byte": key.Value = playerData[key.Index]; break;

                case "Boolean": key.Value = playerData[key.Index] == 1; break;

                default: key.Value = BitConverter.ToInt32(playerData, key.Index); break;
                }

                bool changed = oldValue == null;
                if (!changed)
                {
                    switch (key.Type)
                    {
                    case "Vector3": changed = (PointF)oldValue != (PointF)key.Value; break;

                    case "Single": changed = (float)oldValue != (float)key.Value; break;

                    case "Int16": changed = (short)oldValue != (short)key.Value; break;

                    case "Int64": changed = (long)oldValue != (long)key.Value; break;

                    case "String": changed = (string)oldValue != (string)key.Value; break;

                    case "Completion": changed = (bool)oldValue != (bool)key.Value; break;

                    case "Byte": changed = (byte)oldValue != (byte)key.Value; break;

                    case "Boolean": changed = (bool)oldValue != (bool)key.Value; break;

                    default: changed = (int)oldValue != (int)key.Value; break;
                    }
                }
                if (changed && oldValue != null && logWriter != null)
                {
                    logWriter(key.ToString(oldValue));
                }
            }
        }