Page MenuHomeFeedback Tracker

Select Player not working when selecting old player again
Assigned, NormalPublic

Description

I'm currently working on a spectate mode for my admin tools and I'm running into a problem: I'm creating a temporary player while spectating and when I want to go back to the original char, I cannot move for 10 to 30 seconds and it seems like no input from the client is received by the Server. I attached some code for how to reproduce the problem. This is not how I actually do it, but I included comments for the two steps (start spectate and stop spectate). The interesting thing is, that as long as the player would not leave the network bubble, selecting the original player again is no problem. The problems starts as soon as the original player is deleted on the client (aka leaving the network bubble). When executing the code below, you will not notice a big difference, but when joining with a second client, you will see the player is no longer moving and also the stamina bar is empty and not refilling. When the server or client does some magic resync, everything will work again (the 10 - 30 seconds mentioned above). The stamina bar will be back to normal and the player can move again like before for other players.

I tried hours to find out what this resync could be and I noticed, that player.SetFlags(EntityFlags.SYNCHRONIZATION_DIRTY, true); would help (without it, it would not even sync again at all). I could not find out what is causing it to finally resync to instantly trigger it, so you don't have to wait in this bugged state.

So what do I need: Either fix the problem or at least let me know what I need to do to fix it, because I could not find any RPCs or Events that would be sent

Details

Severity
Block
Resolution
Open
Reproducibility
Always
Operating System
Windows 7
Category
General
Steps To Reproduce
PlayerIdentity sender; // Got through RPC received from the client on the server
PlayerBase player = PlayerBase.Get(sender.GetPlayer());
PlayerBase tempPlayer = PlayerBase.Cast(g_Game.CreatePlayer(sender, player.GetType(), player.GetPosition(), 0, "NONE"));
g_Game.SelectPlayer(sender, tempPlayer);
g_Game.RemoteObjectTreeDelete(player); // Simulates player getting out of the network bubble
// Step 2: Trying to restore the old player
g_Game.RemoteObjectTreeCreate(player);
g_Game.SelectPlayer(sender, player);
g_Game.ObjectDelete(tempPlayer);
player.SetFlags(EntityFlags.SYNCHRONIZATION_DIRTY, true);

Event Timeline

LBmaster created this task.Jan 27 2025, 8:40 AM

Also something I noticed is, that the CommandHandler(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished) method is not called on the server while in this bugged state and as soon as it starts working again, this is called (this is also where the stamina handler is syncing the stamina)

Geez changed the task status from New to Assigned.Jan 27 2025, 2:19 PM

I just checked again and found out, that you don't even have to select another player for that. It's enough to delete the original player from the network bubble and create him again and then select the player again. So basically like this:

g_Game.RemoteObjectTreeDelete(player); // Simulates player getting out of the network bubble
// Step 2: Trying to restore the old player
g_Game.RemoteObjectTreeCreate(player);
g_Game.SelectPlayer(sender, player);
player.SetFlags(EntityFlags.SYNCHRONIZATION_DIRTY, true);
LBmaster added a subscriber: Geez.Tue, Mar 4, 11:02 AM

@Geez I have been playing around with this for hours now and I still cannot wrap my head around it. This must be some kind of desync issue. Here is what I have found

  • I modified the mission server to save the last logged out player and not delete the player when the client logged out. Also in the OnClientReadyEvent I do GetGame().SelectPlayer(identity, oldPlayer) and ignore the player loaded from the DB and the same problem occurs
  • I tried resetting entity flags, entity events, physics, simulation and more things I cannot remember anymore and none of them seem to fix the problem
  • Each time I select the player again I have to wait even longer than I had to wait the previous time. For example after the first time it takes 7 seconds to catch up, then 14 seconds and then 21 seconds. It seems like the sync of the player happens after x seconds after the player is spawned. That would explain why I can immediately select a newly spawned player, but a player, that already existed for a few seconds, takes longer

So what next:

  • Since we already have the option to (partially) interact with the Hive, it would be awesome to have the option to Load a Player from the DB by supplying a GUID or Steamid, so I could just delete the old character from the map and spawn in a new one when needed
  • Somehow be able to reset this timer or whatever is broken when selecting a player a second time

The first option would actually be even better to have, because this would allow admins to inspect player inventories even when not online or allow the creation of mods, which would put players sleeping on the ground like in Rust