Objects in Streaming Levels not replicated in replay

Hey guys,

When I load a replay for playback I get a stream of warnings saying

SerializeNewActor: Static actor failed to load: FullNetGuidPath: ...
UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: NULL

And I get one of these for basically every object in a streaming level that pinged the replay file for some reason or another. The consequence of this for me is that I can’t see doors opening, for instance.

Now, I’ve tried this as a networked multiplayer game to diagnose whether this is a replication issue or a replay issue. And in my testing I definitely have Server->Client communication (i.e. the client player can see the server player running around opening doors)

So I’m reaching out to see if anyone else has come across this?

Thanks,

Hey ,

Can you give me any information on how I can recreate this issue?

Thanks.

I’ll see if I can cook up a test case, but the bullet points are:

– Persistant Level includes Streaming Levels.
– Streaming levels are loaded on Begin Play of Persistant Level.
– An object in a streaming level is replicated
– A Replay/Demo is recorded in which that sublevel object is moved/actioned/whatever
– Playback the replay/demo and notice a) the warnings and b) the sublevel object not playing back the action.

Hmm… it’s not that simple, it seems.

Hey ,

I created a setup with a persistent level that loads in a streaming level(s) and on begin play of the persistent level, I loaded the steam(ing) levels. In one of the streaming levels I have a replicated Actor.

I demo rec the actor and it is programmed to move around.

Playing the demo recording back shows the movement of the Actor and the interaction it has with the Character. Because of this, I do not think that this is a bug with the Unreal Engine. If you have anymore information regarding this issue or more complete reproduction steps, please post again.

Thanks for looking into it. I’m still working on a repro case. If I can nail it down I’ll post again.

I just repro’d it in a sample project! It looks like it’s a timing issue.

[2016.09.27-18.54.21:357][121]LogAIModule: Creating AISystem for world Dialog
[2016.09.27-18.54.21:368][121]LogWorld: Bringing World /Game/Dialog.Dialog up for play (max tick rate 0) at 2016.09.27-16.24.21
[2016.09.27-18.54.21:368][121]LogWorld: Bringing up level for play took: 0.001096
[2016.09.27-18.54.21:369][121]LogLoadingSplash: Loading ends
[2016.09.27-18.54.21:369][121]LogHMD: FOculusRiftSplash::Hide
[2016.09.27-18.54.21:369][121]LogHMD: FOculusRiftSplash::PushBlackFrame
[2016.09.27-18.54.21:369][121]LogLoad: Took 0.623248 seconds to LoadMap(/Game/Dialog)
[2016.09.27-18.54.21:373][122]LogLevel: ActivateLevel /Game/SubLevels/SubLevel1 1 1 0
[2016.09.27-18.54.21:376][122]LogNetPackageMap:Warning: SerializeNewActor: Static actor failed to load:

But, after having run the map once, things got quicker, and it succeeded on a second attempt:

[2016.09.27-18.57.16:613][906]LogAIModule: Creating AISystem for world Dialog
[2016.09.27-18.57.16:621][906]LogWorld: Bringing World /Game/Dialog.Dialog up for play (max tick rate 0) at 2016.09.27-16.27.16
[2016.09.27-18.57.16:621][906]LogWorld: Bringing up level for play took: 0.000577
[2016.09.27-18.57.16:621][906]LogLoadingSplash: Loading ends
[2016.09.27-18.57.16:621][906]LogHMD: FOculusRiftSplash::Hide
[2016.09.27-18.57.16:621][906]LogHMD: FOculusRiftSplash::PushBlackFrame
[2016.09.27-18.57.16:621][906]LogLoad: Took 0.058061 seconds to LoadMap(/Game/Dialog)
[2016.09.27-18.57.16:622][906]LogLevel: ActivateLevel /Game/SubLevels/SubLevel1 1 1 0
[2016.09.27-18.57.17:046][932]LogLevel: ActivateLevel /Game/SubLevels/SubLevel2 1 1 0

You’ll have to show me how to replicate it.

Thanks.

I filled the world with crap, lol. 4 of my sublevels are copies of the InfinityBlade Forge. And 3 more sublevels with, like, 200 sample-asset benches and chairs each. And one of those chairs I slide across the floor. And to make the engine’s life harder I randomized the materials on the chairs and benches just so it’s gotta crunch through all that texture loading.

Hey,

You kind of went silent there, were you able to repro this?

Hey ,

That isn’t much information to go on. Here is a explanation on how to write up a bug:

https://www.unrealengine.com/support/report-a-bug

Please go through it and fill out, with as much detail, how to setup a project to experience the same issue you are because on my end, I cannot reproduce the issue you are describing.

Thank you,

I still don’t have a reliable reproduction case. But I have narrowed down the problem for me and coded a work-around.

In DemoNetDriver::TickDemoPlayback there’s this block of code:

while ( ConditionallyReadDemoFrameIntoPlaybackPackets( *ReplayStreamer->GetStreamingArchive() ) )
{
}

// Process packets until we are caught up (this implicitly handles fast forward if DemoCurrentTime past many frames)
while ( ConditionallyProcessPlaybackPackets() )
{
	DemoFrameNum++;
}

What was happening for me is that level streaming was being initiated as part of one packet being processed, and then more packets are processed that assumed level loading had already happened. But it hadn’t.

I can’t suggest a general solution, because not everyone will have streaming levels, but for me I limited the frames that could be processed until my first streaming level tried to load. Effectively:

if ( ConditionallyProcessPlaybackPackets() )
{
	DemoFrameNum++;
}

Hey ,

Thanks for submitting your issue. Because of the limited reproduction steps provided, we are unable to move forward with your issue. If at anytime you have more detailed steps to reproduce the issue, please update your post with them and we will continue the investigation into your issue.

Here is a guideline on what makes up a bug as well as how to write up a bug report:

https://www.unrealengine.com/support/report-a-bug

Thanks

Hello,
Same problem here! We are using sublevels and the “Load Level Streaming” function to load them.
When playing back a demo, all I have is a black screen and in the log the same error messages than (UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor…).

If I load just one of the sublevels directly in “Run Standalone” mode, DemoPlay works.
Any updates about that?

Engine version: 4.14.3
Step to reproduce : have a project with a persistent level composed of sublevel. Use a Blueprint as a level manager loading your sublevels “OnBeginPlay” using “LoadLevelStreaming” function.

Update: I found this in the logs when I record the demo, so it seems that the sublevels have a problem already when recording:

LogDemo: Num Network Actors: 47
LogDemo: WriteDemoFrameFromQueuedDemoPackets: StreamingLevel: /Game/MAP/10mn_Demo_Lights, None
LogDemo: WriteDemoFrameFromQueuedDemoPackets: StreamingLevel: /Game/MAP/10mn_Demo_LD_elements, None
LogDemo: StopDemo: Demo Test stopped at frame 1107

I did the same modification but it does not work for me. Would you have any idea about that? I’m not sure to understand the timing issue.
Also, when recording, I’ve got this log where PackageToLoad is None (the level listed here are sublevels):

LogDemo: Num Network Actors: 47

LogDemo: WriteDemoFrameFromQueuedDemoPackets: StreamingLevel: /Game/MAP/10mn_Demo_Lights, None

LogDemo: WriteDemoFrameFromQueuedDemoPackets: StreamingLevel: /Game/MAP/10mn_Demo_LD_elements, None

LogDemo: StopDemo: Demo Test stopped at frame 1107

The ‘solution’ I arrived at above worked on 4.13 but I’m in a similar situation to you right now with 4.14.

[2017.01.10-19.24.25:500][199]LogDemo:
PlayReplay: Attempting to play demo
ID123_B4_S2_0

[2017.01.10-19.24.25:501][199]AVERTLog:Display:
AVERTGameInstance::StartReplayPlayback
ID123_B4_S2_0

[2017.01.10-19.24.25:517][200]LogLoad:
LoadMap: /Game/Maps/Searose_Playable

[2017.01.10-19.24.25:517][200]LogDemo:
StopDemo: Demo ID123_B4_S2_0 stopped
at frame 0

[2017.01.10-19.24.25:518][200]LogNet:
DestroyNamedNetDriver DemoNetDriver_1
[DemoNetDriver]

The result is just a black screen, and, based on the logs, none of my sublevels even tried to load.

I’m still investigating.

I’ve attempted to reproduce the issue but I haven’t been able to see the same behavior on my end. If you’re able to provide a simplified test project that showcases the issue I can take a look and see if I can spot a bug that needs to be entered. Otherwise, unfortunately, we are unable to take any further action on this issue due to the lack of a local repro.

Have a great day

I’m trying to reproduce this on a small project, but until now I did not manage to. It seems to be related to the number of replicating actors present in the Levels… I will try to recreate such a scenario but it may take time and I don’t have much. It would be great to narrow down the bug though so I’ll try.

Sounds good, LNaej.

Let me know what you find.

Okay I did a lot of tests and I’m beginning to think that it comes from a bad understanding of the feature. I managed to have some things working, some other not. I realize that I don’t perfectly understand (and the documentation is not very complete on the subject) the way it works. For instance, when I start the record of a video, the player controller for video playback is intantiated (its begin play is called) where it would be logical to instantiate it only on DemoPlay (and not DemoRec). Also some events triggered during the record are not played back when DemoPlay, and I don’t understand why, as they are networked events.

So I suppose this is due to the lack of understanding about the state of the objects when in DemoPlay mode. For instance I discovered that when playing back a demo, even on the server, the “Switch Has Authority” node return that we don’t have the authority when playing back… Would be great to have a detailed documentation on this kind of stuff.

So is there a bug or not? I’m not so sure anymore, on my side at least. But still need to be investigated.

Edit: about the “HasAuthorithy” thing, I just found this in DemoNetDriver.cpp (InitListen method) explaining the behaviour!

// Recording, local machine is server, demo stream acts "as if" it's a client.
UDemoNetConnection* Connection = NewObject<UDemoNetConnection>();
Connection->InitConnection( this, USOCK_Open, ListenURL, 1000000 );
Connection->InitSendBuffer();
ClientConnections.Add( Connection );

So the comment explains it clearly. Even when server, the DemoNetDriver will act as a Client.