What is the best way to rebuild a room when a player re-joins a persistent game?

Options
HI there,
I am using PUN + PlayFab to create a persistent, turn-based. game.

Everything is almost working (thanks to the rad support from Photon and PlayFab), but I am unclear about one thing...

What is the best way to rebuild a room from saved data?

Option 1
- Player re-joins room using PhotonNetwork.JoinOrCreateRoom.
- RoomCreated webhook is triggered with type Load
- PlayFab updates room data on Photon using server.getSharedGroupData

Option 2
- Player gets shared data using client.getSharedGroupData
- Player re-joins room using PhotonNetwork.JoinOrCreateRoom sending over the data simultaneously

Questions:
1) Which option is better?
2) For Option 1, how does PlayFab send the new room data to Photon?
3) Is there a third, even better way?

Thanks in advance once again,
Dan

Comments

  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @dt1000,

    Disclaimer:
    You are entering uncharted territory. Continue at your own risk.

    You are missing the most important parts here, without which there is no "Option 1" nor "Option 2":

    1. How to save and load the list of rooms per player on PlayFab?
    2. How to save and load the room state on PlayFab? (I see you are hinting to SharedGroups, are you sure you got it all figured out? I wouldn't be so sure, I advise you to make a PoC asap and ask PlayFab for assistance when needed, especially regarding their limits and restrictions)
    3. Do you use PhotonViews, PunRPC or PhotonNetwork.Instantiate?

    Option 1
    If I understood right, you should use:
    - CreateRoom
    - JoinRoom
    - RejoinRoom
    and not PhotonNetwork.JoinOrCreateRoom.

    Answers:
    1) Which option is better?
    I prefer Option 1 as it's more intuitive and Photon friendly.
    2) For Option 1, how does PlayFab send the new room data to Photon?
    Do you mean loading the room state? The webhook response should contain the saved room state.
    3) Is there a third, even better way?
    I don't think so but every game can have its own solution of persistence.
  • dt1000
    Options
    Thanks for the tips! :smiley:

    1. How to save and load the list of rooms per player on PlayFab?
    2. How to save and load the room state on PlayFab? (I see you are hinting to SharedGroups, are you sure you got it all figured out? I wouldn't be so sure, I advise you to make a PoC asap and ask PlayFab for assistance when needed, especially regarding their limits and restrictions)


    I got 1 & 2 down for the most part, thanks to your awesome CloudScript samples. I hit data limitations as soon as I tried to save the entire room state, so I am using the bare minimum of info from the room's custom properties to rebuild the room's state. Are there any gotchas I should be looking out for, as I have a sneaky suspicion PlayFab has a load of limitations that could require a little cash investment? What is a PoC?

    3. Do you use PhotonViews, PunRPC or PhotonNetwork.Instantiate?


    I am using PlayMaker to connect to Photon... so I think I am using PhotonNetwork.Instantiate.

    Option 1
    If I understood right, you should use:
    - CreateRoom
    - JoinRoom
    - RejoinRoom
    and not PhotonNetwork.JoinOrCreateRoom.


    The reason I'm using PhotonNetwork.JoinOrCreateRoom here is so that the room's basic properties can be recreated from Unity, as they don't ever change (see above info on limitations about saving the entire state). I could do this in CloudScript though... but PhotonNetwork.JoinOrCreateRoom seemsto be working OK at the moment (although it is still early days of testing!) I will see what RejoinRoom does.

    Do you mean loading the room state? The webhook response should contain the saved room state.

    Yes. OK... I had a hard time working that out from your code sample (not really being a coder myself). Thanks for the tip - looking at the examples, this seems to be the line I need...
    return {ResultCode: 0, Message: 'OK', State: data.State};
    Would you be able to point me in the direction of documentation on how to format that Webhook response?

    Thanks once again for your assistance - you have been amazingly helpful thus far!

    Cheers,
    Dan


  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Are there any gotchas I should be looking out for, as I have a sneaky suspicion PlayFab has a load of limitations that could require a little cash investment?
    I recommend you talk to them about your game's needs, the sooner the better.

    What is a PoC?Proof of Concept.

    Would you be able to point me in the direction of documentation on how to format that Webhook response?
    here is the main documentation page for Webhooks, although this is for Photon Realtime product same things apply to PUN with little or no difference, PUN version will be available soon.
  • dt1000
    Options
    OK. Nice. I thought "PoC" was something a little... saltier. :blush:

    Anyways, that documentation link was super helpful - thanks! This section makes me think that Option 2 could be a viable bet...

    In case the state is found, the web server should return a JSON object as { 'State' : state, 'ResultCode' : 0 }. If the state cannot be found for some reason, the web service should check the value of CreateIfNotExists to allow or disallow room creation with new state. If CreateIfNotExists is true, you can return an empty room state (e.g. { 'State' : '', 'ResultCode' : 0 }) to allow creation of a room the options provided by the client. With its value being false Photon Cloud should be informed that the web server failed to load the state by returning a ResultCode other than 0. Consider adding a human readable error message with the cause.


    ...unless it is possible to send partial state data in the webhook response. Do you know if that might work?

    The reason I suggest this is because the size of the state data is larger than PlayFab's free limit...



    ...and there seems to be a lot of extraneous data in there that is not really needed for a game as simple as the one I am working on. So... to keep costs low, it makes sense for us to only save/transmit the bare minimum of data.

    What are your thoughts on this?
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited November 2017
    Options
    Hi @dt1000,

    Do you know if that might work?
    You can return a previously saved state. If you want to use "Option 2" then you should rely only on custom room properties and maybe global cached events. As you will not use rejoin feature and everytime the same user joins the room he will get a new actor number.

    Be careful! A user is not allowed to join a room if he is marked as inactive inside.
    So with "Option 2", you will need to always leave the room for good.
    And if you leave the room for good, you can't save the state (PathClose will be sent with Type = "Close" always) as there is no inactive actor inside.

    So you can initialize a room state only by using RoomOptions passed to JoinOrCreate client method. Currently, you cannot manually construct a room state server side on your own and send it to Photon server. Or you can do it but it's very limited (not tested): maybe few state properties that you can tweak on CloudScript.

    About Shared Group limits (from my head):

    - up to 100 ley/value pairs per a single Shared Group.
    - up to 10 * Shared Group per player.
    - keys do not allow "." character.
    - single value size up to 1000bytes.
    - up to 5 key/value pairs can be updated in a single request (I made a method that updates more in a batch of 5)

    To limit room state size, read this part about "stripping room state".
  • dt1000
    Options
    Ah - very helpful. I will try and strip the room state then!
    I'll let you know how I get on.
    Thanks once again.
    :D
  • dt1000
    Options
    Woooh! I got it working! Thanks for the help! :smiley:

    I took the state, stripped out all the unnecessary stuff, and known parameters I could rebuild programatically (as per that documentation), then extracted the binary and stored it in a separate key.

    This reduced the state data from a single key of about 1900 bytes, to two keys of around 350 bytes each.

    I was then able to reconstruct the state in CloudScript and reJoin the room.

    RESULT! :sunglasses:

  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @dt1000,

    That's great!

    Let us know if you have any feedback (especially about the docs) and keep us updated about your experience with the PlayFab and Photon integration.