Cached events
The whole answer can be found below.
Try Our
Documentation
Please check if you can find an answer in our extensive documentation on PUN.
Join Us
on Discord
Meet and talk to our staff and the entire Photon-Community via Discord.
Read More on
Stack Overflow
Find more information on Stack Overflow (for Circle members only).
Cached events
M4TT
2019-12-30 21:26:05
Hello
I'm working with PUN2 and I'm currently implementing cached events.
I managed to make cached events works but there is still questions I can't answer.
Let's say I'm joining a room and I will receive the data from the cached event, is there a way to know when the cached data is finished to being recovered. Is there a distinction possible between the current data that I'm receiving and the data which is stored in the room knowing that both have the same event code ?
What I would like to do is : make someone joins a room, wait until he loads all the stored data on the cache of the room
( perform actions with data ), instantiate him ( he's free now ! ^^ ).
I don't know if I'm verty understandable at this point but my second question is about the size of the cache room and the global cache room, could we know what are their maximum size capacity ?
My last question would be about room cache & global room cache, is this Paint enough accurate to describe their both differences ? https://imgur.com/a/RexdYgZ
Comments
Is there any particular reason why you want to cache events ?
Just because of spawning?
Using cached event I can send events to current user connected on the room and I also save these events for people joining later.
My game is designed in such way that there is a lot of instantiation at a fixed short frequency, RPC can't handle that, this is to much data. Also the current room must be the same on every client, so when someone joins he can instantly receive the current data room.
Failing to use RPC I'm currently using cached events which works great atm
I don't think it's a bad way to achieve what I said above, isn't it ?
Hi @M4TT,
There is no built-in way to make a distinction between live events and cached events.
Cached events will be received first when joining.
Global cached events could be identified using a trick: they have a sender actor number 0.
But this is not enough to identify all cached events.
Did you consider switching some cached events to room/actor properties instead? If possible?
Otherwise:
Not tested but ideas (could be tricky to implement):
1.
You could use an incremental event ID that you save in room property (global index) or actor properties (per actor).
In each event add the ID which is unique per event.
Before or after sending the event update the index in the room property to save the latest live one sent.
This way when joining a room you could compare received events' event ID with the current/latest event
ID saved in the room/actor property.
- Use timestamps per event + join timestamp in actor property of joiner, then compare.
Yo
Did you consider switching some cached events to room/actor properties instead? If possible?
Yes I think it's possible but I can't understand what whould be the goal ?
I managed to understand your first idea, I could try to work on it.
Yes I think it's possible but I can't understand what whould be the goal ?
I think it could be easier to synchronize some parts of the room state using room or actor properties.
Everyone joining the room gets the same up-to-date properties.
I see, I don't think my game logic is in agreement with this method as you asked before
I was wondering how cached events are received.
If player 1 (master client ) and player 2 are storing data on room cache, when player 3 joins will he receive first p1 data necessarily before p2 data
In such case your first idea souldn't works because when p3 will receive p1 data and he will compares the room preperty id with p1 event id and it will be the same at a time, but p2 data is not load at this point ?
I may missed something
Edit: I think cached events are received in the order they are sent, thay's why your first idea should works. Am I right ?
If I'am, I think I should only set the custom room property if I'am the master client but still increase localy the event index on all non master clients in the case where there is a master client switch ( and remove the old master client event id from the room property )
I think cached events are received in the order they are sent, thay's why your first idea should works. Am I right ?
Yes you're right.
The last event ID or event index synchronization is up to you as it depends on how you use cached events.
I finally managed to implement your idea @JohnTube and it works very well
Currently if there are to many cached events, players join rooms and game will freeze a lill ( locally ) because he will receive all cached events at once
Using couroutine to wait and isMessageQueueRunning I solved the issue but it takes a long time to load, and I don't think it's very relevant
I would like to know if you guys have any suggestion? Thanks!
private IEnumerator ReceiveData(EventData _photonEvent)
{
byte eventCode = _photonEvent.Code;
if (eventCode == EVENT_01)
{
PhotonNetwork.IsMessageQueueRunning = false;
yield return new WaitForEndOfFrame();
object[] data = (object[])_photonEvent.CustomData; LoadMapData(data);
PhotonNetwork.IsMessageQueueRunning = true;
yield return new WaitForEndOfFrame();
}
}
public void OnEvent(EventData photonEvent)
{
StartCoroutine(ReceiveData(photonEvent));
}
Hi @M4TT,
Not sure which idea you implemented but great that it works for you and it wasn't that much of a trouble.
About the coroutine, what it does is that in case you get the event with code EVENT_01, you stop processing all incoming Photon messages (Properties update, events, etc.) until the end of frame. You start loading map data just before that.
Not sure this helps you with the issue of receiving too many cached events and not sure if EVENT_01 is live or cached?
Maybe what you need is clean up of some cached events to reduce their number and impact on joining player.
Or we could think of more advanced options.
note:
I would maybe invert these lines so I could give enough time (a frame) for load map data to finish?
yield return new WaitForEndOfFrame();
PhotonNetwork.IsMessageQueueRunning = true;
@JohnTube
I managed to implement your first idea above
( send a locally incremented id in each request & udpate the room property with this id then compares them when we get into the game )
In fact this coroutine delay a lill the time between each EVENT_01 are received and it helps because there are no freezes anymore although the process can be very slow if there are many cached events... And I'm currently facing this issue.
Without this coroutine there are freezes as soon as someone joins the game because every single event are received at once I suppose.
EVENT_01 is cached and none of them should be cleaned. I will try to invert lines as you said.
What do you mean by advanced options ? Have you already encountered this issue ? Thank you.