AGameModeBase::Logout doesn't seem to work in UE 4.26

Hello everyone.

I’m making a multiplayer game using UE4.26. I have a GameMode class that extends GameModeBase, where on PostLogin, I assign team index to connected PlayerControllers. PostLogin works as expected.
When a player type “disconnect” into their console or alt+F4, I want to free the slot in my team array, but I cannot detect the disconnection event. Everyone says “use Logout function”, but when I extend it and put my code in, it’s never called. I put my log on every function of my GameMode class and it showed everywhere except Logout.
I test on both “Play As Client” in the editor, starting UE edtior with “-server” param, and building my own dedicated server using the special UE4 build from Github. AGameModeBase::Logout just never get called no matter how the client disconnect, reconnect, alt F4, unplug internet cable… nothing. Not called once.
Is this a bug only to UE4.26? Or did I miss something?
If this doesn’t work, Is there any other way I can detect player disconnection?

Since you aren’t disconnecting the client gracefully (that is, by not attempting to notify the Server you are leaving) - the Server is likely waiting for the player connection to timeout instead, before it removes the controller and calls “Logout”.

You don’t want to make that timeout too short, because then legitimatelly connected players can timeout. The best way to handle this is to add a “graceful” logout process. You could even hijack the alt+f4 command to attempt that before closing the application.

If you are using sessions, ending and destroying the session is usually enough to notify the server that a player is leaving.

Thank you very much for your reply.

At first, I thought so also, so I waited for like 15 minutes. Still, Logout not called. Can you show me where to edit the timeout amount?
For graceful logout, is this supported by UE already or I have to implement my own RPC?

Thanks again.

When I exit out of the editor my GameMode class that exends AGameModeBase, the Logout method is called for each client opened.

I assumed you confirmed you overrode it correctly?

virtual void Logout(AController* Exiting) override;

Hello. Yes, I override it exactly like this. The function never called, I even waited after 2 hours since the client disconnect to make sure there is no timed out.
The pawn which the PlayerController posses isn’t even destroyed like they say it will be.
The function GetNumPlayers() still return the same number of players. (Yup, I print it to log in Tick for 2 hours straight)
Something is wrong with my unreal engine I guess.

Edit: When a client disconnect, I found this little piece of log inside Dedicated server console:

LogNet: UNetConnection::Close: [UNetConnection] RemoteAddr:, Name: IpConnection_0, Driver: GameNetDriver IpNetDriver_0, IsServer: YES, PC: PlayerControllerTank_0, Owner: PlayerControllerTank_0, UniqueId: NULL:, Channels: 9, Time: 2021.01.20-11.31.10

LogNet: UChannel::Close: Sending CloseBunch. ChIndex == 0. Name: [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr:, Name: IpConnection_0, Driver: GameNetDriver IpNetDriver_0, IsServer: YES, PC: PlayerControllerTank_0, Owner: PlayerControllerTank_0, UniqueId: NULL:

The dedicated server is well aware of a client recently disconnected. It just doesn’t do anything. Doesn’t destroy pawn, doesn’t reduce the number of player, and doesn’t call “Logout”.

If I use the default PlayerController, LogOut will be called normally.
If I use my custom PlayerController, LogOut won’t be called.

Then I checked and I saw in my BeginPlay method, I forgot to Super::BeginPlay.

After adding that, LogOut is called normally.

Hard to believe that one line missing result in the game play normally, except when players decide to quit. :frowning:

Oof! I have experienced this kind of oversight as well. Glad you got it tracked down. Hooking things properly into this beast is a constant battle.