ObjectSynchronization vs RPC vs RoomProperties

Hello!

I read the documentation where you explain that ObjectSynchronization is best for things that happen often, RPC for things that happen less often and RoomProperties for things that update rarely. (https://doc.photonengine.com/en-us/pun/v2/gameplay/synchronization-and-state)

It's nice to have a simplified explanation like this, but I would really like to understand WHY this is the case, as I'm trying to decide what to do with RoomProperties. So could you please write (or link me to one) a more detailed explanation as to when and why I should or shouldn't use certain ways of synching the state between the players. For example, is RoomProperties meant to be used for things that happen rarely because it's bad for fast and responsive real time gameplay features, or because if I call it too often it'll flood the whole room and make a bad and laggy experience for everyone.

Thank you in advance!

Comments

  • I am also interested in this! Could someone from Exit Games shed some light on the implementations of mentioned techniques and in why should for example RPC be chosen over room properties (or vice versa) in certain situations?
  • Im not from the Photon team but hopefully i can shed some light on the topic:

    PhotonSerializeView: This is meant as you stated for syncing object states with the sendRate and sendRateOnSerialize values. A main example can be syncing a transform position which of course needs to send and receive data frequently.

    RPC: This is meant for single calls based upon input or state changes. A main example can be shooting a weapon or receiving damage, even sending a chat message can be an example here.

    RoomProperties/CustomProperties: These are meant to store data. Room properties of course store data for the room session for all users to access. CustomProperties can also be applied to players for a similar use. A main example of RoomProperties can be match information such as a match timer value or general pre-made values that don't change too often that all players need to access.

    While RoomProperties are generally meant to be used in my experience for initialization purposes, i have sometimes used them to share gameplay states across all users, such as turn-based games.

    Hopefully this gave some use cases on each method and further clarification. Hopefully a mod can shed some more light on this for you.
  • Helloes!

    Thanks for trying to help, but what I'm actually after is more about WHY these are the intended use cases. Especially in regards to the room custom properties. Our application is such that users can join and leave mid-session, so basically I'm thinking of quite heavily utilizing RoomProperties because of how handy they are for this - I don't need to leave buffered RPC calls waiting for the joining users or anything like that, I can just update session-specific functionality into room properties.

    A concrete example would be that we can highlight a 3d mesh so that other uses will see the highlight effect. Imagine like clicking a file in windows. It stays highlighted until you click elsewhere. What needs to happen is that if I highlight a mesh, then another player joins in, they will immediately see the highlighted mesh. I could do buffered RPCs but it feels weird as the PREVIOUS state of the mesh highlighting is not at all important. The joining user only needs to know the CURRENT state. So sending all the highlight-cancel highlight-hightlight details from an entire one-hour session to new users is a waste of RPCs.

    But what I'm concerned about is whether RoomProperties are somehow very unoptimized and using them for a functionality like this, which MAY happen quite often, will bite me in the butt in the long run. That's why I would need to understand not only their intended use case, but the reason for why that is. Do they get extensively slow if called every half a second? Do they get extensively slow if I have 80 different values stored in there? Just knowing "it's good to use this for things that happen relatively rarely" isn't enough information.
  • RPCs are good, when you "target" a specific networked game object, because that's built-in. PUN sends this sort of meta data with whatever call you do, so it's just there.
    Buffering / caching the RPCs is a way to keep a sequence of actions that happened (before someone joins). The cache may grow into an unwieldy mess (long to load on join), if you are not careful but it's the way to go for actions that rely on sequence (e.g. you load a cannon before it can be fired - which is not a good example, as this is a temporary thing and may not need to be cached)...

    The Custom Properties should also be fine for what you want to do. In terms of networking, highlighting some item is not a frequent action and it neither requires a sequence of actions. The state is enough.
    So, if you would use a key "highlighted" (or "hl" because shorter strings are better) and put in a viewID or some other sort of identifier, then you're fine. This won't grow, this won't be done 10 to 100 times per second either.

    The main reason for Custom Properties being suggested for lower-frequency updates is that PUN has a separate workflow to sync values of objects that need 10 or 20 updates per second. The observed items list of a PhotonView implements a fixed frequency for updates, writing and reading. It should be more convenient for this type of frequent updates.

    Performance wise, you should do a test. Fill the Custom Properties with the amount of content you expect in worst case, run it, check if everything is fine. We have very few fixed limits in Photon, by design. This leaves more room for unexpected use cases (those we didn't have in mind when programming PUN)...

    80 items is not a problem. Try to keep the keys short, that's all.
  • Thanks a lot for your answer! This is exactly the type of a confirmation I was looking for :)
  • jarileon
    jarileon
    edited January 2019
    It wouldn't hurt if these would be also explained in more detail in the docs!
  • spacef
    spacef
    edited January 2021
    I just checked RPC and Custom Properties with Profiler a lot of times for execution of one method:

    For RPC:
    photonView.RPC("ChangeButtonValue", RpcTarget.All, "RPC");
    

    And for custom property:
    PhotonNetwork.CurrentRoom.SetCustomProperties(customProperty);
    

    So,
    • GC allocates less memory for RPC than for CustomProperties ( 0.5KB by CustomProperties and 288B by RPC - it’s a huge difference, 5000B and just 288B )
    • CustomProperties need less time for execution ( 0.03 ms by CustomProperties and 0.06ms by RPC )

    Maybe it will helpful for someone, but anyway I suggest checking with the profiler by yourself for your production methods because I made that only for test reasons.