Enemy animation not syncing from peer to host

Godot Version

4.2.1

Question

I am trying to make a co-op beat-em up game, like Streets of Rage.
I have a problem getting things to sync from Peer to Host
So I have 2 players in the game and 1 enemy.
When the peer grapples the enemy, it should put them in the GRAPPLED state and play the correct animation. This works on the Peer machine, but even though the enemy has a multiplayer synchronizer, which is et to sync all grapple values and animation on change, the enemy state and animation isnt being synced over to the host.

I did try the idea in the below thread, however, it seemed to randomly work only when initiating the grapple, but never when breaking it.

Does anybody have any ideas?

Thanks in advance

So when you grapple there are probably checks that happen on a successful grapple, and an animation is triggered. when you go to set state on the remote instance only the variable I set and no functions are called.

The best way to solve this is to have a state-machine keep checking the variables in a process function. And when the variables change go through the proper functions just like it happened on the host machine.

You could fake some things to guarantee the remote instance always matches the host-client, but this problem gets a little hairy to solve.

Thanks for your reply. I have the state machine and variable set up. here is what the player machine sets on the enemy during the grapple

State set to grappled
Boolean set to grappled

If the host does this, everything is set correctly and synced to the peer.
When the peer does this it is not synced to the host.
So Peer and Host are setting the same code on the same enemy, but when peer does it, it’s not synced to the host.

The only way around this I can think of is to set the grapple code outside of the Player script. Since the player script has the multiplayer authority script set I’ve been having problems with stuff like this. But if I put the grapple code just on the body collider, it will work (I know this will because the attack code is on a collider attached to the players fists, and that correctly sets the enemy into a damaged state and calls the correct animation which is synced)

I am very new to all of this so it takes a time to get my head around a new way of thinking. I can’t understand why the enemy values aren’t synced by MultiplayerSynchronizer from peer to host.

I will have to change my approach but I do like to try and work out problems instead of moving on. But I’ve been stuck on it for ages.

Thanks again for your reply.

MultiplayerSynchronizers only go one way. They are not bidirectional, the direction is based on authority of the node. Authority of a node needs to be agreed on by the host and client. Meaning both the host and clients have to call set authority on the same node with the same multiplayer id for synchronization to work correctly. (Everything defaults to host authority, and if you do set_authority all child nodes will recursively be set to the authority. Any new child nodes need to be manually updated.)

Thanks for the explanation, that’s really helpful :slightly_smiling_face:
So would you suggest the best way, when initiating the grapple, is to change multiplayer authority of the enemy to the player doing the grapple? I should be able to do this as I’ve done something similar in a course.

Or I can just go to my other idea of coding the grapple the same way the attack colliders work, as they are displaying properly across both machines.

I guess it’s hard to say without knowing more details on your code, I personally have a grapple hook concept that is pretty complicated which uses joints, and I use a state machine. as my base states change I signal an event that sets a target state, which will later get checked by a process function to see which action to take.

So state change target event and actions are separated. This way if you synchronize the target event state on both sides then the action will take over on the remote end via a process function action check.

Thanks very much for your suggestion. Something that I’ll have to play around with. I didn’t think about sending a signal when the grapple initiates.
Yes sorry for not posting code, I figured it would be easier if I just explained the idea, to get a general idea of how to get around the problem.

You’ve given me some things to think about, I appreciate it. Thanks again.