question

squigglyo avatar image
squigglyo asked

CloudScript and Entitiies?

I cant find anything at all that shows how to interact with entities through CloudScript.

At the moment, Im just looking to set up an entity.

I have a function that is called when a new account is created.

Previously, in this function I would use UpdateUserData, give it the currentPlayerId and the Data, and I would have a new user set up.

Im trying to change this to use the entity.SetObjects function but have no idea how to give it the information it wants.

Best I can gather, it needs an Entity and the Objects.

Not sure how to give it an entity or what info that would need.

For the objects, I assume similair to Data in the UpdateUserData, just needs a JSON/Array kind thing.

This is what ive got so far.

The entity bit is definitly wrong, thats the name of the entity, i guess it wants the actual entity.

entity.SetObjects(
  	Entity: "PlayerData",
    Objects: [{
    	"_charStats": {
    		"P1" {
    			"Lv": 0,
    			"Str": 1,
    			"Spd" : 1
    		}
    	}
    }]
  );
1 comment
10 |1200

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

squigglyo avatar image squigglyo commented ·

An entire day spent on this. There are so few resources or questions asked about how to use Entities that any problems or questions are hard to solve. Literally the only resource I can find is the 'getting started' page.

1. How do you create/update entities in Cloud Scripts?

2. How do you update an entity? So far, all I can find is the SetObjects function, but that replaces the entire entity? Does my client need to, at all times, have the entire entity stored/generated and save the entire thing every time? That seems very counter productive compared to the Player Data system and extremely easy to abuse or bug out.

With the 500 byte limit, ive hit it almost immediately with very little actual data.

Ive only got about 50 or so bits of data to save but at this rate, I'll run out of space before I get past the character creation.

I must be missing something because these entities seem like a huge step back from Player Data. I cant store as much data, cant change/update any of it without storing/sending the entire thing, I havent yet found a way to change entities in CloudScript but if the same limitations ive found are there (gotta change the whole thing) that would seem pointless as well.

0 Likes 0 ·
pfnathan avatar image
pfnathan answered

You can only create entities when they are referenced at the moment, so if someone creates a character, that character has an entity. Updating entities is done with SetObjects, and yes, the idea is that you moved from "here's this row-based data storage mechanism" to "every call to get the entity and set the entity affects the entire list of objects within the entity" because we have noticed that most of our users actually don't want just 1 row out of an entity- they want the whole set of objects at once. We will be releasing a beta release soon so, please look for an announcement, but in the meantime, your code has an argument issue.

On this,

 entity.SetObjects(
  Entity: "PlayerData",

it should be;

entity.SetObjects(
  Entity: { Type: "master_player_account", Id: "[USER PLAYFAB ID]"  },

Or

entity.SetObjects(
  Entity: { Type: "title_player_account", Id: "[TITLE PLAYER ACCOUNT ID FROM LOGIN RESULT]"  },

Note: Until the beta release, the best is after login call to include the Entity in the Cloud Script request.

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.

squigglyo avatar image squigglyo commented ·

Thanks.

I can understand the wanting to get all the data at once. The only time I was reading my data was when the game started and I DID want all of it.

But what's the intended flow for updating data?

Do I really need to update the entire set of data if im changing 1 tiny thing?

Not too familiar with networking/sizes/etc but isnt needing to do this every time I save 'expensive', or is this such a small amount of data it doesnt really matter at all that im sending it a few times every minute?

If I wanted have my Cloud Script (since I cant from the client?) handle the changes to the entity (so I dont need to parse/send the entire games data every time I save, how would I go about having a Cloud Script function that changes a single value from the entity?

Or would I need my function to open up the whole entity data, skim through it to find the right thing to change, change it, save the entire entity data- and if so, how would you do that?

Whats wrong here? Its not liking my Entity line, says its missing a ')'

  entity.SetObjects(
    Entity: { Type:"title_player_account", Id: currentPlayerId },
    Objects: {Test1 : "Blah", Test2, 1, Test3, true, Test4: [2,3,4], Test5: {One:1,Two,2}}
 );



0 Likes 0 ·
pfnathan avatar image pfnathan ♦ commented ·

- No, but you do have to update an entire object, but you don't have to update all objects, just the ones that changed.

- No reason to load the profile, just send a request to update the specific object that changed.

As for your code: Type:"title_player_account", Id: currentPlayerId` is wrong, currentPlayerId is the master_player_account entity ID, not title player.

so the code should be;

entity.SetObjects(
{
    Entity: { Type:"title_player_account", Id: currentPlayerId },
    Objects: [{
  ObjectName: "Test1",
  DataObject: "Blah"
 },
 {
  ObjectName: "Test2",
  DataObject: [ 1, 2, 3 ]
 }]
 });

Also, there's no reason to try and check if the value changed either if it didn't change we simply won't update it.

0 Likes 0 ·
squigglyo avatar image
squigglyo answered

So the last thing I need to know is how to change (or if its possible) individual entries in the entity?

If I have an entity called "CurGameData", and it has "_curCoins" and "_charStats" in it.

{"_charStats":"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0","_charCoins":"2;2.036999"}

In Unity, if i try this

var dataList = new List<SetObject>();
Dictionary<string, object> saveData = new Dictionary<string, object>();


saveData.Add("_charCoins", "2;10");
dataList.Add(new SetObject() { ObjectName = "CurGameData", DataObject = saveData});


PlayFabEntityAPI.SetObjects(new SetObjectsRequest()
{
	Entity = entityToken,
        Objects = dataList
}, result => {
	Debug.Log("Saved");
}, error => {
   	Debug.Log("didnt save: " + error.ErrorMessage);
});

It overwrites the data in PlayerData, so I have to save the entire thing every time.

So can I just save the data I want to? Or do I need to send all of the data every time?

And same question for Cloud script. If we are meant to be replacing Player Data with Objects, how can I update things?

So in my game, I might have some bonus event, and the reward can by dynamic, controlled by the Cloud. 'Click this button, gain x coins'.

Previously, I would just have a Cloud script function that gets the _CurCoins value, changes it, puts it back.

How would I accomplish that now with the entity data? Would I have to get the entire json string, pull it apart (how would you do that in cloud script?), change the relevant one, then resave the entire json?

Basically, the thing im missing here is the 'Save this part of the entity data' and all I can find is 'save this as the entire entity data'

So the overall flow here just doesnt seem to translate from Player Data method of altering things to Entity style of altering things :/

What if I don't want ALL of the data?

7 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.

pfnathan avatar image pfnathan ♦ commented ·

You should able to update a single object at a time, which closely resembles updating a key in player data. Please update just _charCoins

0 Likes 0 ·
squigglyo avatar image squigglyo pfnathan ♦ commented ·

How?

The above code would override the entire JSON, erasing all keys except the _charCoins.

Is there a specific way I need to say which object to save?

Do I need to set the ObjectName to something different?

Is there a variable im not setting?

There might be some confusion between what we are talking about, maybe my words mean different things.

Previously in PlayerData, I would have _charCoins and _charStats as seperate keys sitting in Player Data.

I could change either of them individually and easily.

Using Entites, they are both resting in the same data object. I have not yet found a way to change the keys individually that are sitting inside the entity object.

Im trying to get the same functionality I had before where I can update just the _charCoins part of my data and not have to save all other parts (since they arent changing).

Im starting to think that this isnt the intention of entity data.

Not sure how the entity data is any different from a JSON string saved into Player Data though.

0 Likes 0 ·
1807605288 avatar image 1807605288 ♦ squigglyo commented ·

First: Your usage of Player Data is more granular than we expect. Storing a tiny bit of data in many keys is a high cost for us. We always wanted you to store ~1k complex json objects into the Player Data values as well, instead of multiple separate keys. _charCoins is just 4 bytes, but it costs us the same as a 1kb db write. Our cost for that row is literally 250 times what you're using.

Second: You still have multiple entity objects at your disposal.

Third: Ideally PData and EntObjs are the same
https://www.w3schools.com/js/js_json_parse.asp
In fact, for entities, it's even easier, because we automatically do the json parsing for you:
https://api.playfab.com/documentation/Entity/datatype/PlayFab.Entity.Models/PlayFab.Entity.Models.ObjectResult
Result.Objects[i].DataObject will be "DynamicGameData"

As far as updating these as objects, it's a multi-step process, in both cases:

  1. Get the json for the object
  2. call json parse on that json, to get an object with all the properties
  3. modify one of the fields, such as myObj._charStats[3] += 1;
  4. save the whole object back to PlayFab

Entities are even easier, as you only have to get, modify, and save, no json parsing.

0 Likes 0 ·
Show more comments

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.