This is a problem that happens seemingly randomly, perhaps a steam network issue?
My project uses the steam dev appid. Not sure at what engine version this problem became noticeable, but it happens more now than before.
At servertravel one or more players will get stuck. The next level is loaded but not on the server, rather a client-side limbo version with a frozen camera/playercontroller hovering somewhere. If the server host and the others who made the travel succesfully runs around etc, nothing of that is visible for the limbo-clients.
If the server runs servertravels again, the limbo-clients gets traveled to the new level together with everyone else, almost always successfully, so they are still connected to the server…
Im pretty confused about this problem and have not yet had time or ability to investigate it, but I will try to look into it more deeply soon. I dont seem to find anything strange in the logs, no warnings or errors during travel.
Anyone has any suggestions? Experience with anything like this before? Any help is appreciated!
Update: This has been moved to my project’s top priority issue at the moment, after our latest game test session we had huge problems with clients getting stuck in a “decapitated floating” player controller in a limbo version of the level the server loads, clients affected needed to exit the server and reconnect to be able to play.
They still load new maps if the server executes servertravel again, but remain unpossesed and in a new limbo version of loaded level, not loading any other players etc.
This happens between every servertravel and mostly affects the same clients, but sometimes different clients.
This issue is most prominent with more then 3 players on the server. (last game test session we had 8-9 players)
This was never an issue in the past, and I have no idea whats going on…
I’m currently investigating this problem.
Hi! I have currently created a firstperson blueprint template project and set it up for multiplayer using steam, the only difference from the default template is find/join session nodes in a widget.
I will get back with results after I’ve scrambled some game testers and investigated it. I will also compile some different builds and if the template works fine I will try migrating the game to a fresh project, trying to eliminate possibilites.
I’ll get back as soon as I can. Thanks for looking into this issue!
So after some testing today I’ve come up with some results.
The same bug/problem seems to be present even in a fresh firstperson-BP project.
Extra details on the new project: For fast integration with steam I used the steam setup utility (found on the forums) and it does a nice job, allowing steam overlay and online sessions to work quickly in the new test build.
The new project has 2 levels, 1 “menu” level displaying a widget that basicly joins the first found session, and one transision level “transmap”.
Enabled Seamless Travel in game mode.
This time the test was done with 1 client as listen server, and 2 clients connecting to that session.
Randomly clients would get stuck in limbo after server executes servertravel,
The problem occures exactly as it did before. The affected players can be seen in the console log of servertravel command.
I seem to be having the same issue. I have a lobby map, an empty transition map and a gameplay map. Each with game modes with bUseSeamlessTravel = true. When executing the seamless travel, sometimes it works, sometimes it fails. The times it fails it always involves the client getting stuck in a separate version of the map with unmovable camera and no pawns (as OP said, limbo). Interestingly, the client that gets stuck is always done loading way faster than the server who is still loading the new map. I will spend a bit more time to try to make sure its not an error on my end, or perhaps a work around for it. But if that fails I’ll try to reproduce this in a simple project too.
Would it be possible for you to provide the project that you are using when experiencing this issue? This will help insure that we are seeing the same results.
The seamless server travel seems to work fine in this clean project I made. On my end I’ll try to find other causes for the issue in my main project. I’ll get back here if I make any progress.
The clean project that works, is it using steam for multiplayer? steamworks v1.32?
Is it built with source or binary engine?
Have you taken any steps other than those I mentioned in my post when making that build?
Our problem occurs with both the precompiled 4.11.2 and the source built engine (release branch). In our case we’re not using Steam, but your and our symptoms are similar and personally I suspect Steam and source vs. binary don’t make a difference.
I’ve tried my best today to understand the GameMode, PlayerController and World code related to seamless travel. To do that, I’ve compiled the engine from source and added a bunch of logging messages to get an image of what function calls happen in what order, on both host and client.
My understanding is that for the seamless travel to succeed for a client, AGameMode::HandleSeamlessTravelPlayer must be called with the client’s player controller being passed. For remote clients, this relies on the client himself reporting that he is done loading the map via APlayerController::ServerNotifyLoadedWorld.
Now using the logging messages I added and comparing the logs between succesful and failed seamless travels, the key difference seems this: the seamless travel fails when a client calls ServerNotifyLoadedWorld before the server is done loading the map, more specifically before the server has ran AGameMode::PostSeamlessTravel(). Since ServerNotifyLoadedWorld has been ran before the server has finished loading the map, it doesn’t execute HandleSeamlessTravelPlayer.
Now it seems to me that in this case AGameMode::PostSeamlessTravel is supposed to detect this case, this is the only other location in code where HandleSeamlessTravelPlayer is called. In fact it iterates over all player controllers and executes HandleSeamlessTravelPlayer if this check succeeds: PlayerController->HasClientLoadedCurrentWorld().
The problem is that the check fails even for player controllers that have previously already have reported to have loaded the correct world.
ServerNotifyLoadedWorld stores the name of the client-side loaded map and HasClientLoadedCurrentWorld checks this name but what I’m seeing is somewhere between the client initiated RPC ServerNotifyLoadedWorld and PostSeamlessTravel the player controllers are re-instantiated server-side: using only two clients, somewhere along the way PlayerController_0 became PlayerController_2 and PlayerController_1 became PlayerController_3. But with the reinstantiating, the reported map name doesn’t copy over. This makes the server incorrectly think that player is still loading.
Its a long post and I hope I’m onto something. Perhaps this helps your case as well. And maybe can tell me if I’m on the right path.
This sounds like you definitely are onto something. One of the testers reported that the problem seemed to occure when the client loaded the world faster then the server, and looking at the logs I can see that the playercontroller names/ID are incremented every servertravel.
Im curious how you where able to make a clean project without this issue tho.
I managed to fix the issue on my side with a small modification to the engine source. In NetConnection.cpp, line 1814, comment out this line: ClientWorldPackageName = NAME_None;
This prevents the connection’s ClientWorldPackageName from incorrectly being cleared between the remote client’s player controller’s ServerNotifyLoadedWorld execution and the server’s PostSeamlessTravel call execution. Then, AGameMode::PostSeamlessTravel recognizes that the remote client was done loading the map before the server, and at then calls HandleSeamlessTravelPlayer for that client.
I’m not sure about side effects, but I think this is a good solution. Using logging I’ve seen that cases that would previously fail succeed with this change. Let me know if this solves your issue as well!
Looking at the master branch of the UE source, it seems exactly that “ClientWorldPackageName = NAME_None;” has been removed from the function. Seems this bug has already addressed for upcoming releases. Rejoice.
Nice that you got it to work! Interesting that the modification seems to be planned for the next engine release.
I have recompiled the engine source with the modification and will report back with results after doing a game test session with atleast 7-8 testers, it should reveal if the problem is resolved on my end aswell.
Cheers!
Could you respond with the results of your test. If this works for you please let us know so that any other users that are having this issue will be able share in the solution.