Opening the network relevant treasure chest using a timeline?

I have a network relevancy problem where I need to open/close a door slowly using a timeline. I followed the example in the docs involving the treasure chest. In this example though, the treasure chest opens instantly. I’m having difficulty understanding how to do this with something that happens over time (i.e. a timeline), like if the treasure chest opened slowly.

I have a door in my example. Assume there are three clients. Both Client A and B are network relevant to the door, while Client C is not.

  1. Client A calls a Run on Server event to interact with the door.
  2. Client A then immediately begins playing a sound and particle effect (help hide lag).
  3. The server responds by changing the door’s Open state variable to True. This variable is replicated using a rep notify. Finally the server calls a Multicast event to allow clients to play effects.
  4. Both Client A and B receive the Multicast event, since they are both relevant. Client A drops this event, since it already played its effects. Client B plays the sound and particle effect.
  5. At some point during this, both Client A and Client B receive the rep notify that the door’s Open state variable has changed, at which they both trigger a timeline to begin slowly opening the door.

This all works great until Client C shows up sometime later (long after the door has finished opening) and becomes network relevant to the door. Client C correctly does not see or hear the effects, since it never received the Multicast. The issue is that it receives the rep notify, which triggers it to start the timeline to slowly open the door. What needs to happen is that Client C should not see the door opening, but instead the door should be snapped instantly to the opened position.

I’ve experimented with running the timeline in the Multicast event instead and then snapping the door to opened when the rep notify is received. This looks great for Client C, but Client A and B end up skipping the animation. One way I can get around this is with a Delay in the rep notify, but that just seems hacky.

Another idea I had was to use multiple states for the door (i.e. closed, opening, open). However that requires the server to change the state twice, doubling the state replication of the door. The issue is I have many actors that do things over time like this, not just a door, so I’m hoping to avoid unnecessary replication.

Anyone have any other ideas?

Using the multicast to trigger the animation and “ignoring” the OnRep call if the door is already in an “Opening” state is what I would do.
The Opening and Closing state should not be replicated but simply be a local state.

You only need 1 replicated variable and a Multicast Event which should not be a performance concern.

That won’t quite work, because if player C walks in range while the door is opening, they may see the door already open.

To make this 100% reliable, you need to replicate a float that shows how many % the door is open, and, if the door can also be closed, a boolean for whether it’s going in the “opening” or “closing” direction. You also need a local variable for whether you’re currently playing a timeline, and whether you’re playing the timeline in opening-direction or closing-direction.

When you receive OnRep for the % open variable, then if you are not currently playing a timeline, OR if you’re playing it in a different direction than indicated, THEN restart the timeline from the given open/close % position, going in the indicated direction, else if you are currently playing the timeline in the right direction, then just keep playing it – unless the onrep is 100% or 0%, in which case you can optionally snap to the right position, if the timeline is “too far away” from the desired position.

Yes, you need to update the %open while opening – either in tick, or maybe even from the timeline.

Another option is to have a “started opening at time” variable, which uses a consistent game time, to derive what the opening state should be, if you don’t want to send %open variable updates. You’d then have to derive “%open” from “current time minus time-started-opening.” This sends slightly less network traffic while opening, and adds a little bit extra complexity, so your choice on that trade-off.