Only Buffer Last RPC Call

Options
Hi,

I'm curious about the best way to accomplish something within the Photon paradigm. Let's say you have a door (or multiple) in a room. You want the state of this door (closed, open, etc.) to be networked, and you want anyone (i.e. not just the "owner" of the door) to be able to open and close it. Additionally, when a client joins later, you want them to get the correct state of the door. Here are a few different ways on how to accomplish this, and my thoughts on why none of them seem to work well:

- Just use the OnPhotonSerializeView method. This doesn't work, as only the owner will be able to write to this, but there is no conceptual owner of the door, and anyone should be able to change it.
- Use RPC. This works great when everyone is already connected, as any client can simply send an RPC to let all other clients know to change the state of the door. However, this falls apart on late join. There are a few different ways to try to solve this on late join, each having their own problems:
.... - Buffer the RPCs - This seems like a bad idea on many levels. If the room stays open for a decent period of time, and new client will get a bombardment of unnecessary RPC calls, when all they care about is the last one.
.... - Have them ping someone (master client?) on what the correct state of the door is - while this works, this is unnecessary network traffic to the master client when there does not need to be. If users are constantly joining/leaving and switching rooms, the master client is going to be bombarded.
- Have the master client listen for a new client joined, and send them the state of the door(s) - Again, I'm not a fan of relying on any given client to have to send all of the current state for everything.


It seems like the ideal thing here is an RPC with the option of BufferLastCall or something of the sort where any new client only gets the last call of the RPC. I'm using the example of the door as a simple one to illustrate the problem, but I feel like this is a common problem and I'm curious on what the agreed upon way of dealing with this is.

Answers

  • dkonik
    Options
    Just giving this a bump!
  • js101
    Options
    I'm totally new to PUN but am currently struggling with some concepts. To me, it seems like the solution to the door state may be handled with cached events

    https://doc.photonengine.com/en-us/pun/current/gameplay/cached-events

    So on door unlock add it to the room cache, if it gets locked again just remove the old event and add a new "locked" event? So only one event would exist for that door?
  • gevarre
    Options
    Bumping this because there hasn't been any official response yet...

    Do we seriously not have a "BufferLastCall" option? It's such a basic necessity and has been a feature of every networking system I've ever used. It's not like it's a difficult thing to code: clear out any existing buffered calls on this object and add this one. If Photon's code keeps track of this buffer data, it can certainly do such a simple manipulation.

    I've looked at the caching system, and seriously? Are we expected to have to set up all that when it should be handled just by setting one option in the call? I've got an mmo that's about to be announced and I've got a lot of objects that need their states synced. I really don't want to have to go through all the work of having to create a custom system using caches when this can so easily be handled with the correct buffer call.

    Or maybe I'm missing something...

    Devs: I've got objects changing states that are spawned by the player and are only there as long as the player is. I have other objects that are owned by the server and can be controlled by any player (doors, levers, etc). What is the CORRECT way of doing this? I haven't been able to find any decent examples of this, just various guesses and workarounds by people in forums.
  • Hi @gevarre,

    I have other objects that are owned by the server and can be controlled by any player (doors, levers, etc). What is the CORRECT way of doing this?


    You have different possibilities to achieve this, so I'm not sure if there is one 'correct' way. Let's take a door for example. Assuming that this door only have the two states 'opened' and 'closed'. In this case you can store the door's state in the Custom Room Properties for example by using some kind of an unique ID and the state itself. This works well as long as there aren't too many doors. You can basically do the same thing with levers, assuming they only have the two states 'pulled' and 'not pulled'. An extension to this might be, to only store the states of objects, that are not the default state. For example only store the state of opened doors, pulled levers, etc.

    Another way would be using cached RPCs, as you already mentioned. If a client opens a door, you can cache an RPC, if a client closes a door, you can remove that RPC from the cache. There would be a similar approach by using RaiseEvent, too.
  • Dazdingon
    Options
    It is very easy to only buffer the last RPC.
    Simply clear the buffer right before you send another RPC.
    PhotonNetwork.RemoveBufferedRPCs(this.photonView.ViewID, "RPC_Test"); // clear buffer 
    photonView.RPC("RPC_Test", RpcTarget.AllBuffered, myData); // send rpc