I’ve attached an image of what I want. Essentially when we’re applying replicated state I need to know if we’re doing the IsInitState() for the replication. This is integral to a system I’ve built for signals, because I need to report if what people are seeing is an actual change that just occurred, or state that’s being initialized for a first time viewer of the current state. That way things like particle systems/animations etc. know if they need to trigger, or simply appear in their final state.
I’ve attached the patch I had to apply to get the state I wanted - It seems a bit ham-fisted to me, but since the underlying Apply function took the NetSerializationContext, I went with that as the context that needed to continue through the hierarchy. I don’t particularly care if the patch gets used, but the goal is what is important.
Iris KNOWS that we’re applying the initial state but it’s not accessible at the apply stage via the passed in dummy Context. It also knows the owning UObject (a little higher up). Currently that’s not available either. I don’t *currently* need the UObject, but it would be nice in a future update to have more context down in the depths at the apply stage when we’re back on the GT.
At the very least I’d like a future update of Iris to propagate the initial state correctly. It’s weird that some of the other code looks at Traits to know if this is Init, because the Traits are all share const data for descriptor types, something as transient as the Init state shouldn’t be on that in the first place, and belongs on the context as it is in other places.
You are correct, the context should be passed along to the apply method. In fact I found a bug in our code as well that relied on the context to work correctly. I have created a Jira to make sure we pass the context.
I would however be careful when executing gamelogic from Apply as it makes things subject to serialization/apply order of other properties. It is fine if the triggered logic only uses data from the property with the custom apply but could cause unexpected issues if misused.
This actually also applies to the callbacks fired from FastArrays. It is more robust to trigger gamelogic updates from RepNotifies as all properties sent in a batch (actor + subobjects) will be applied when the rep notify fires.
It is also worth noting you might see multiple calls to apply if your member is part of a struct containing objectreferences which gets mapped/resolvable in which case the Context.IsInitState() will not be set for subsequent calls originating from a mapped object reference, so you might need some more information to make this robust a quantized timestamp for example.
I need to think a bit more and discuss with the team if it is a good idea or not to pass down the owner to the apply method as well. We typically want to keep NetSerializers from operating on other data than what is passed as Src and Dst to avoid side-effects as far as possible (apply being a bit of a special case). The long term plan has always been to try handle this at a higher-level (ReplicationState or Fragment).
To clarify a bit on the EReplicationStateTraits::InitOnly trait set on some ReplicationStates it just tells us that the entire ReplicationState only contains members that are InitialOnly and that we do not track them individually in the changemask.
I will update the thread when we have addressed the missing context.
So far we have mostly used them for a few select special cases to solve specific issues related to trying to behave like the legacy replication system and some of them could have been solved through NetSerializer::Apply as well.
I will let you know when we have addressed this on our end, but it will probably look close to what you did so do not worry bout using your solution for the time begin, we will probably pass the entire original context.
Re: Passing the owner. I’m not opposed to handling things at the ReplicationState or Fragment level, I’ve honestly not heavily investigated customizing either. The Fragment bits felt like things I just *had to write* as opposed to a way to heavily extend things. There’s probably some interesting extensions of it in FN i’d imagine, but I don’t recall anything in the engine that really made me stop and go. ohhhhhhhhh i can do ‘this’ with it.