Player state not valid after ServerTravel

Hello, I have a problem in a multiplayer game and player state.

Actually I do server travel with seamless travel from a lobby-level to gameplay-level. Often everything works fine, but sometimes on Clients they somehow do not have a valid playerstate. I think same for game state, but let’s focus on player state first.

I do nothing curios in the BP, just check the playerstate in playercontroller. Which is a default replicated variable and normally hold the playerstate of the player.
And even by simply checking for validity (before casting it) I get an error player state is not valid.

I read already that this can happen in first frames after level change. But as you see in my log screenshot, this happens (when the error occur) still after 15 seconds, doing a valid player state check every second.

Any help is greatly welcome.

facts:

  • only happens sometimes (but too often)
  • player state is invalid by just doing a validity-check on default “player state” variable in player controller
  • after servertravel
  • steam as online subsystem
  • occurs mostly not in stand alone game, but when game is published to steam and played in real steam environment

One answer thread I found says:
“In the lobby set the Playerstate to the default one, not the custom one.”
Ist that right that using same player state on server travel (with or without seamless travel) can make problems?
I tried it, but was no solution for me. Same problem occurs.

I found more thread about it, but nothing really as solution.

319703-2020-10-22-18-21-08-window.png

2 Likes

Figured it out by myself. Sadly so few questions get answered nowadays.

I will leave some advises for people with similar problems and investigations. I also got some advises for more in depth analyse in UnrealSlackers I want to spent here.

Set very verbose Log in DefaultEngine.ini

[Core.Log]
LogActor=VeryVerbose
LogNetPackageMap=VeryVerbose

Search in Log for example:

UActorChannel::ReceivedBunch: Received a MustBeMappedGUID that is not registered.
LogNetTraffic: Error: UActorChannel::ProcessBunch: New actor channel received non-open packet

This was not my problem, so I did not have this error messages. Advise is from UnrealSlackers. And this very verbose shows me important things in Logs so I could better analyze what was happen.

With log LogNetPackageMap VeryVerbose yor can see the creation of playerstate in the logs. But as assumed, for server everything is correct, but on client the creation of playerstate after server travel is missing.

In the end it turned out my problem was that I had actors in the level which had higher priority as player state and the server (I still do not know why) stopped simply replicating actors and player state. So player state was not created on client and error occur.

At the moment, for me it is a bug in UE. But its not directly reproducible, also in my case it only happens on some machines and only sometimes on these machines. (Error case in 30-50% of the test runs)
The behavior is not intuitive and makes no sense for me, that Server is stopping replicating to client before all very important actors like controllers, player state, game state, etc… is replicated. In my case, the log in the following screenshots clearly shows that server stopped replicating to client before player state was replicated.
I also do not get the point why UE4 is replicating actors before creating player state. Of course, when priority of other actors is higher at gameplay, these should be replicated before player state. But of course it is very important to create the player state at client side at all.

Investigation was pretty hard, because it not happening an all PCs just on the slower ones. Perhaps some limitation in UE is met. I still do not know, I found nothing about limitation of that kind in UE4 documentation.

What was my solution: Turn down net priority of physics enables actors in my map back to default or at least lower then game state, player state, player controller…

I attach a lot of screen shot with explanation. Perhaps it helps the next one who gets this curios problem. Also in screenshot you see the buggy/random behavior.

Everything fine in most cases. Problem occurred only sometimes. Here is the “fine case” Logfile

Sometimes Server stops replicating, here is the “failure case” Logfile

This settings in actors in the map I had to set back

5 Likes

This problem still exists on UE5.0.2. Is there any better solution? I think this kind of solution is more like magic hahaha.

I think the solution is to override “CopyProperties” event on your PlayerState

There are a couple of factors here, and it’s unfortunate Epic does not make this more reliable out of box. I don’t know if these are all the issues you’re encountering, or some but not others, so here’s my brain dump.

First problem is the most complex one. ServerTravel, unless marked as seamless, means players completely disconnect from the server. From their side it looks like the server died, on the server side it is completely shutting down players and playerstates and rebooting into the next map. When players “realize” the server is back “online” in the new map, they completely rejoin the server as if they’re brand new players. So they go through the whole rejoin and reconnect process. The server will attempt to re-map/restore each of the players and their respective player states that they had previously, but the replication is done completely from scratch as if they had just joined a brand new server host.
Someone above mentioned the “CopyFrom” override, that I believe is what you need to use to restore information in custom overrides of APlayerState. If you were to enable seamless travel, none of that is necessary since players retain their original state instance. Unfortunately, you CANNOT enable “seamless travel” when playing in the Editor. It simply isn’t supported. So for a lobby to gameplay transition, you either never enable seamless travel to support the editor, or you develop and maintain 2 seperate workflows. The timing and issues you may encounter with seamless travel are vastly different from without it enabled. Headaches!

Now, what about the “validity” of the PlayerState? The timing of replication of these properties on structures like PlayerController are not guaranteed in the same order every time players connect. Which is very frustrating. I’ve seen PlayerState ready on BeginPlay, and then on the next run of the game, it’s not ready by BeginPlay. Sometimes it depends on who connects first, if anything is happening in the map (like join in progress in the middle of a match), it can change just based on the performance of your machine or network if its remote. This also occurs if you’re listening for OnPlayerJoin in the GameState, and the PlayerState may be valid but GetPawn may or may not be ready and linked up by the time that function triggers. Even in Unreal Engine’s Lyra sample project, they make note of the issue. If I remember offhand, they wait for the PlayerState to fully replicate and be valid along with the Player Pawn/Character before flagging the player is “ready” and firing event delegates. You have to either copy this or built out your own system so this initialization ordering is guaranteed between loads or even just playing in the editor. Fun!

Third issue you’ve touched upon. You mentioned the priority of PlayerState, that’s probably best to make highest priority. If there are too many other actors with higher priority on load, my guess without looking at the engine code is that it will push those higher priority actors first and maybe the PlayerState gets the short straw. By that I mean it simply doesn’t get pushed down if the other actors are “cutting in line” thanks to priority ordering and throttling. But also, depending on what you do in the PlayerState, you may want to update the frequency of updates. In Lyra, they ramp NetUpdateFrequency. They do it in LyraPlayerState -

	// AbilitySystemComponent needs to be updated at a high frequency.
	NetUpdateFrequency = 100.0f;

Lastly, “Run Under One Process”. This is PIE/play in editor specific. There’s a magical setting in the Play settings that when checked, will load multiple client players and the server under the same Unreal Editor process instance. This is very fast and efficient for iteration when developing. And rapid testing.
However, you’re gambling with this setting enabled because the issues and timings mentioned above will be different than when you play the game standalone. It’s very similar to not having latency, because it’s all locally connecting the players under one process. Speedy, but you lose observability of these mentioned issues. I’ve encountered many issues where logic running in BeginPlay of a player character blueprint would be valid with this option on. But then break and fail when “run under one process” is turned OFF. PlayerState checking is one of them, if not the most common one. To address this, I’ve overridden the OnRep_PlayerState to add a delegate event that Blueprints can listen to if they ever need to talk to playerstate from the Character’s Pawn base class.

Personally I intend to eventually do something similar to Lyra where all of this initialization ordering is handled in lockstep. It’s far too hazardous to leave things to chance between server travel, timing of network update ordering and prioritization under the hood. If someone goes and updates the priority of an actor and that messes with the initialization order of a player connecting and their PlayerState, that’s a big problem as you’ve encountered. I don’t find it acceptable.

2 Likes

should we raise net priority to or just net update frequency to 100?

On 5.3.1. running a dedicated server → client model this problem is still here, but the problem I’m running into isn’t the player state but after 3 rounds against bots on the map change I get spawned in the ground and can’t do anything. After doing some trial and error I found I do have a valid player state but don’t get an pawn:

[412]LogBlueprintUserMessages: [B_Crowbar_LyraGameMode_C_2147474263] Warning: (Nvexx) Register Player Complete > Already On Server (Event BeginPlay)
[412]LogBlueprintUserMessages: [B_Crowbar_LyraGameMode_C_2147474263] Warning: (Nvexx) GameInstance > Get Player State For: LyraPlayerState_2147481379 Is Valid > We have a Player State? > We should be able to play?
[412]LogBlueprintUserMessages: [B_Crowbar_LyraGameMode_C_2147474263] Warning: (Nvexx) GameInstance > Get Controlled Pawn For: B_Crowbar_LyraPlayerController_C_2147481380 Is Not Valid > We Do Not have a Pawn! Ask for Restart Next Frame?

Have been on this issue for several days now, and I can’t really seem to find why this is happening as Lyra calls the GA_AutoRepsawn this does take note of an issue

@TODO: If the death is cancelled too close to the respawn the pawn doesn't init properly?

And this does seem to be my problem but have no direct solution yet

Even running it locally without PlayFab I get a lot of

UActorChannel::ProcessBunch: New actor channel received non-open packet. bOpen: 0, bClose: 0, bReliable: 0, bPartial: 0, bPartialInitial: 0, bPartialFinal: 0, ChName: Actor, ChIndex: 78, Closing: 0, OpenedLocally: 0, OpenAcked: 1, NetGUID: 0

It does seem I can play a few more rounds locally. It’s strange as I haven’t changed much from the Lyra Sample Game package at all and haven’t changed any of its original content.

The problem with the Lyra sample as far as I could see is that they don’t check for a PlayerState but (player)Controller.

Did you find an answer to this? I am also having this issue with lyra 5.3