question

rocco@done-solo.com avatar image
rocco@done-solo.com asked

GetGameList implementation in Photon/Cloudscript example missing

Hello, 

In the Photon turnbased SDK/Playfab-Integration example, an important piece of the CloudScript code is missing which is the handler for the GetGameList WebRPC.  Provided is only this placeholder in CloudScript/photonEvent.js:

// Placeholder to prevent Photon Error
handlers.GetGameList = function(args)
{
return { "" : "" };
}

Could you kindly share your Cloudscript implementation you used to save (and return) the list of games the player can rejoin when he leaves a room?

-act

10 |1200

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

brendan avatar image
brendan answered

The GetGameList reference is from the Exit Games examples, and you can read more on it here: https://doc.photonengine.com/en/realtime/current/reference/webrpc. Also, one of their team members discussed an implementation in more detail in this thread: https://community.playfab.com/hc/en-us/community/posts/207129407-Persistent-turn-based-games-. In short, it's game-specific, since it's meant to contain all the saved info needed to re-start the game from its current state. We do plan to provide an example of our own, using a sample game, as soon as we can. For now, the recommendation would be to write the info on the game state to User Data (or, preferably, User Read Only Data, so that you can have checks in place to prevent cheating) to write out the same info. For the game list then, you would usually have a "summary" key which lists the essential info and Keys for looking up the details of the individual games.

10 |1200

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

Hamza Lazaar avatar image
Hamza Lazaar answered

Hi @rocco, 

Here is a working link: GetGameList WebRPC.

Data persistence with Photon Cloud can only be done through webhooks first.

---

The question: is can you achieve what you want with what we have?

If you want the short answer I can't give it to you because it's not politically correct.

Long story, making Photon work "well" with PlayFab has become a personal challenge for me. It's no longer about my own WiP game but rather about delivering a working example to people out there. If you want to join me in my journey in CloudScript madness feel free, I'm starting to become paranoid and need a second external point of view. 

 

10 |1200

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

brendan avatar image
brendan answered

And also bear in mind that we're happy to help out with any advice we can give, whether it's on debugging your Cloud Script projects or helping to determine the best path to get past blocking issues.

10 |1200

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

rocco@done-solo.com avatar image
rocco@done-solo.com answered

Thanks to the both of you. I will implement a save/load process along the suggestions. Since the Playfab-side of user data does (currently?) not allow for nested JSON I assume that the choice to store the actual state of a room would be to use JSON.stringify and JSON.deserialize to write/read that value-data on a key via CloudScript.  

Is this the suggested approach for storing arbitrary chunks of nested information into user data?

Thanks again
-act

 

 

10 |1200

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

brendan avatar image
brendan answered

Currently, yes. The right way to manage embedded JSON in your data would indeed be to use parse and toString to serialize/deserialize. We're considering an update to allow for managing embedded JSON more conveniently (so that you could specify a "sub-key" in your data to read or update). If that's something you'd like to see, please feel free to add it to the Feature Requests forum (or vote it up if someone beats you to it).

10 |1200

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

rocco@done-solo.com avatar image
rocco@done-solo.com answered

Thank You Brendan.

10 |1200

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

Hamza Lazaar avatar image
Hamza Lazaar answered

@Brendan,

I know we've talked about this but please can you state clearly what does PlayFab recommend:

Room State should be stored in UserData/UserReadOnlyData and not in a SharedGroup?

Game list should be a SharedGroup or a subset (a single key or keys) from UserData/UserReadOnlyData?

---

@rocco,

I thought I should share few ideas with you (I'm assuming you read previous discussions about this matter):

- PlayFab SharedGroup data keys should not contain '.' character. Maybe this applies to other data containers too (TitleData, UserData, etc.).

- IMO, a single Photon room data saved in PlayFab should contain at least:
{ ActorNr = <x > 1>, CreatorID = <PlayFabId of ActorNr1> } or { ActorNr = 1, DeletionFlag, State = <lighter version of the one sent in GameClose webhook>}.

ActorNr: is used to make a difference between type of game entry: partial game data (>1) or full game data (1).

CreatorID: is pointer or reference to the user space/context of where the full game data (e.g. State) is saved.

DeletionFlag: since a game data is saved in the user space/context of a single player, we should delete it only when we make sure no one will try loading it to sync his client game data / local cache. So if a player (other than creator) no longer needs game data from server he/she should delete its own game entry AND mark/flag full game data for deletion (e.g. DeletionFlag += ActorNr). Then everytime you fetch game list you should check games that need to be deleted (e.g. DeletionFlag == sum(ActorNr) - 1). 

- GetGameList should be optimized for PlayFab: let's say you have the following game list of "PlayerX":

"RoomA": { ActorNr = 2, CreatorID = "PlayerY" }

"RoomB": { ActorNr = 1, DeletionFlag = 1, State = <>}

"RoomC": { ActorNr = 2, CreatorID = "PlayerZ" }

"RoomD": { ActorNr = 1, DeletionFlag = 3, State = <>}

"RoomE": { ActorNr = 1, State = <lighter version of the one sent in GameClose webhook>}

"RoomF": { ActorNr = 2, CreatorID = "PlayerY" }

"RoomG": { ActorNr = 2, CreatorID = "PlayerY" }

When you need to get State of all games, make sure to use as many API calls as different "CreatorIDs" and not as rooms that has "ActorNr == 2", in this case: you should get "RoomA", "RoomF" and "RoomG" at once (single API call) since they should be saved in the same place instead of 3 API calls. So in total you'll need at least 3 API calls to load all room State of the games of "PlayerX". 

10 |1200

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

brendan avatar image
brendan answered

@Hamza

Since the Room State is shared across all the users playing in that room, I would recommend it be stored in Shared Group Data, though to ensure there's no write collisions, the title logic should negotiate which client is doing that write (or write their own pieces to Keys which are named using their PlayFab IDs). And since a client has read/write access to a Shared Group Data when the user is added to it, I would recommend not adding them, and doing the writes via Cloud Script.

For Game Lists, since those are specific to an individual player (the list of all games I'm in), I would store that in User Data or User Read Only Data.

10 |1200

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

Hamza Lazaar avatar image
Hamza Lazaar answered

Thank You Brendan.

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.