private Creature ConvertGameObject(GameObject creatureObject, int?levelStep)
        {
            if (!Values.V.TryGetSpeciesByClassName(creatureObject.ClassString, out Species species))
            {
                // species is unknown, creature cannot be imported.
                // use name-field to temporarily save the unknown classString to display in a messageBox
                return(new Creature {
                    name = creatureObject.ClassString
                });
            }

            GameObject statusObject = creatureObject.CharacterStatusComponent();

            // error while deserializing that creature
            if (statusObject == null)
            {
                return(null);
            }

            string imprinterName = creatureObject.GetPropertyValue <string>("ImprinterName");
            string owner         = string.IsNullOrWhiteSpace(imprinterName) ? creatureObject.GetPropertyValue <string>("TamerString") : imprinterName;

            int[] wildLevels  = Enumerable.Repeat(-1, Values.STATS_COUNT).ToArray(); // -1 is unknown
            int[] tamedLevels = new int[Values.STATS_COUNT];

            for (int i = 0; i < Values.STATS_COUNT; i++)
            {
                wildLevels[i] = statusObject.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsApplied", i)?.ByteValue ?? 0;
            }
            wildLevels[(int)StatNames.Torpidity] = statusObject.GetPropertyValue <int>("BaseCharacterLevel", defaultValue: 1) - 1; // torpor

            for (int i = 0; i < Values.STATS_COUNT; i++)
            {
                tamedLevels[i] = statusObject.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsAppliedTamed", i)?.ByteValue ?? 0;
            }

            float  ti = statusObject.GetPropertyValue <float>("TamedIneffectivenessModifier", defaultValue: float.NaN);
            double te = 1f / (1 + (!float.IsNaN(ti) ? ti : creatureObject.GetPropertyValue <float>("TameIneffectivenessModifier")));

            var      arkId    = creatureObject.GetDinoId();
            Creature creature = new Creature(species,
                                             creatureObject.GetPropertyValue <string>("TamedName"), owner, creatureObject.GetPropertyValue <string>("TribeName"),
                                             creatureObject.IsFemale() ? Sex.Female : Sex.Male,
                                             wildLevels, tamedLevels, te,
                                             !string.IsNullOrWhiteSpace(creatureObject.GetPropertyValue <string>("ImprinterName")),
                                             statusObject.GetPropertyValue <float>("DinoImprintingQuality"),
                                             levelStep
                                             )
            {
                imprinterName     = creatureObject.GetPropertyValue <string>("ImprinterName"),
                guid              = Utils.ConvertArkIdToGuid(arkId),
                ArkId             = arkId,
                ArkIdImported     = true,
                ArkIdInGame       = Utils.ConvertImportedArkIdToIngameVisualization(arkId),
                domesticatedAt    = DateTime.Now, // TODO: possible to convert ingame-time to realtime?
                addedToLibrary    = DateTime.Now,
                mutationsMaternal = creatureObject.GetPropertyValue <int>("RandomMutationsFemale"),
                mutationsPaternal = creatureObject.GetPropertyValue <int>("RandomMutationsMale"),
                flags             = (creatureObject.GetPropertyValue <bool>("bNeutered") ? CreatureFlags.Neutered : CreatureFlags.None)
                                    | (creatureObject.GetPropertyValue <bool>("MutagenApplied") ? CreatureFlags.MutagenApplied : CreatureFlags.None)
            };

            // If it's a baby and still growing, work out growingUntil
            float babyAge = creatureObject.GetPropertyValue <float>("BabyAge", defaultValue: 1);

            if (babyAge < 1)
            {
                double maturationDuration = species.breeding?.maturationTimeAdjusted ?? 0;
                float  bornSecondsAgo     = (float)maturationDuration * babyAge;
                if (bornSecondsAgo < maturationDuration - 120) // there seems to be a slight offset of one of these saved values, so don't display a creature as being in cooldown if it is about to leave it in the next 2 minutes
                {
                    creature.growingUntil = DateTime.Now.Add(TimeSpan.FromSeconds(maturationDuration - bornSecondsAgo));
                }
            }
            else
            {
                double nextMatingPossible = creatureObject.GetPropertyValue <double>("NextAllowedMatingTime");
                if (_gameTime < nextMatingPossible)
                {
                    creature.cooldownUntil = DateTime.Now.Add(TimeSpan.FromSeconds(nextMatingPossible - _gameTime));
                }
            }

            // Ancestor linking is done later after entire collection is formed - here we just set the guids
            ArkArrayStruct     femaleAncestors = creatureObject.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestors");
            StructPropertyList femaleAncestor  = (StructPropertyList)femaleAncestors?.LastOrDefault();

            if (femaleAncestor != null)
            {
                creature.motherGuid = Utils.ConvertArkIdToGuid(Utils.ConvertArkIdsToLongArkId(
                                                                   femaleAncestor.GetPropertyValue <int>("FemaleDinoID1"),
                                                                   femaleAncestor.GetPropertyValue <int>("FemaleDinoID2")));
                creature.motherName = femaleAncestor.GetPropertyValue <string>("FemaleName");
                creature.isBred     = true;
            }
            ArkArrayStruct     maleAncestors = creatureObject.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestorsMale");
            StructPropertyList maleAncestor  = (StructPropertyList)maleAncestors?.LastOrDefault();

            if (maleAncestor != null)
            {
                creature.fatherGuid = Utils.ConvertArkIdToGuid(GameObjectExtensions.CreateDinoId(
                                                                   maleAncestor.GetPropertyValue <int>("MaleDinoID1"),
                                                                   maleAncestor.GetPropertyValue <int>("MaleDinoID2")));
                creature.fatherName = maleAncestor.GetPropertyValue <string>("MaleName");
                creature.isBred     = true;
            }

            creature.colors = new byte[Species.ColorRegionCount];
            for (int i = 0; i < 6; i++)
            {
                creature.colors[i] = creatureObject.GetPropertyValue <ArkByteValue>("ColorSetIndices", i)?.ByteValue ?? 0;
            }

            bool isDead = creatureObject.GetPropertyValue <bool>("bIsDead");

            if (isDead)
            {
                creature.Status = CreatureStatus.Dead; // dead is always dead
            }

            if (creatureObject.IsCryo)
            {
                creature.Status = CreatureStatus.Cryopod;
            }

            creature.RecalculateCreatureValues(levelStep);

            return(creature);
        }