Forces created locally on a player character have severe replication delay no matter what is used

quite simple, i want to find a method or workaround that has no innate replication delay, or a negligible amount of it compared to whats shown in the attached vids. first clip is setting assemblylinearvelocity, second clip is linearvelocity constraint

the way i’m replicating my vfx is client > server > other clients, where the user creates them on their side first, sends a request to the server, then the server fires to all clients and the receiving end calls the same vfx functions as the user, ignoring the client event if they are the same user. everything about this model works fine, all animations and associated events are in sync. the only problem seems to be when the user locally creates a constraintforce or any form of bodymover, this is the part that’s not done in the vfx functions. the only movement that doesn’t have innate replication delay is the default movement (WASD, jumping, etc)

i’ve tried all types of body movement, including linearvelocity, setting assemblylinearvelocity directly, applying impulses, all of the above. everything has noticeable builtin delay that appears unavoidable. any suggestions for what should be done would be appreciated

The idea of replicating client → server → client is the best (only) option available. The network delay visible here is unavoidable in a client-server architecture. Some online multiplayer games utilize a peer-to-peer (P2P) architecture to decrease this delay (however a delay is still present) and P2P is not an option on Roblox anyways.

Techniques used to mask the unavoidable network delay under a client-server architecture are generally called “netcode” and may involve client and/or server prediction, server authority, and flashy effects that distract the player(s) experiencing a delay over the network. The general idea is to keep things snappy for each client personally (in other words, if a client activates an effect, perform that effect immediately instead of waiting for confirmation from the server) and do your best to hide any replication delay from other clients.

i am aware of how roblox’s network model works, i’m more focused on why there’s such a large innate replication delay on locally instantiated forces that affect a player’s character. the playtest the clips are from is a local server in studio, that should not result in delays of movement this high

As you can tell, the Roblox engine handles physics replication a bit different here.

You would have to create a local copy of every player character that you will use to switch between a player’s actual character and the local copy of their character. When you handle the VFX for another player, switch their actual character for the local copy, then replicate the player’s movements through the local copy. You might be able to get away with simply applying the same linear velocity to the local copy as the other player does to their own character, but that will only work if the local copy is lined up correctly and the physics simulation is deterministic.

Worst case, you can use an unreliable remote event to send the CFrame of the player’s root part every frame to every player (client → server → client), then move the local copy of that player’s character to the CFrame that you sent over the wire. This way you don’t have to wait for Roblox replication to do its thing.

Edit

When you first do this, however, you may notice that the character movement looks choppy when some of the data gets lost over the wire. This can be mitigated by interpolating the character’s positions to make movement appear smooth. There are different ways of doing it, but what I do is I get the direction that the player has to move in (i.e. (newPosition - currentPosition).Unit), then I move the player in that direction by X amount of studs per second. I’m assuming you know how to move a part every frame at a constant speed, but if you get stuck on that then I suggest you make a separate post. One more thing, when the distance between the character’s current position and new position is very small, then floating point errors will also start to mess up your movement. The fix for this is simple. Since the distance is small, we can skip the interpolation altogether and just update the player’s position directly.

Don’t worry about bandwidth usage; sending 16 CFrames every frame adds up to about 35KB per second. Although that is not a small amount of data to be sending, it’s still an acceptable amount to send if the effect only lasts for a second or two (this is what I do in my game without any complaints about performance), so only sending one CFrame every physics step will be negligible for you. You just have to make sure you’re switching between the local copy and the actual player correctly.

1 Like

haven’t thought about the local character copy approach, i will try something similar to this and see how it works out

I’m not sure if a local server started from studio automatically adds some artificial network lag or not. You can try checking File → Studio Settings → Network → “Incoming Replication Lag (seconds)” and setting this to 0 if it isn’t already.

yeah, i’ve done playtests with that setting before but i recently did non-studio tests with a friend who is on the opposite side of the world, and we were both seeing the same behavior. i still did check to see if it was 0

I edited my comment to mention interpolation if you do end up using unreliable remote events.

:+1: much appreciated, your original reply was very helpful. i have a few options and i know how to execute them within my infrastructure

for my case, I settled with a much simpler approach. all I had to do was create a mimic HRP on each side that was propelled by the same linear velocity, which used a starting cframe sent over the wire for each dash. it also uses an align orientation to more closely match the rigidity of the HRP

1 Like

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