LogNetPackageMap:Warning: Using None instead of replicated reference to MyActorClass /Games/Map/MyMap.MyMap:PersistentLevel.MyActor_C because the level it's in has not been made visible

When restarting a level using seamless travel (?Restart) the client machine is spamming out these warnings for a lot of actors in the level.

This warning is preceded by a warning like this:
[2015.02.23-21.18.41:479][329]LogNet:Warning: Received invalid actor class on channel 33

Something is going horribly wrong, and it almost looks as though the net driver is ticking away packets in the background during a seamless load of the level. It’s failing out on all these actors because the level is still loading.

Is this normal? I suspect this is bad… why is the net driver processing net data during a level load… shouldn’t this be processed after the level loads, or will all these actor channels get created again?

This happens when the server tries to tell the client to create an actor, but the client fails to do so. This can happen for several reasons, missing assets, bad package names, etc. Do you have any more info from the logs around the warning you posted above? It might shed more light on why the client is failing.

If these channel open commands were meant for the new level, this would be a problem, and it’s hard to say without getting more info from the logs what might be happening.

It’s technically possible, if the timing was right, for old messages on different channels meant for the old level to cross over into the new level. This would require the server to have fired off a good number of channel open commands, and have all of them arrive before the travel RPC, which is less likely, but technically possible.

Hi John,

Yes I debugged this, it’s happening because of this . The client is still loading the map during seamless travel while the net driver is processing bunches:

// NULL if we haven't finished loading the objects level yet (line 104 of PackageMapClient.cpp)
if ( !ObjectLevelHasFinishedLoading( Object ) )
{
}

I’m doing a restart map using seamless travel. The client has this happen, it only seems to happen in a slower (debug) build.

Hi John, one more comment in case it wasn’t clear before: both client and server have loaded this map already. After the game finished we do GameMode::RestartGame() which does a seamless travel to the same map. The error occurs during the restart/reload process on the client.

Hi John,

I think this is a legitimate bug and I think I have a fix (I will submit on GH in a few hours): What’s happening is that when you restart a map using seamless travel (i.e. travel to the same map) the ClientWorldPackageName of a client players netconnection contains the package name of the destination map already. Adding these lines right after PlayerController->ClientTravel() in AGameMode::ProcessClientTravel() fixes the issue:

PlayerController->NetConnection->FlushNet();
PlayerController->NetConnection->ClientWorldPackageName = NAME_None;

This puts the net driver into a holding state and it doesn’t start creating actor channels (because otherwise it thinks the player has already loaded the map, hence the warnings).

Hi ,

I’m sorry that it’s been a while since we have responded. I’m currently talking to our Networking-team about this issue and we hope to update here soon.

Thanks , this looks legitimate at first glance. We’ll try to look deeper to make sure, but thanks for uncovering this!

It would help us look into this if we had a test project that had this error. Do you still happen to have a project that you can send us?

If so, can you post a link for us to download it here or send it by private message directly to me over the Forums.

Hi Guys,

I have a very large 30+ GB project, but this should be easily reproducible with any map that has many networked actors and a slow client. Seamless travel ?Restart should do it. This is my fix:

if ( Cast<UNetConnection>(PlayerController->Player) != NULL )
{
	// remote player
	PlayerController->ClientTravel(FURL, TRAVEL_Relative, bSeamless, NextMapGuid);
	PlayerController->ServerUpdateLevelVisibility(GetWorld()->GetOutermost()->GetFName(), false);
	PlayerController->NetConnection->FlushNet();
	PlayerController->NetConnection->ClientWorldPackageName = NAME_None;
}

I can submit this as a pull request if that helps.

By the way, which version of the editor are you seeing this issue in?

I did the fix for 4.6.1 in our fork. I’ve carried it forward to 4.7.1, but I’ve never tried to reproduce it in 4.7. Was there some changes that might have solved this? It looks like the code was about the same here.

Not that I know of, I just needed to know the engine version for the report that I’m creating. Which is JIRA UE-12152 by the way.

I’m been having some issues reproducing this in-house. If you have time would you be able to make a small test project that has these errors? If so, I can attach it to the JIRA report and it will help with the investigation.

Let me discuss getting you a build of our game with my partners. I’d need an NDA agreement to do that.

I’m skeptical you could get it to happen in a small test, since it’s timing dependent you’d want a large level so it took a decent amount of time to load on the client. Also running unpackaged it is much more likely to get it to happen (because of how much longer it takes to load).

We can see how far we can get with just the errors in the report. Without a reliable repro case though it may be impossible to track down.

OK well I hope you guys are able to find it, the issue is apparent to me based on code analysis alone and sometimes that’s all you have with timing problems. If the server seamless travels to the same map it’s client state already says the client is on the destination map even before the server starts the travel. So as soon as the server comes up the net drive sends packets.

We actually encountered this same issue, and 's work around worked for us. One of the additional symptoms we found was that UWorld::GameState pointer was NULL after a final transition because when the GameState was spawned on the client, the TransitionMap world was still current, which caused the GameState to be assigned to the TransitionMap world instead of the final destination world.

One thing that helped us reproduce the issue was to simulate lag (setting PktLag).

Thank Clapfoot. I’ve added this info the JIRA report.