Replicated variable never set on clients for always relevant actor in level

I have a replication issue that I cannot solve. I have a BP actor on a level, which is replicated, always relevant, and has Net Load on client set to true.

On BeginPlay, I call the following:

Basically on the server I compute and set a replicated & notify variable.

If I run this in PIE with a listen server, the replicated value gets set and the OnRep method associated to this variable is called on both the server and the clients.

However, in a packaged game, after a seamless travel, the variable never gets updated on the clients and OnRep is never called (but it still is on server). This happens when I run two instances of a game in standalone (right click on project file > Launch Game).

If I add a DELAY in there, everything works as expected:

My understanding though is that this replicated & always relevant actor in the level should send its data to clients when they are ready, hence trigger the replication and the OnRep on clients as well, but this is not what’s happening. It looks as if the first replication message from the server is lost on the clients.

Can some kind soul give me a pointer?

Thank you,
r.

PS: Adding or removing the Force Net Update has no effect.
PS2: I do see an error in the server logs, but google does not help and I don’t know whether this is related (also, it happens in a TMP level which I imagine is the transition map?):

[2022.10.15-15.39.16:330][353]LogNetPackageMap: Warning: FNetGUIDCache::SupportsObject: Level /Temp/Untitled_1.Untitled:PersistentLevel NOT Supported.
[2022.10.15-15.39.16:330][353]LogNetPackageMap: Warning: FNetGUIDCache::SupportsObject: Level /Temp/Untitled_1.Untitled:PersistentLevel NOT Supported.
[2022.10.15-15.39.16:392][356]LogNet: Server connection received: ActorChannelFailure [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 192.168.1.56:58856, Name: IpConnection_0, Driver: GameNetDriver IpNetDriver_0, IsServer: YES, PC: MST_PC_Lobby_C_1, Owner: MST_PC_Lobby_C_1, UniqueId: NULL:DESKTOP-P0PSOPM-1BEC658845F4BBCFC437C595C0121D07
[2022.10.15-15.39.16:849][363]LogStats: FPlatformStackWalk::StackWalkAndDump -  0.224 s
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: === Handled ensure: ===
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: 
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: Ensure condition failed: Resource->bProduced || Resource->bExternal || Resource->bQueuedForUpload [File:D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\RenderGraphValidation.cpp] [Line: 580]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: Pass Post Pass: InstanceCull has a read dependency on Nanite.OccludedInstances, but it was never written to.
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: Stack: 
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffa787a743 UnrealEditor-RenderCore.dll!<lambda_99a2a98958c2219bcef246c0b7d4bf00>::operator()() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\RenderGraphValidation.cpp:578]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffa7877e65 UnrealEditor-RenderCore.dll!<lambda_1c67f225222ca53d5338410ea21c0e6b>::operator()() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\RenderGraphValidation.cpp:680]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffa786108b UnrealEditor-RenderCore.dll!FRDGParameterStruct::Enumerate<<lambda_1c67f225222ca53d5338410ea21c0e6b> >() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Public\RenderGraphParameters.inl:15]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffa78cd5f7 UnrealEditor-RenderCore.dll!FRDGUserValidation::ValidateAddPass() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\RenderGraphValidation.cpp:742]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffa782ba1c UnrealEditor-RenderCore.dll!FRDGBuilder::SetupPass() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\RenderGraphBuilder.cpp:1771]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4d786d0b UnrealEditor-Renderer.dll!FComputeShaderUtils::AddPass<FInstanceCull_CS>() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Public\RenderGraphUtils.h:549]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4d7c0d39 UnrealEditor-Renderer.dll!Nanite::AddPass_InstanceHierarchyAndClusterCull() [D:\build\++UE5\Sync\Engine\Source\Runtime\Renderer\Private\Nanite\NaniteCullRaster.cpp:1634]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4d7cf799 UnrealEditor-Renderer.dll!Nanite::CullRasterize() [D:\build\++UE5\Sync\Engine\Source\Runtime\Renderer\Private\Nanite\NaniteCullRaster.cpp:2652]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4d7ce257 UnrealEditor-Renderer.dll!Nanite::CullRasterize() [D:\build\++UE5\Sync\Engine\Source\Runtime\Renderer\Private\Nanite\NaniteCullRaster.cpp:2719]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4d1d7243 UnrealEditor-Renderer.dll!FDeferredShadingSceneRenderer::Render() [D:\build\++UE5\Sync\Engine\Source\Runtime\Renderer\Private\DeferredShadingRenderer.cpp:2441]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4dca1d19 UnrealEditor-Renderer.dll!RenderViewFamily_RenderThread() [D:\build\++UE5\Sync\Engine\Source\Runtime\Renderer\Private\SceneRendering.cpp:4102]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4dc703a2 UnrealEditor-Renderer.dll!<lambda_220f8abc2f1feaab5010e9f914117006>::operator()() [D:\build\++UE5\Sync\Engine\Source\Runtime\Renderer\Private\SceneRendering.cpp:4353]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4dc896ba UnrealEditor-Renderer.dll!TEnqueueUniqueRenderCommandType<`FRendererModule::BeginRenderingViewFamily'::`46'::FDrawSceneCommandName,<lambda_220f8abc2f1feaab5010e9f914117006> >::DoTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Public\RenderingThread.h:193]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff4dc911fa UnrealEditor-Renderer.dll!TGraphTask<TEnqueueUniqueRenderCommandType<`FRendererModule::BeginRenderingViewFamily'::`46'::FDrawSceneCommandName,<lambda_220f8abc2f1feaab5010e9f914117006> > >::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:975]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff710f3a9d UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:753]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff710f3f3e UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksUntilQuit() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:642]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff710f42e1 UnrealEditor-Core.dll!FTaskGraphCompatibilityImplementation::ProcessThreadUntilRequestReturn() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2115]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffa78b976b UnrealEditor-RenderCore.dll!RenderingThreadMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\RenderingThread.cpp:380]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffa78bd158 UnrealEditor-RenderCore.dll!FRenderingThread::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\RenderingThread.cpp:527]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff717c7a2b UnrealEditor-Core.dll!FRunnableThreadWin::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:146]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fff717c0a90 UnrealEditor-Core.dll!FRunnableThreadWin::GuardedRun() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:76]
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffc93d7034 KERNEL32.DLL!UnknownFunction []
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: [Callstack] 0x00007fffcac826a1 ntdll.dll!UnknownFunction []
[2022.10.15-15.39.16:849][363]LogOutputDevice: Error: 
[2022.10.15-15.39.16:849][363]LogStats:                SubmitErrorReport -  0.000 s
[2022.10.15-15.39.17:433][363]LogStats:                    SendNewReport -  0.584 s
[2022.10.15-15.39.17:433][363]LogStats:             FDebug::EnsureFailed -  0.808 s
[2022.10.15-15.39.27:636][578]LogWorld: BeginTearingDown for /Temp/Untitled_1
[2022.10.15-15.39.27:636][578]LogWorld: UWorld::CleanupWorld for Untitled, bSessionEnded=true, bCleanupResources=true
[2022.10.15-15.39.27:636][578]LogSlate: InvalidateAllWidgets triggered.  All widgets were invalidated
[2022.10.15-15.39.27:665][578]LogAudio: Display: Audio Device (ID: 1) registered with world 'EX_Map_01'.
[2022.10.15-15.39.27:677][578]LogAudio: Display: Audio Device unregistered from world 'None'.
[2022.10.15-15.39.27:720][578]LogUObjectHash: Compacting FUObjectHashTables data took   1.66ms
[2022.10.15-15.39.27:723][578]LogSubsystemCollection: Failed to initialize subsystem dependency (WorldPartitionSubsystem)
[2022.10.15-15.39.27:723][578]LogChaos: FPhysicsSolverBase::AsyncDt:-1.000000
[2022.10.15-15.39.27:723][578]LogAIModule: Creating AISystem for world EX_Map_01

I had difficulties with OnRep functions myself. In many cases, I had to call a Rep Notify variable that acts as the notification itself, but create practically the same variable, but marked as replicated and inside the OnRep function populate the information on the replicated variable/variables. Sometimes needs a replication condition, depends on what you’re using it for…

If you populate the Rep Notify variable inside itself, it creates an infinite loop which is obviously bad. But I don’t think it’s notifying the clients if the function doesn’t set the replicated variables inside the Rep Notify.

Is there any logic inside your On Rep function from the Notify?

I’m not sure about the errors. “Level/Temp/Untitled_1:PersistentLevel Not Supported.” looks to be a naming convention error or the level is missing in the packaged build. I don’t think the engine likes anything named “Untitled”. Unless that’s not the case… Looks unrelated, unless its a call on something that isn’t set or unknown to the server.

I believe ActorChannelFailure is logged when a level is unable to accept clients for whatever reason. I see this on the transition level mostly. Client comes in, server says “nope”, ->ActorChannelFailure → closes connection, continues travels to next level accepts connections, life goes on.

I even removed the logic and only print out “REPLICATED!”, just in case.

Also, if I print out the value of the variable in a loop on the clients it simply never gets set. It looks like the server thinks the variable is replicated, but it never is.

The only thing that works is setting the variable after a delay, then yes, the clients do receive the new value and the OnRep gets called.

Could this somewhat be related to clients loading maps before the server or something similar?

Could be… Where is this begin play? On the level?

No, it’s in the actor.

Possibly from the switch has authority? The server isn’t allowing the client to set the variable to replicate the variable to server to clients. Might possibly be “out of scope”?

Im most of my cases, the client would set the rep notify variable on a server event or something of such and the function would populate the replicated variables. When new client came in the server would send the updates.

Possibly from the switch has authority? The server isn’t allowing the client to set the variable to replicate the variable to server to clients. Might possibly be “out of scope”?

Not sure I follow. The switch is there so that it’s the server that sets the value of the variable (replication always work server → client).

I guess what I’m saying is it depends on where the values are being originated… Where and how is “readable date” being set?

On the server. Which sets a replicated variable which should replicate to clients, but it never is.

I’ve also tried setting a boolean value and it just never is replicated.

Maybe try running it on a server event and call it off begin play?

The actor needs to be set to replicated, then take something like the Gamemode which exist only on the server and call functionality that exist for each client in something like the player controller and they will see it. Example: I set the time of day that is within the actor, which is located in a place like the level that everyone sees, and I call that in the Gamemode, which belongs on the server, then the server sends a call to the client (ie. the player controller) which then tells the player to see it. The issue with replication is understanding what is controlled only by the Server or the Client and to understand that the Server must always make the call that everyone sees. The Client can never control the server therefor you have to make all calls that are client driven from an actor and then have that actor tell the server that something has changed. So if you just run the weather on the server everyone will see it. Try removing begin play and putting a custom event that is Run On Server in the Gamemode, Then add another custom event that is set to Multicast within the independent client, like the Player Controller. The Player Controller is what the player sees on his screen, the Character is what that guy is controlling within the level that everyone can see, the Gamemode is the rules for the server, etc. think about it in these terms as you code it, and it helps.

1 Like

Thank you but this has nothing to do with the issue at hand. You can see that because by adding a simple delay node everything works. :slight_smile: I’m familiar with replication, but thanks for taking the time to write about it.

If Delay works, then it is a latency issue.

For anyone bouncing into this: my issue resulted from a misconfiguration in seamless traveling. I don’t know what it was, but rewriting the travel code from scratch made the whole project behave correctly, with no changes to the code posted here above.

a screen shot would have been nice to see what you did,…

When replicating an object one of the most efficient ways to do this is to have an Event Dispatcher in the BP in question, and to add an interface that is called like Interact Interface or something. In project settings create Interaction Input and call that in the player, then when you hit it check the BP you are interacting with to see if they have the interact interface and if they do then cast to the item of that type that you are interacting with, then call the Event Dispatcher on a bind in the character. The Event off the bind should be run on server, then go to a multicast to do any logic. If that logic is like rotation or location then feed it through the Multicast and the Server Events and be sure that you have any of those inputs added to the Event Dispatcher in the BP in question. It will replicate every time like this.