what might prevent a client from properly acknowledging the pawn it has possessed?

In short, I am using the default Third Person Map and example content. Everything is box standard except the NetDriver which is my own variation of the SteamSocket NetDriver from Unreal. All I have done is remove the dependency on OSS Steam in favour of my own “full fat” integration with Steam.

I have effectively duplicated the build in SteamSocket NetDriver including its SockSubsystem, Connection, etc everything in that module where the only difference is my copy is not dependent on OSS Steam instead I work with the Steam Interfaces directly (it was like 3 or 4 lines total changed)

I stress that as I know everything is the same functionally between what I am running and a box standard Third Person example with OSS Steam. However in my test where I have 1 machine open [levelName]?listen and the other machine connects to it via open [serverId] everything connects correctly. The hosting player sees the peer’s pawn, from the pawn camera I can see the host run around nice and smooth … however

On the “client” of the connected peer, all the network synced objects spawn, then the next frame is destroyed, and then the next frame is spawned again over and over.

I have checked all the logs I can think of and have tried stepping through everything I cannot for the life of me figure out why everything initalizes and spawns and replicates as expected then simply destroys everything just to do it all over again.

Clearly, I am missing something with my custom NetDriver but as I stressed above the code is all the same as it is with the out-of-the-box OSS Steam + SteamSocket the only difference being I have my own full fat Steamworks Integration (which yes I know is working perfectly) and thus my SteamNetSocket NetDriver is a variant of the built-in one that in the few lines where OSS Steam is used I simply use the Steam APIs directly

I am assuming my issue is something with configuration … for example here is my Engien.ini

[/Script/Engine.Engine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="SteamworksComplete.NetSocketsNetDriver",DriverClassNameFallback="SteamworksComplete.NetSocketsNetDriver")

[SystemSettings]
net.CurrentHandshakeVersion=2
net.MinHandshakeVersion=2
net.VerifyNetSessionID=0
net.VerifyNetClientID=0

[/Script/SteamworksComplete.NetSocketsNetDriver]
ConnectionTimeout=60.0
InitialConnectTimeout=60.0
NetConnectionClassName="SteamworksComplete.NetSocketsNetConnection"

[Plugins]
EnabledPlugins=SteamworksComplete

Yes I have the timeout set stupid high at the moment that is from some other testing

Any ideas as to what might be causing it the delete and respawn on client only?
I have tried setting up a similar project with OSS Steam + SteamSocket … I have issues getting OSS Steam to work at all so I threw that out long ago as just a frustrating thing that isn’t likely to help me find the issue.
I have an example that uses the default IPNetDriver or whatever it is so I know the example works fine and should work fine with my Steam NetDriver

Also as noted replication does work … as in the host can run around and I can see that update on the client, the issue is wholly that the client is replicating everything, destroying it and doing it again over and over which means the client basically can move as it gets respawned each frame. It’s like the initial connect and spawn process is completing, then starting all over again.

[Edit]
Here is a LogNet VeryVerbose incase it helps

LogNet: Verbose: PlayerController_1 setplayer LocalPlayer_1
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetHUD Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientVoiceHandshakeComplete Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientEnableNetworkVoice Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientCapBandwidth Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientRestart Local
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerCheckClientPossessionReliable
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetViewTarget Local
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerVerifyViewTarget
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetRotation Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerShortTimeout
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 177
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_Pawn Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerSetSpectatorLocation
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 213
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientRetryClientRestart Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetViewTarget Local
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerVerifyViewTarget
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_Pawn Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_GameModeClass Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_SpectatorClass Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedHasBegunPlay Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedWorldTimeSecondsDouble Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 356
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnInputOwnerEndPlayed Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnInputOwnerEndPlayed Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedMovement Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedBasedMovement Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: PhysicsVolumeChanged Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 508
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedWorldTimeSecondsDouble Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerId Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_UniqueId Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerName Local
LogNet: Verbose: PlayerController_2 setplayer LocalPlayer_1
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_Pawn Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_Owner Local

So the above is just 1 loop of it, the first in particular

the
LogNet: Verbose: PlayerController_1 setplayer LocalPlayer_1
is the first time everything is spawned in correctly so what should happen next is the finalization of that inial spawn and then the regular play of the game

The Received packet from 765561198036455492:-1 with size 213 looks a bit odd to me in that the vPort is -1, I would expect the vPort to always be 0 but I see other cases of a -1 so ignoring that and moving down the list of actions taken after setplayer

I see ClientRetryClientRestart Local getting called, then what looks like maybe it deletes the old objects and spawns new ones … but why did it do that I cannot figure that part out

A bit more logging

So this is from the perspective of a client connection. I can see messages that suggest the issue is around “acknowledging” the pawn I am just unsure how that process happens and what about my NetDriver or related configuration could/would mess with that

Log segment, this is a snippet between the Welcome message and the first 2 setplayer calls so is at least 1 full iteration of the loop

LogNet: Verbose: PendingLevel received: Welcome
LogNet: Welcomed by server (Level: /Game/ThirdPerson/Maps/ThirdPersonMap, Game: /Script/CkeanTest_5_3.CkeanTest_5_3GameMode)
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 9
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogLoad: LoadMap: steam.76561198036455492/Game/ThirdPerson/Maps/ThirdPersonMap?game=/Script/CkeanTest_5_3.CkeanTest_5_3GameMode
LogWorld: BeginTearingDown for /Game/UEDPIE_0_ExampleLevel
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientReceiveLocalizedMessage Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnInputOwnerEndPlayed Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnInputOwnerEndPlayed Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnInputOwnerEndPlayed Local
LogWorld: UWorld::CleanupWorld for ExampleLevel, bSessionEnded=true, bCleanupResources=true
LogSlate: InvalidateAllWidgets triggered.  All widgets were invalidated
LogAudio: Display: Audio Device unregistered from world 'None'.
LogUObjectHash: Compacting FUObjectHashTables data took   0.62ms
LogAudio: Display: Audio Device (ID: 4) registered with world 'ThirdPersonMap'.
LogWorldSubsystemInput: UEnhancedInputDeveloperSettings::bEnableWorldSubsystem is false, the world subsystem will not be created!
LogChaos: FPhysicsSolverBase::AsyncDt:-1.000000
LogWorldPartition: ULevel::OnLevelLoaded(ThirdPersonMap)(bIsOwningWorldGameWorld=1, bIsOwningWorldPartitioned=1, InitializeForMainWorld=1, InitializeForEditor=0, InitializeForGame=1)
LogWorldPartition: Display: WorldPartition initialize started...
LogWorldPartition: UWorldPartition::Initialize : World = ThirdPersonMap, World Type = PIE, IsMainWorldPartition = 1, Location = V(0), Rotation = R(0), IsEditor = 0, IsGame = 0, IsPIEWorldTravel = 1, IsCooking = 0
LogWorldPartition: UWorldPartition::Initialize Context : World NetMode = Client, IsServer = 0, IsDedicatedServer = 0, IsServerStreamingEnabled = 0, IsServerStreamingOutEnabled = 0, IsUsingMakingVisibleTransaction = 0, IsUsingMakingInvisibleTransaction = 0
LogWorldPartition: Display: GenerateStreaming for 'ThirdPersonMap' started...
LogWorldPartition: Display: GenerateStreaming for 'ThirdPersonMap' took 29 ms (total: 117 ms)
LogContentBundle: [ThirdPersonMap(Client 0)] Creating new contrainer.
LogWorldPartition: Display: WorldPartition initialize took 31 ms (total: 127 ms)
LogPlayLevel: PIE: World Init took: (0.033046s)
LogWorld: Bringing World /Game/ThirdPerson/Maps/ThirdPersonMap.ThirdPersonMap up for play (max tick rate 0) at 2024.02.05-03.31.47
LogWorld: Bringing up level for play took: 0.001790
LogLoad: Took 0.103182 seconds to LoadMap(/Game/ThirdPerson/Maps/ThirdPersonMap)
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 10
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 10
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: GetFunctionCallspace Client local function: ServerShortTimeout Local
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 10
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 333
LogPlayerController: Verbose: NULL GameState when trying to spawn spectator!
LogNet: Verbose: PlayerController_1 setplayer LocalPlayer_2
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetHUD Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientVoiceHandshakeComplete Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientEnableNetworkVoice Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientCapBandwidth Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientRestart Local
LogPlayerController: Verbose: ClientRestart_Implementation None
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerCheckClientPossessionReliable
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetViewTarget Local
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerVerifyViewTarget
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetRotation Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerShortTimeout
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 467
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_Pawn Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_GameModeClass Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_SpectatorClass Local
LogPlayerController: Verbose: Spawned spectator SpectatorPawn_0 [server:0]
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedHasBegunPlay Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedWorldTimeSecondsDouble Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 160
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerSetSpectatorLocation
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 413
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientRetryClientRestart Local
LogNet: VeryVerbose: GetFunctionCallspace Client calling Client function: ClientSetViewTarget Local
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerVerifyViewTarget
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerId Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_UniqueId Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerName Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedMovement Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerState Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_ReplicatedBasedMovement Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: PhysicsVolumeChanged Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 367
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnInputOwnerEndPlayed Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnInputOwnerEndPlayed Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerId Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_UniqueId Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerName Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: OnRep_PlayerState Local
LogNet: VeryVerbose: GetFunctionCallspace Not Net: PhysicsVolumeChanged Local
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Exhausted message, exiting loop.
LogNet: VeryVerbose: SteamNetSockets: Recieved packet from 76561198036455492:-1 with size 63
LogPlayerController: Verbose: Spawned spectator SpectatorPawn_1 [server:0]
LogNet: Verbose: PlayerController_2 setplayer LocalPlayer_2

in particular

LogPlayerController: Verbose: ClientRestart_Implementation None
LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerCheckClientPossessionReliable

seem to indicate that when the client is running

void APlayerController::ClientRestart_Implementation(APawn* NewPawn)

That NewPawn is null though this happens after the setplayer message and I can observe that the pawn does indeed spawn in and for a moment the view is set correctly before it clears it all down and tries again

So my issue must be somewhere between spawning the pawn and verifying that is correct and acknowledging that … I am just not sure where or how that process happens

Stuck on this one still yet

Trying to understand the intended process of a client spawning the content the server tells it specifically the finalization of that e.g. the “acknowledgement” is the only way I can word it … that is whats is going wrong I just am not sure how it should go right and it doesn’t help to debug working ones or hasn’t so far.

Assuming I find it I will comment here what the solution is

This is still an outstanding issue with the crux of the issue being that after the pawn spawns and control is assumed the next step where that is acknowledged is not happening correctly

I have not been able to find where that is, done or how it should work. I am looking at Unreals built in NetDriver for Steam Networking Sockets and we are nearly 1 to 1 with, getting the Built In Steamworks integration of Unreal to work properly hasn’t gone well at all so I haven’t been able to step through it running.

Checking other NetDrivers such as the default IP one hasn’t proven useful either. Has anyone here created a custom NetDriver before or have an idea about this finalization step of spawning in a clients objects?

Hello, have you found the reason? I’ve encountered the same issue. After using the ReplicationGraph, one of my Actor classes, which is unrelated to Gameplay, changes the initialization process. In the function ClientRetryClientRestart, the Pawn parameter is Null.


No, I never did, refactored to use a built-in net driver all together shame but it is what it is