Can't disable tick event of characters on server side

Hello, I have multiplayer design(listen server). Inside the BP of a character, the following code was used to disable tick event of non-local.

It works to disable tick event of non-local characters in client side. But, it doesn’t work to disable tick of non-local characters on server. In my test, I have 1 server and 2 clients.
There are 3 instances of character running on server, one is the character controlled by server itself and another 2 are the copies of 2 client characters.

It’s expected to disable the tick of 2 client character on server. But it does not work.

Does anybody know why?

After some tests with different settings, one approach was found to make this work.
Right after Event_BeginPlay, some delay is required. I added 2 seconds delay as illustrated below. It works.

I guess ‘IsLocallyControlled’ function is not ready at the moment of Event_BeginPlay. And it will be ready for use after a while(like 2 seconds). However, I can’t find any document to confirm my guess.

Correct. A pawn is spawned, at some point BeginPlay is fired (both on server and client), then he is possessed by a controller, getting Possessed to fire (on server). IsLocallyControlled was returning false because the pawn wasn’t possessed yet.

What you did isn’t a real fix, but a hotfix. Refrain from using delays, and stick to event-based code.

My approach will likely be:
Turn off tick on pawn by default (set Start with Tick Enabled in Class Defaults to false, and on Possessed fire a client RPC that runs SetActorTickEnabled with Enabled checked.

1 Like

@WizardCell Thanks a lot for the insightful comments! Indeed, the approach you recommended is more decent and will take it as the solution.

I have a further question. In the code above, I added a PrintString after CLT_StartTick to show how many times CLT_StartTick Event is called.

When the server hosted and started the game(2 clients didn’t join yet), the screen output is as below. It looks good.

After a while, the first client(client 2) joined the game, the screen output is as below. I was expecting only client2 printed out the message, but the server printed out the message as well. I don’t know why. Does this mean SetActorTickEnabled was implemented on server as well? and the tick event of client2 character was enabled on the server as well?

After a while, the 2nd client(client 0) joined the game. The screen output is as below.
I don’t understand why client2 and server printed out the ‘Possessed!’ messages. I was expecting only client0 can print out the message. Does this mean SetActorTickEnabled was called again on server and client2? Does this mean tick event of client0 was enabled on the server and client2 as well?

Are you sure those aren’t old messages? If they are stacking up then that’s normal, but if the message for an already joined players are removed then added back after a late joiner joins then no that shouldn’t happen. Tested on my end for sanity and it only shows new messages for newer clients (only late joiners, though messages can stack up depending on the display time you’ve set) which is normal.

@WizardCell , Yes. I’m sure those are not old messages. In my test, new player won’t join until old messages are gone. So, the messages on the screenshot are triggered by the new player’s logging in.

It looks weird, but it happed in my test.

That’s weird. Simulated proxies (pawns that are not yours) aren’t possessed for the simple reason that controllers don’t exist for them on your machine. Unless you’re doing local multiplayer, which is another story.

Currently, I’m using one computer to test a multiplayer game with the following settings.
image

Is this making the difference?

@WizardCell ,I added “IsLocallyControlled” and did the test again. The result is the same. The branch “Failed” never happened.

I’m guessing EventPossessed happened each time new player join the game and then it triggered all possessed-successfully CLT_StartTick events again including those on server and clients which have joined the game and possessed successfully last time. Not sure if my guess is correct and have no idea how to confirm it.

The branch Failed should never happen. Possessed event only fires on autonomous proxies, i.e., pawns that the player has control over (i.e. are locally controlled).

I reproduced on my end with the exact same settings you have: 3 standalones, where the first hosts a map, and the other 2 join him.


First player presses the 2 key, while the other two press the 0 key. It’s working as before ( before I was launching as client and late joining).