x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Pawn PlayerState reference on client is sometimes NULL

I have run into some problems with the PlayerState reference inside the Pawn class. PlayerState is sometimes NULL on clients. This happens right after loading up a level with a server and multiple clients. It is still NULL if you keep waiting for many minutes, so it should not be a replication issue. It is also completely random which clients it happens with and on how many.

I have provided an image where I show that the PlayerState reference is NULL on two of the clients. alt text

I have managed to isolate this issue down to the Player Controller function BeginSpectatingState that is called immediately at startup on all clients (I dont know why this function is called). The way I see it, the following is what normally happens:

  • When the level has loaded up and gameplay has started, the server calls Possess and PossessedBy for clients. At this point, the PlayerState reference for Pawns are set to point to the same as the Controller PlayerState. The PlayerState is eventually replicated down to the client. (I have tested that this replication successfully happens).

  • Sometimes however, the BeginSpectatingState function is called after this replication happen. The problem is that this function calls UnPossessed for the Pawn which again sets the PlayerState to NULL on the client.

  • Since this sometimes happens after the PlayerState was replicated from the server, I believe this may be what causes it to be NULL.

This issue only happens sometimes, and only on clients. Most of the time, the PlayerState is ok. I have managed to reproduce this issue in a project based on the Third Person template. Please see my explanation below for the modifications I made:

Reproducable steps:

Using Engine version 4.8.2, I created a project based on the C++ Third Person template, and did the following modifications:

  • Create a C++ function in the custom character class with the below code. Also make sure to add input to the project that calls this function when clicking the left mouse button (or any other button). We will just use this function to check if the PlayerState is NULL.

    void ABugTestProjectCharacter::checkPlayerState() { if (Controller->PlayerState != NULL) { GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, TEXT("Controller->PlayerState is ok")); } else { GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, TEXT("Controller->PlayerState is NULL")); }

       if (PlayerState != NULL)
         {
             GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, TEXT("PlayerState is ok"));
         }
         else
         {
             GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, TEXT("PlayerState is NULL"));
         }
     }
    
    

To test, click the Play button as Standalone Game from inside the editor and test with at least four players (1 listen server and 3 clients). (Testing with more than two players increases the chances for it to happen). I also used the following settings: Uncheck "Use Single Process" and use Editor Multiplayer Mode as "Play As Listen Server".

When clicking the left mouse button on some of the clients, you will hopefully see that on some of them, the PlayerState reference is reported as being NULL. Most of the time however, the PlayerState reference is ok, therefore it is a good idea to test multiple times. Hopefully you will see it as NULL some of the times.

Product Version: UE 4.8
Tags:
image1.png (1.4 MB)
more ▼

asked Jul 16 '15 at 11:39 AM in Bug Reports

avatar image

Gardennnnnnn
46 1 3 7

avatar image Ben Halliday STAFF Jul 16 '15 at 04:16 PM

Hi Gardenn,

I've assigned a member of our team to look into this issue for you, and they'll post here if they require any additional information. Thanks for your report!

avatar image Doug E ♦♦ STAFF Jul 16 '15 at 08:28 PM

Hey Gardenn-

I tried testing this by calling the function on LMB click. With 4 players I only saw PlayerState as NULL once however Controller->PlayerState was NULL as well. After the next frame when I clicked again they were both "ok". This only occurred once out of about 15 tried with four players each time. all other attempts showed all players as ok when I clicked. How often are you seeing the PlayerState as NULL with the Controller->PlayerState being ok and is there anything else that might increase the odds of this occurring?

avatar image Gardennnnnnn Jul 16 '15 at 09:54 PM

Hello

For me, at least every third or fourth time that I test this, the PlayerState is NULL on at least one of the clients. The Controller->PlayerState is always ok.

It is also important to note that for me, when the PlayerState is reported as NULL, it stays permanently NULL. Even if I have the game instance running for several minutes, the PlayerState is still NULL when I click LMB.

At the moment I dont know about anything else that might increase the odds for this occurring.

As I said in my original post I also believe this problem occurs because the BeginSpectatingState function is called for Controller on clients at startup. This function will sometimes call UnPossess which effectively sets the PlayerState to NULL on local clients. I have also tested that, for any of these clients, the servers authorative version of this PlayerState is ok.

I am going to sleep now since I live in norway, but when I wake up tomorrow, I will try to create a project where this happens for me and post it here so that maybe you can take a look at the same project as me. Maybe this will help. I will also see if I can find out anything more about this problem.

Thank you very much for taking a look at this.

avatar image Gardennnnnnn Jul 17 '15 at 11:31 AM

I have created a new project now in engine version 4.8.2, and overriden several functions and added debug messages to the screen inside them to see when and if they are called. I have included the project as an attachment. You will have to rebuild the project after unzipping the file. The following modifications are done (in C++):

  • Inside the BugTestProjectCharacter class, I have done the following:

  • Added the function checkPlayerState. This function is called when clicking LMB.

  • I have overriden the UnPossessed function declared in Pawn.

  • I then added a new class called BugTestProjectPlayerController that extends from PlayerController. Inside this class, I have done the following:

  • I have overriden the BeginSpectatingState function declared in PlayerController.

  • I have overriden the UnPossess function declared in Controller.

  • Finally, I modified BugTestProjectGameMode to use the BugTestProjectPlayerController class as its Player Controller.

To test the project, make sure to do the following: Click Play in editor as "Standalone Game" with the following settings under Advanced Settings -> Multiplayer Options: - Number of players: 4 - Uncheck "Use Single Process" - Editor Multiplayer Mode: "Play as Listen Server"

link text

avatar image Gardennnnnnn Jul 17 '15 at 11:42 AM

I have tested the project multiple times now with four players and can report the following findings:

  • Sometimes, PlayerState is ok on all clients.

  • Most of the time, PlayerState is NULL on either one client or two of the clients.

  • The PlayerState can also be NULL on all three clients (Occurs very rarely).

I also believe I know why the PlayerState is sometimes NULL. At the start of the game, the server will initialize everything, among the PlayerState for all clients. The PlayerState will eventually be replicated down to the client. Also at startup, the BeginSpectatingState function is called on all clients. If GetPawn() is not NULL, this function calls UnPossess which again calls GetPawn()->UnPossessed. This function sets PlayerState to NULL on the client. If this call happens after the PlayerState was replicated down to the client, I believe the client now sets its own PlayerState reference to NULL, which is why the PlayerState is NULL on some of the clients.

This is the screen output I get:

When PlayerState is NULL, I get the following screen output:

  • ABugTestProjectCharacter::UnPossessed

  • ABugTestProjectPlayerController::UnPossess

  • GetPawn() != NULL

  • ABugTestProjectPlayerController::BeginSpectatingState

  • GetPawn() == NULL

  • ABugTestProjectPlayerController::BeginSpectatingState

When PlayerState is ok, I get either this screen output:

  • GetPawn() == NULL

  • ABugTestProjectPlayerController::BeginSpectatingState

or this screen output (Same as the first one):

  • ABugTestProjectCharacter::UnPossessed

  • ABugTestProjectPlayerController::UnPossess

  • GetPawn() != NULL

  • ABugTestProjectPlayerController::BeginSpectatingState

  • GetPawn() == NULL

  • ABugTestProjectPlayerController::BeginSpectatingState

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

3 answers: sort voted first

(this is unfortunately not an answer but the system would not let me post my bug confirmation with more than 2000 characters otherwise)

Hi everyone

We experienced some random editor crashes when testing our multiplayer game with more than 1 player in PIE where PlayerState on a clients locally controlled pawn suddenly was NULL even though it was successfully received in OnRep_PlayerState before.

Turns out that in some cases PlayerState on the APawn can get replicated before SpectatorClass in AGameState gets replicated. In that case, AGameState then calls ReceivedSpectatorClass which then goes on to put all local player controllers into spectator mode. Controllers entering spectator mode will UnPossess the pawn and that in turn sets PlayerState back to NULL.

I have made a tiny test project which implements a custom AGameMode, AGameState and APawn which just logs out when relevant steps are called during initialization. Then during the bad late call to AMyPawn::UnPossessed and during AMyPawn::Tick it prints a message that things are going badly.

It is seems very much a race condition in that it happens very randomly. Sometimes it doesn't happen at all between editor starts and sometimes it happens every second time. Sometimes it happens more often when testing with 4 or more PIE players instead of just 2.

Here is me running the project in PIE 4 times with 2 players. First and fourth time ended up with the client pawn having no PlayerState. I set the log output to just print info from the client (HasAuthority() == false) and only included lines regarding the controlled pawn here.


 [0.00] AMyGameMode::OnConstruction
 [0.00] AMyGameMode::RestartPlayer
 [0.28] AMyGameMode::RestartPlayer
 [0.34] AMyPawn         OnConstruction    - PlayerState: 0x0 - State: Has No Controller
 [0.37] AMyPawn         OnRep_PlayerState - PlayerState: 0x4674e400 - State: Spectating
 [0.37] AMyGameState    OnConstruction
 [0.37] AMyGameState    ReceivedSpectatorClass
 [0.37] AMyPawn         UnPossessed       - PlayerState: 0x4674e400 - State: Spectating
 [0.37] AMyPawn             UnPossessed due to ReceivedSpectatorClass during init after receiving PlayerState will remove PlayerState again
 [0.37] AMyPawn         BeginPlay         - PlayerState: 0x0 - State: Has No Controller
 [0.37] AMyGameState    BeginPlay
 [0.59] AMyPawn         Restart           - PlayerState: 0x0 - State: Spectating
 [0.60] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [0.72] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [0.84] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [0.96] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.08] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.20] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.33] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.45] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.57] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.69] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.82] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.94] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.06] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.19] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.31] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.43] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.56] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.68] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.81] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.94] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [3.07] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [3.07] AMyPawn         EndPlay           - PlayerState: 0x0 - State: Playing
 [3.07] AMyPawn         UnPossessed       - PlayerState: 0x0 - State: Playing
 [3.07] AMyGameState    EndPlay
 [3.07] AMyGameMode::EndPlay

 [0.00] AMyGameMode::OnConstruction
 [0.00] AMyGameMode::RestartPlayer
 [0.24] AMyGameMode::RestartPlayer
 [0.27] AMyPawn         OnConstruction    - PlayerState: 0x0 - State: Has No Controller
 [0.29] AMyGameState    OnConstruction
 [0.29] AMyGameState    ReceivedSpectatorClass
 [0.29] AMyPawn         UnPossessed       - PlayerState: 0x0 - State: Spectating
 [0.29] AMyPawn         BeginPlay         - PlayerState: 0x0 - State: Has No Controller
 [0.29] AMyGameState    BeginPlay
 [0.33] AMyPawn         OnRep_PlayerState - PlayerState: 0x427c4800 - State: Has No Controller
 [0.53] AMyPawn         Restart           - PlayerState: 0x427c4800 - State: Spectating
 [1.12] AMyPawn         EndPlay           - PlayerState: 0x427c4800 - State: Playing
 [1.12] AMyPawn         UnPossessed       - PlayerState: 0x427c4800 - State: Playing
 [1.12] AMyGameState    EndPlay
 [1.13] AMyGameMode::EndPlay

 [0.00] AMyGameMode::OnConstruction
 [0.00] AMyGameMode::RestartPlayer
 [0.23] AMyGameMode::RestartPlayer
 [0.28] AMyPawn         OnConstruction    - PlayerState: 0x0 - State: Has No Controller
 [0.30] AMyGameState    OnConstruction
 [0.30] AMyGameState    ReceivedSpectatorClass
 [0.30] AMyPawn         UnPossessed       - PlayerState: 0x0 - State: Spectating
 [0.30] AMyPawn         BeginPlay         - PlayerState: 0x0 - State: Has No Controller
 [0.30] AMyGameState    BeginPlay
 [0.33] AMyPawn         OnRep_PlayerState - PlayerState: 0x59365600 - State: Has No Controller
 [0.53] AMyPawn         Restart           - PlayerState: 0x59365600 - State: Spectating
 [0.96] AMyPawn         EndPlay           - PlayerState: 0x59365600 - State: Playing
 [0.96] AMyPawn         UnPossessed       - PlayerState: 0x59365600 - State: Playing
 [0.96] AMyGameState    EndPlay
 [0.96] AMyGameMode::EndPlay

 [0.00] AMyGameMode::OnConstruction
 [0.00] AMyGameMode::RestartPlayer
 [0.27] AMyGameMode::RestartPlayer
 [0.32] AMyPawn         OnConstruction    - PlayerState: 0x0 - State: Has No Controller
 [0.34] AMyPawn         OnRep_PlayerState - PlayerState: 0x33dc9600 - State: Spectating
 [0.34] AMyGameState    OnConstruction
 [0.34] AMyGameState    ReceivedSpectatorClass
 [0.34] AMyPawn         UnPossessed       - PlayerState: 0x33dc9600 - State: Spectating
 [0.34] AMyPawn             UnPossessed due to ReceivedSpectatorClass during init after receiving PlayerState will remove PlayerState again
 [0.34] AMyPawn         BeginPlay         - PlayerState: 0x0 - State: Has No Controller
 [0.34] AMyGameState    BeginPlay
 [0.57] AMyPawn         Restart           - PlayerState: 0x0 - State: Spectating
 [0.58] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [0.70] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [0.82] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [0.94] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.06] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.18] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.31] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.43] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.55] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.68] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.80] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [1.92] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.04] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.17] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.29] AMyPawn         Tick on bad pawn! - PlayerState: 0x0 - State: Playing
 [2.29] AMyPawn         EndPlay           - PlayerState: 0x0 - State: Playing
 [2.29] AMyPawn         UnPossessed       - PlayerState: 0x0 - State: Playing
 [2.29] AMyGameState    EndPlay
 [2.30] AMyGameMode::EndPlay

As one can see on the bad first and fourth attempt, AMyPawn gets constructed and then gets OnRep_PlayerState right away even before AMyGameState gets constructed (all happening seemingly on the same tick, same time stamp). On the second and third correct run ReceivedSpectatorClass happens what seems a tick before OnRep_PlayerState.

We confirmed this on two machines with 4.10.2, 4.10.3 and 4.11.0 preview 5.

The test project is attached.

Thanks for looking into this,
Bernhard

playerstatebug.zip (10.6 kB)
more ▼

answered Feb 18 '16 at 03:02 AM

avatar image

bernhard.schelling.opus
26 1 2 4

avatar image Doug E ♦♦ STAFF Feb 18 '16 at 03:20 PM

Hey Bernhard-

Thank you for the detailed information about the pawn/playerstate/game state. I have updated the bug report to include this information as well as the sample project you provided.

Cheers

avatar image sds-michael Feb 19 '16 at 05:12 AM

This might also help, I was able to reproduce this issue much more frequently after a server travel using these network settings: -pktloss=2 -pktlag=75 -pktlagvariance=10 -pktdup=2 -pktorder=1

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

We were seeing this relatively consistently in a test project, and I was able to track down what I believe is the reason for some of the calls not working as expected.

The short version of the "fix" is to test for GetPawn() == nullptr in ReceivedSpectatorClass() before calling BeginSpectatingState(). That way only on the initial connect does it cause a problem. In our case, this fixed the problem. We also had a second potential fix that involved rebuilding the PlayerState pointer inside of the client reset when it acknowledged the pawn. This however still caused the Pawn value to thrash by switching to a spectator pawn and back.

The long version of what was happening, based on my testing, was as follows. Note that our Pawn class was loaded via LoadClass and was not loaded by the GameMode's default values.

  1. Net Player joins

  2. Player pawn class is loaded via GetDefaultPawnClassForController

  3. Player pawn is spawned via SpawnDefaultPawnFor

  4. ClientRestart() is called inside of Server's Possess

  5. ClientRestart() sends a null for NewPawn since PackageMap has not ack'd the pawn class (blueprint class)

  6. ClientRestart() happens on client, sets to NULL pawn, does not enter Playing state since Pawn is null

  7. Controller's Pawn replicates, calls OnRep_Pawn, sets Pawn

  8. Pawn's PlayerState replicates, calls OnRep_PlayerState, sets PlayerState

  9. GameState's SpectatingClass replicates, calls OnRep_SpectatorClass, which calls ReceivedSpectatorClass, which is forwarded to all local player controllers

  10. Since state is Spectating because ClientRestart() failed, and SpectatingPawn is null, it calls BeginSpectatingState()

  11. BeginSpectatingState() sees that Pawn variable is set, calls Unpossess()

  12. Unpossess clears Pawn's PlayerState variable on client

  13. ClientRestart() is called again on a retry with correct Pawn value.

  14. ClientRestart() uses SetPawn rather than possess, which does NOT set PlayerState locally

  15. ClientRestart() AcknowledgesPawn

  16. ClientRestart() changes state to Playing

more ▼

answered Aug 01 '16 at 07:05 PM

avatar image

Chris.Ranney
16 2

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

Hey Gardennnnnnn-

We were able to find the repro for this issue and have submitted a bug report (UE-19058) for investigation.

Cheers

Doug Wilson

more ▼

answered Jul 23 '15 at 02:10 PM

avatar image Wrekk Nov 26 '15 at 02:12 PM

I still have this issue, is it fixed?

avatar image Doug E ♦♦ STAFF Nov 27 '15 at 12:51 PM

Hey Wrekk-

I checked the status of the ticket I had entered, and it is still open. Unfortunately we do not have any estimate for when it will be resolved. However, I have added a comment to the ticket to indicate this is still affecting people.

Cheers

Doug Wilson

avatar image sds-michael Dec 10 '15 at 12:02 AM

Thanks Doug, just FYI we're seeing this exact same issue on our project Space Dust Racers as well, both in 4.8 and 4.10 (after upgrading).

And thanks for filing the detailed bug report Wrekk!

avatar image sds-michael Feb 13 '16 at 03:44 AM

Hi Doug, has there been any progress on UE-19058? We're still seeing it in UE4.10. It'd be great if we could fix it before release!

avatar image Doug E ♦♦ STAFF Feb 16 '16 at 05:14 PM

Hey sds-michael-

UE-19058 has not been resolved yet. If there is any information specific to your case that has not been mentioned here I can add it to the report.

Cheers

Doug Wilson

avatar image sds-michael Feb 16 '16 at 11:46 PM

Thanks Doug. We're seeing it in Development and Shipping builds somewhat infrequently (perhaps 1/100?) when a client joins a server (this happens in separate processes, not a single process through the editor). I've tried testing with different lag simulation settings but it doesn't seem to make a huge difference. Cheers!

avatar image bdavey Sep 12 '16 at 08:13 PM

This issue still seems to be occurring in 4.12.5 and is a real issue for my current project. I'm working on a workaround involving re-launching clients with invalid network setups automatically but this is just trying to work around the issue. This issue was originally posted over a year ago, has no progress been made on it in all that time?

avatar image Doug E ♦♦ STAFF Sep 12 '16 at 08:20 PM

Hey bdavey-

This issue was tested and has not been seen to occur as of 4.13. Please try making a copy of your project and let me know if you still have this occurring on your end in the latest engine version.

avatar image JAC_Improbable May 02 '18 at 09:56 AM

I am still experiencing this issue in 4.19, building off of the 1st Person template.

avatar image CarloMaker Jul 16 '18 at 08:23 AM

Confirm . So do i .

avatar image Caviarail 5 days ago

Confirmed, being in 4.21.0. Pretty reproducable, using the PlayerState right in OnRep_PlayerState() itself. So I decided to handle every PlayerState-related thing on the Server from there on, which works and throwing a log there to remind me that "sometimes" the PlayerState is invalid on the Client.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question