(Posted in wrong area) I'm really struggling with Godot Multiplayer and syncing

I’m really struggling with Godot Multiplayer and could do with some help.
Every time I think I know what’s going on, I don’t.
Given this scenario, what is the best way to sync it across players?

I have a 2 player co-op game.
Each player has their own authority set, so only that machine can run the code for that player

Player 2 (peer) walks into the enemy and grabs them.
The player then calls the grab code on the enemy.
The enemy only reacts on player 2’s screen. Player 1 isn’t running this code. It seems to be because the player script has multiplayer authority set, so only one machine (peer) is running the code and the host won’t.

The enemy does have the animation on sync, so when the enemy animation reacts to the grab on player 2’s (peer) machine, shouldn’t it sync to player 1s machine (host)? Because it doesn’t seem to be doing that

I must be going about this whole approach wrong. The basic idea is
I want the enemy to react to a grapple when either player collides with them, and for the enemy reaction to be synced across both screens.

I can move the code to the Area2d that detects the collision, that way it’s not affected by multiplayer authority.

I just can’t understand why the enemy values aren’t syncing from player 2’s machine to player 1’s machine.

Thanks in advance

Although this isn’t part of the course, I feel a bit bad that you haven’t arrived at an answer after all the testing you did related to your other topics. I haven’t done the multiplayer course, so I really can’t be of that much help… but I’ll take a stab at it anyway XD

The first thing I would try is abstracting the problem you’re facing. I would start by giving the enemy a hardcoded number (don’t even make it dynamic for now, doesn’t matter), and on contact with either player, send it:

  • back to that player (sounds like this already works)
  • specifically to the other player as a targeted message (if I understand correctly, this works in one direction and not the other, since P1 is a host)
  • to all players as a broadcast (which I assume you’re trying to do).
    You might get the same result, but if any of these tests turn out differently than you expect for the current status of your game, then that indicates that part of the problem is outside the scope of your transceiving code.

Would it be possible to set up some sort of… not necessarily “global” entity in the normal sense, but something that has the ability to directly transceive data, in a targeted way or broadcast (whichever works; bonus if both), with both players and with enemies? Even if it’s not covered by the course or considered a bad practice, it would be worth looking into that; my uneducated guess would be that this could circumvent any data culling caused by multiplayer authority on the players. If something like that could be implemented, you could use this entity as a multi-directional “messenger pattern” node - basically building a hub-and-spoke network. There are ways of securing that so a given object can’t overwrite the wrong data, but security can be added later. I’m sure you just want it to work at this point! =)

2 Likes

Thanks very much for your lengthy reply and ideas, it is much appreciated.
I did think of the idea of using an adjudicator, something that both players could query so that they each know what they could do.

I also used the player’s unique multiplayer ID in debug printouts to see who is doing what, and even though that was being called correctly on the host when peer grapples the host, the following lines to attack values (such as grapple state) were being ignored.

However I was provided with some information on the Godot forums, and that is that Multiplayer Synchronizer only works one way, from the Multiplayer authority to the rest. So this helped me understand why, even though values can’t be directly changed from host to peer (host grappling peer), that if peer where to change them for its own player (peer grappling enemy) host still wouldn’t see it.
So with that, and something that is within the course, I have found a way around it.

  1. When player v player grapple starts the player walking initiates the grapple. Since both players know and run this code themselves, there is no need for one player to try to directly change values on the second player to tell them they have been grappled. This won’t work if both players are walking and I’ll need a way around this, but currently it’s ok. The reason one player cant affect the other player is because the player script is set to only run if multiplayer authority. I noticed that the attack code CAN affect values on the other player, but that’s not on the player script and so isn’t affected by the multiplayer authority.
  2. When a player grapples an enemy, if I then request multiplayer authority at that point, the player can then correctly grapple the enemy and everything is synced correctly (values can be affected and Multiplayer Synchroniser will go from peer to host) And this is the part that is part of the course.

So with all of this I now have a working solution. Grapple now works between Peer->Host, Host->Peer, Peer->Enemy, and Host->Enemy.
It’s taking a while to understand how MP works in Godot and how I can use it, but I’m slowly getting there.

Thanks again for taking time to reply :slight_smile:

1 Like

Excellent! Multiplayer is surely one of the most challenging realms of game programming, so hopefully your experiences here (not to mention tenacity!) will help others along the way.

Congratulations =)

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms