question

kabumere avatar image
kabumere asked

Start off every player with certain Player Data and Statistics

So I have the basic currencies every user starts off with and their starting values. Is there a way to do something similar for player data and statistics?

So the way I'm designing my game, I decided my Inbox object can be created new each startup, and the List of Message objects that each inbox contains can just be set from JSON data I save in each player's player data. However I want to be able to set the initial message or two each player has in their inbox when they first create an account and play the game. Is there a way to have a default value for a specific key in player data?

Likewise, I'll user the player's list of statistics to hold the booleans for the player, like "hasPlayedEndlessMode" and "hasBoughtStarterPack". Is there a way I can create a set of statistics and their default values for new players?

I could solve both of these by initializing them client side at new account creation and then just syncing them with the server later, but I would rather have a server-side solution so I can change the content of either at any time.

Thanks!

Player DataAccount ManagementContent
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.

kabumere avatar image kabumere commented ·

As far as player data, how would you guys recommend me pushing messages to player's on the fly? I know you guys have push notification functionality, but I'd rather use my own messaging system. Since inboxes hold a List<Message> and I want to serialize the list of messages server-side in the player's PlayerData, is there a way I can run a server-side command whenever I want along the lines of:

For every player account, find the value for the key 'MessageList' in PlayerData. This value will be a string in JSON format representing a List of Messages. Append a new message (string) at the end of this list in correct JSON format and save this new string back to the user's PlayerData.

This way I can push out a message to all users, on any platform (mobile, desktop, etc) that they will see whenever they either refresh their in game inbox, or close the game and open it back up.

0 Likes 0 ·
brendan avatar image
brendan answered

Both the things you're describing can be enabled with PlayStream. For setting distinct values on the player the first time he logs into the game (and assuming these values aren't supposed to be the same for all players, in which case you could just use Title Data), you could set an Action (Automation->Rules) which triggers on the event player_added_title. The Action would be to call a Cloud Script that you write which sets the values you need for a first-time player.

For the messaging you describe, you could create a task (Automation->Tasks) that sends the message you want.

However, I do want to make sure you're not literally referring to Player Statistics when you talk about setting statistics for things like "hasBoughtStarterPack" above. Statistics generate leaderboards, so using them for boolean flags would be extremely inefficient. Instead, I would recommend aggregating all those flags into a single User Data (or User Read Only Data, if you need it to be more secure) key/value pair (values under 1,000 bytes aren't very efficient, either).

For more info on PlayStream and Tasks, I'd also recommend reading these posts:

https://playfab.com/introducing-playstream

https://playfab.com/blog/introducing_tasks

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

kabumere avatar image kabumere commented ·

In an answer to my question at https://community.playfab.com/questions/6747/converting-playfab-info-to-player-object.html?

Joshua stated I'd want to move my booleans to statistics. Is there a different type of statistic that doesn't generate leaderboards automatically?

1 Like 1 ·
Joshua Strunk avatar image Joshua Strunk kabumere commented ·

My suggestion was primarily driven around player segmentation, which you might not even need / care about. If you do want segmentation, below is another possible way to segment with boolean values. If you don't just go ahead and store them in user data.

-

After doing another look at PlayStream, segmentation, and the APIs it appears you could use tags.

Server.AddPlayerTag

Server.GetPlayerTags

I was not aware of a tags that could be used for segmentation, when I recommended statistics for your boolean data. Tags are not exposed to the client api. Any of the tags needed on the client would need to be replicated to user data.

0 Likes 0 ·
brendan avatar image brendan Joshua Strunk commented ·

Depending on the specific needs of the game, Statistics could be exactly what you need. But as Joshua says, if the only reason you'd be making them stats is for segmentation, the Tags would be the way to go. And if you don't need segmentation, then collecting them in a Key/Value pair would be the most efficient thing to do.

0 Likes 0 ·
kabumere avatar image kabumere commented ·

Also, when I issue log statements from cloudscripts, are they recorded somewhere permanently? I want to have a running list of server-side logs that I can check whenever about a user. So if a user calls my CloudScript for increasing their coin currency 10 times, I'll have 10 logs about that along the lines of:

Player's coins increased by [amount] due to [reason]

0 Likes 0 ·
brendan avatar image brendan kabumere commented ·

We do not store a log of all transactions for all clients, across all games, long-term. The PlayStream events, by default, are kept for titles for seven days. Some things you can see in the Game Manager, like logins and purchases, are kept long-term, but as data in our service - not log events that you can query. What I would recommend is connecting the PlayStream Event Archive to your own S3 bucket, so that you can collect a full history of all player actions in your game (and then choose your own retention period). We can also provide the configuration files needed to set up a job to automatically pull the S3 records into Redshift, if you're planning on using it for data analysis.

0 Likes 0 ·
kabumere avatar image
kabumere answered

Took a bit of a break for holidays but I'm back, with more questions of course!

So could you point me to a tutorial regarding Tasks and Rules, and the difference between both? Getting back to the inbox system and I have the client side work done. Now I need to find out how server side to set the value for players' messages. Pretty much each player has an Inbox that holds a list of Message objects. Whenever I update currency using cloudscript I also save the Player object serialized to a JSON string under player data. The currencies aren't serialized but their Inbox is.

I want to run something serverside that iterates through all current players, obtains their player data (specifically their Player JSON string) and writes a new message to their message list inside the JSON string. That way next time they load up the game and I create their Player with the JSON string, they have the new message there.

Happy New Year and thanks!

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.

kabumere avatar image kabumere commented ·

Actually just saw your earlier link from last year pointing to the Task info, sorry!

So with what I'm trying to perform, would it be easier to have a cloudscript iterate through every single player in my game, or have a PlayStream segment that just consists of all players to begin with? With the first way, would that run the risk of going over your cap for Cloudscript execution time (assuming there's a fair amount of players to iterate through?) With the second way, would I have to pay to use that PlayStream feature?

Or would you think setting Title Data would be even easier? So upon each startup each player grabs title data and looks for the key 'Messages'. The value for this would be JSON of a List of Messages. Then they can deserialize it client side and add any messages in it that they don't already have to their own inbox. Only issues I see with this are 1, having to add an ID field to my message objects so as to quickly tell which are present in the inbox already, and which aren't. Also with this method, each messagewould have to stay under title data for quite a bit to ensure each user receives it. Whereas cloudscript everyone gets it instantly...

0 Likes 0 ·
brendan avatar image
brendan answered

Well first and foremost, Title Data cannot be used as a place for users to write data. Title Data is a cached and sharded data store, meant to be read by all players - not written to by players. It should only be updated infrequently, by the developer or publisher, using local tools or the Game Manager.

Now, for the player JSON you want to update, I'm trying to determine your actual usage scenario. At first, I thought you wanted to set up each player with some specific data when they first sign into the title, which you can do using the Rule system (on the title added event, call a Cloud Script handler that writes the data you need). But now, you're discussing setting JSON data on a player who already exists in the game. It's possible to update all players in your game with new data via a Task, but bear in mind that Tasks execute over time - so, from when the Task launches, it's going to be a variable amount of time before players A and B both have the update. If this is data that impacts gameplay in any way, it would be far better to have an "OnLogin" handler that is called when the player signs in, which takes care of updating data as needed.

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

kabumere avatar image kabumere commented ·

Players themselves would never write to the title data. I was suggesting that I myself, through GameManager, update the key 'Messages' to have JSON representing a List of Messages. Each user at login would pull Title Data (just read it) and look for the value for Messages. They would then deserialize the JSON into C# List of Message objects. Then for every message in that list that they don't already have in their own inbox, they would add it to their own (which will later be saved under their Player JSON string in their own player data). This way I don't have to iterate through all players in a cloudscript.

The messages I want to push in this fashion won't be super impactful. Just messages like Title: "Gem Sale!", Body: "All gems are 50% off for the next 48 hours! Head to the store to take advantage!", or maybe a message telling users to look forward to a new update coming by the end of the week. Basically the inbox feature is used in-game to record some major events, but I also wanted to use it to communicate with players whenever they next open the app, without using push notifications.

0 Likes 0 ·
brendan avatar image brendan kabumere commented ·

Sure, you could use it that way. Or you could just use our Title News system:

https://api.playfab.com/Documentation/Admin/method/AddNews (also in the Game Manager, in the Content tab)

https://api.playfab.com/Documentation/Client/method/GetTitleNews

0 Likes 0 ·
kabumere avatar image kabumere brendan commented ·

Any major benefit/difference of using Title News as opposed to Title Data for the messages?

0 Likes 0 ·
Show more comments
kabumere avatar image kabumere commented ·

I *do* want to set up each player with specific data when they first sign in to the title, but that's separate from the Inbox feature. I just asked both questions in the same thread as I figured both would be done relatively the same (i.e. some kind of command that runs server side and iterates through all players)

0 Likes 0 ·
brendan avatar image brendan kabumere commented ·

For that, if it's okay for the data to be staged out to users over time, yes, a Task would be best, and you would run it against a Segment (potentially the "all users" segment).

0 Likes 0 ·

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.