Netcode For Gameobjects physics rope

Hey people,

I’m currently working on a small cooperative (so cheating is not really an issue) 2d 2player platformer. In the game there are ropes (basically small hingejoint segments that are linked together in a chain also they are connected via distance joints - just because its more stable like that) works kinda well locally.

Some of these ropes hang down to swing on them Tarzan style (picture attached)

I have been developing in Unity for quite a while and tried around with a lot of systems but this is the first prototype I’m trying to get actual online multiplayer into or more like testing if its worth the hassle for a solo hobbyist dev.

My Problem: I followed some tutorials and started initially with the ClientNetworkTransform which already worked kinda well for the movement of the players (running, jumping, climbing etc.) but as the ropes are physics objects there is a lot of desync with just letting the client also manipulate that. I read up in a lot of reddit posts / forum discussions that stuff should be server side and propagated to the Clients I didnt really find a solution that works yet.

In my search I found the smoothSync asset of the store which already helps a lot with better syncing for the owner authorative movement of each player. What would be the best way to get this to work? Does all the movement need to be server sided or can the players own movement be client authorative while the physic objects interaction is server sided? If thats possible how would I do so for the swinging on rope example?

I tried to apply a solution via ServerRpc calls (Taro Dev tutorial + ChatGpt) but still it doesnt help. Either the client player cannot have any influence (swinging adding force) to the rope or when I tried to change the authority of the client to the Server - he just teleports away to only god knows where.
So I would be very glad if someone could tell me if my approach is actualyl doable or if its complete nonsense.
Here is the code:

private void SwingRope()
    {
        if (!NetworkController.Instance.onlineMultiplayer) // Local play mode
        {
            Debug.Log("No multiplayer should just swing Rope");
            playerRigidbody2D.AddForce(new Vector2(horizontalMove * swingForce, 0));
        }
        else // Server applies the force for online multiplayer
        {
            if(IsServer)
                playerRigidbody2D.AddForce(new Vector2(horizontalMove * swingForce, 0));
            else
            {
                if (IsOwner) // Client sends input to the server for validation
                {
                    //SwitchAuthorityToServer();
                    SwingRopeServerRpc(horizontalMove);
                }
            }
        }
    }

    [ServerRpc]
    private void SwingRopeServerRpc(float horizontalInput)
    {
        // Apply force on the server
        Debug.Log($"SwingRopeServerRpc called on server by client {playerController.gameObject.name}, input: {horizontalInput}");
        playerRigidbody2D.AddForce(new Vector2(horizontalInput * swingForce, 0));
    }

private void SwitchAuthorityToServer()
    {
        if (TryGetComponent(out SmoothSyncNetcode smoothSync))
        {
            Debug.Log("Switching authority to server for rope interaction for: " + smoothSync.gameObject.name);
            smoothSync.transformSource = SmoothSyncNetcode.TransformSource.Server;
        }
        else
        {
            Debug.Log($"No SmoothSyncComponentP2 set for: {OwnerClientId}");
        }
    }

Thanks a lot in advance and sry if the question is a bit messy - not really sure on how to best ask this either.

Cheers

To each his own. :wink:

Make sure none of the physics ropes are network synchronized! These ropes need to be simulated client-side only, for every client. Only the local player can interact with them and swing them.

If you can make this work, you’ll find a way to simulate remote players swinging on their ropes. However, if two or more players can swing the same rope, you will have to live with either the other players swinging through the air with no rope attached (since the rope is only for the local player), or drawing multiple ropes - the ropes for remote players being non interactable by players and actually just following the remote player around rather than the remote player actually swinging on it.

General problem is that network-synched rigidbody physics simulation is the holy grail of multiplayer. You just don’t see it in the wild, and when you do, it’s a whacky party game with little to no direct control or a stringently rule-based game in a small, static environment developed with a custom physics engine by an experienced team (eg Rocket League).

Remove SmoothSync for testing. You expressly do NOT want things to be smooth while you try to make it work. The smoothing could negatively affect the behaviour and makes it harder to reason about what is actually happening.

1 Like

Thanks for the detailed response so just that I get that right and some more details on what I wanted:

So something like this where I would like to have the first player swing on the rope to get to the other side → other player can then jump on the already swinging rope and also get on the other side.

So something like the just explained scenario is (at least for me with my limited multiplayer knowledge etc.) impossible to get? Or is there a way with calculating client movement on Server/Host side and just requesting it for the Client similar to some of the tutorials on youtube?

If you are using a client-server network topology and keeping everything server authoritative then it should visually synchronize properly.
Server authoritative
You would want to have user/player inputs sent to the server and let the server handle moving the players. You will want to account for client latency when handling the processing of inputs from players, but you can prototype/develop early alpha with just receiving inputs and having the server “react for the player” upon changes to input state of each player.

I would recommend playing around with potentially using an INetworkSerializable implementation that provides your player input state so the serialization is all handled in one place (i.e. you can optimize what is sent based on only changes to player input as opposed to just sending the current state of player input which will help keep bandwidth consumption low). I would highly recommend including the current client relative network tick (i.e. NetworkManager.ServerTime.Tick and NetworkManager.Singleton.ServerTime.TickOffset for a higher precision of “where in the tick” these states were updated) so on the server side you can use that to help account for latency conditions where player jumps to the rope but it takes 180ms to receive that input…which by that time at least 5 ticks would have passed on the server side and the server can see the input was received at a point in time where the player might not have been (server relative) considered not on a valid floor/surface (i.e. would normally be falling).

If you keep track of player positions for at least 1 to 2 seconds (with server-side tick values of those positions), then the server can determine if the player was indeed on a valid surface when they junmped to a rope (or within a valid range of the rope if jumping rope to rope) and you can do some adjustments to make the jump “valid”.

If you are running a host, then the host side will see some minor visual deltas of other remote player’s position…but it also depends upon your motion model. Of course, video games are about “smoke and mirrors”…so if you make your player animation has a blend tree that can transition to a “failed jump” or a “successful jump” and you provide enough time (i.e. 150-200ms) of the “initial jump” animation then blending between the two can hide the latency delta.

So… triggers at a point past the platforms/floors that kick off the “initial jump” always for all players…then as long as a player has sent “I jumped” or “I grabbed the rope” before the initial jump portion of the blended animation tree is not complete it should look visually correct.

The rope you will definitely need to have some special consideration in regards to how you want to visually synchronize this on clients…always consider if the rope is a physics object (or series of them) then on the client side (unless it is a host too) it will be a kinematic body (or series of them) that you will need to visually synchronize…

Before you get too deep into your project… I would create a very simple POC with Netcode for GameObjects and get the feel for what it can offer and what you will need to write yourself. If you are happy with your POC then all is good… if you are not happy or sort of “in the middle” on what you have…then you might look at Netcode for Entities and make your same POC using that…then compare the experience between the two and determine which best fits your project’s needs.

1 Like

Thanks aswell for the response. I tried implementing both ways:
-just simulating everything locally
-Server authorative movement etc.

And its just too much work for the existing project I would need to rewrite a whole lot of systems for this. I will for now just focus on local coop as it was intended in the start.

Guess its more important to finish the project than trying to get big things like multiplayer into it. If it sees any success I can still try to implement it as I now have a better idea how all this stuff works its just too tedious for now on a hobby project.

Thank you guys anyway I have a multiplayer concept for a game in mind for quite some time that I will start once this project is done and your input will definitely help with that.

Cheers