question

thejamiryu avatar image
thejamiryu asked

Having trouble with Entity Objects

Greetings everyone. I'm saving players progress through entity system(ID: 1DC4D). Lately I'm having trouble with it. Some players report that there is progress resets(1 or 2 entity objects won't load).

I have checked twice and none of my entity objects exceed the 1000 byte limit.

This is how I save one of the entity;

public void EntitySave()
    {
        var data = new Dictionary<string, object>()
    {
          {"Po", stats.lichPosition},
          {"Rs", stats.rogueStrenght},
          {"Rd", stats.rogueDexterity},
          {"Rv", stats.hunterVitality},
          {"Rp", stats.hunterPerception},
          {"Rt", stats.rogueMissionTimer},
          {"Rn", stats.rogueMissionNumber},
          {"Rl", stats.rogueLevel},
          {"Re", stats.rogueExperience},
          {"Ra", stats.rogueStatPoint},
          {"Hs", stats.hunterStrenght},
          {"Hd", stats.hunterDexterity},
          {"Hv", stats.hunterVitality},
          {"Hp", stats.hunterPerception},
          {"Ht", stats.hunterMissionTimer},
          {"Hn", stats.hunterMissionNumber},
          {"Hl", stats.hunterLevel},
          {"He", stats.hunterExperience},
          {"Ha", stats.hunterStatPoint}
    };
        var dataList = new List<SetObject>()
    {
          new SetObject()
    {
            ObjectName = "PlayerData",
            DataObject = data
    },


    };
        PlayFabDataAPI.SetObjects(new SetObjectsRequest()
        {
            Entity = new EntityKey { Id = entityId, Type = entityType },
            Objects = dataList,
        }, (setResult) => {
            //Debug.Log(setResult.ProfileVersion);
        }, OnPlayFabError);
    }

And this is how I load it;

public void EntityLoad1()
    {
        var getRequest = new GetObjectsRequest { Entity = new EntityKey { Id = entityId, Type = entityType } };
        PlayFabDataAPI.GetObjects(getRequest,
            result =>
            {
                JsonObject jsonResult = (JsonObject)result.Objects["PlayerData"].DataObject;
                object lichPos;
                if (jsonResult.TryGetValue("Po", out lichPos))
                {
                    stats.lichPosition = Convert.ToInt32(lichPos);
                }
                object rogueStr;
                if (jsonResult.TryGetValue("Rs", out rogueStr))
                {
                    stats.rogueStrenght = Convert.ToInt32(rogueStr);
                }
                object rogueDex;
                if (jsonResult.TryGetValue("Rd", out rogueDex))
                {
                    stats.rogueDexterity = Convert.ToInt32(rogueDex);
                }
                object rogueVit;
                if (jsonResult.TryGetValue("Rv", out rogueVit))
                {
                    stats.rogueVitality = Convert.ToInt32(rogueVit);
                }
                object roguePer;
                if (jsonResult.TryGetValue("Rp", out roguePer))
                {
                    stats.roguePerception = Convert.ToInt32(roguePer);
                }
                object rogueTimer;
                if (jsonResult.TryGetValue("Rt", out rogueTimer))
                {
                    stats.rogueMissionTimer = Convert.ToInt32(rogueTimer);
                }
                object rogueNumb;
                if (jsonResult.TryGetValue("Rn", out rogueNumb))
                {
                    stats.rogueMissionNumber = Convert.ToInt32(rogueNumb);
                }
                object rogueLvl;
                if (jsonResult.TryGetValue("Rl", out rogueLvl))
                {
                    stats.rogueLevel = Convert.ToInt32(rogueLvl);
                }
                object rogueExp;
                if (jsonResult.TryGetValue("Re", out rogueExp))
                {
                    stats.rogueExperience = Convert.ToInt32(rogueExp);
                }
                object rogueStat;
                if (jsonResult.TryGetValue("Ra", out rogueStat))
                {
                    stats.rogueStatPoint = Convert.ToInt32(rogueStat);
                }
                object hunterStr;
                if (jsonResult.TryGetValue("Hs", out hunterStr))
                {
                    stats.hunterStrenght = Convert.ToInt32(hunterStr);
                }
                object hunterDex;
                if (jsonResult.TryGetValue("Hd", out hunterDex))
                {
                    stats.hunterDexterity = Convert.ToInt32(hunterDex);
                }
                object hunterVit;
                if (jsonResult.TryGetValue("Hv", out hunterVit))
                {
                    stats.hunterVitality = Convert.ToInt32(hunterVit);
                }
                object hunterPer;
                if (jsonResult.TryGetValue("Hp", out hunterPer))
                {
                    stats.hunterPerception = Convert.ToInt32(hunterPer);
                }
                object hunterTimer;
                if (jsonResult.TryGetValue("Ht", out hunterTimer))
                {
                    stats.hunterMissionTimer = Convert.ToInt32(hunterTimer);
                }
                object hunterNumb;
                if (jsonResult.TryGetValue("Hn", out hunterNumb))
                {
                    stats.hunterMissionNumber = Convert.ToInt32(hunterNumb);
                }
                object hunterLvl;
                if (jsonResult.TryGetValue("Hl", out hunterLvl))
                {
                    stats.hunterLevel = Convert.ToInt32(hunterLvl);
                }
                object hunterExp;
                if (jsonResult.TryGetValue("He", out hunterExp))
                {
                    stats.hunterExperience = Convert.ToInt32(hunterExp);
                }
                object hunterStat;
                if (jsonResult.TryGetValue("Ha", out hunterStat))
                {
                    stats.hunterStatPoint = Convert.ToInt32(hunterStat);
                }
            },
            OnPlayFabError
        );
    }

I call save and load functions with Coroutine to avoid throttling.

IEnumerator EntityLoadThemAll()
    {
        EntityLoad1();
        yield return new WaitForSeconds(1f);
        EntityLoad2();
        yield return new WaitForSeconds(1f);
        EntityLoad3();
        yield return new WaitForSeconds(1f);
        EntityLoad4();
        yield return new WaitForSeconds(1f);
        EntityLoad5();
    }

Any guidance will be super helpful.

entities
2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Seth Du avatar image Seth Du ♦ commented ·

May I ask how often does this issue occur? Can you located the corresponding PlayStream events? Otherwise, would you share the player ID so that we can dig into it?

0 Likes 0 ·
thejamiryu avatar image thejamiryu Seth Du ♦ commented ·

For example, "89E931FD800CAC52" this user had this issue multiple times. Thank you for help again @SethDu.

0 Likes 0 ·

1 Answer

·
Seth Du avatar image
Seth Du answered

I have been trying to reproduce, but this issue doesn't occur in my testing environment. If this issue doesn't occur on many other players, usually there can be 2 possible reasons:

  • The JSON is not formatted well or some part of data is corrupt. You may enable "Require valid JSON for custom data values" in the Title Setting to ensure the format is consistent.
  • The network issue of this player causes the client cannot get a correct callback result. RESTful API cannot guarantee 100% success and accurate. You will need add extra codes before the data is processed to improve the robustness of the client.

In addition, I don't think it is reasonable to simply reset the save data when 1 or 2 entity objects won't load. If the client progressively save the game, there should be multiple save data so that if the latest data is corrupt, the client can still load the previous one.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.