How can I reduce network ownership delay from unanchoring a part?

I’m making a fighting game and I’m facing a bit of an issue where doing knockback on a player who has just been released from a grab has significant and unwanted delay, I’m aware that there is always going to be latency, but this seems to be worse than most other fighting games (TSB, JJS, etc.).

Here is a video of the issue:

Grabbing in this game works by making all clients teleport the enemy in front of the player while keeping the player anchored on the server. After the move finishes the enemy’s body is teleported to the player where it is then knocked back. It’s during this part where the HumanoidRootPart is unanchored that there is significant delay, however, I am unable to deduce where the issue stems from.

The following code is the logic that the game uses when determining the order of each operation:

hitChar:PivotTo(char.HumanoidRootPart.CFrame*CFrame.new(0,1.5,-2)) -- teleport player
CombatService.EndGrab(char) -- unanchor player
states:Add({"Stun", "Ragdoll"}, LoveHug.Config.StunTime) -- ragdoll player
Knockback.Add(hitChar, char.HumanoidRootPart.CFrame.LookVector, LoveHug.Config.KbDistance, LoveHug.Config.KbTime, Vector3.one*40000) -- knockback player

Am I looking something over here, because I am completely stumped.

2 Likes

Hello!
The delay issue might be due to the sequence of operations or the network latency involved in synchronizing states between the server and the client. Here are some potential issues and suggestions to improve the responsiveness:

1. Order of Operations

  • Immediate Pivot to Target: Ensure that hitChar:PivotTo() is executed as soon as possible and confirm that no unnecessary computations occur between this and subsequent actions.
  • Anchoring/Unanchoring Timing: Verify that CombatService.EndGrab() unanchors the player before applying knockback. Any delay here could propagate through the sequence.
  • Knockback Application Timing: If the knockback relies on the unanchored state, ensure there’s no frame where the character is still considered anchored or otherwise restricted.

2. Physics Replication

  • Roblox’s physics can sometimes delay effects when objects are unanchored or moved over the network. To address this:
    • Apply Knockback Server-Side: Instead of relying on client-side replication for knockback, apply it server-side and let it replicate to all clients.
    • Force Replication: Add a small artificial “jiggle” or slight offset to the HumanoidRootPart to force faster replication of physics updates.

3. Debugging Tips

  • Timing Analysis: Use debug logs or tick() to measure the time difference between each step (teleportation, unanchoring, knockback).
  • Latency Compensation: Temporarily disable visual effects or non-essential computations between the steps to see if that reduces the delay.

4. Optimization Ideas

  • Pre-Calculate States: If possible, pre-determine where the character will move and their state transitions so that the server-client synchronization happens faster.
  • Custom Knockback System: Instead of relying on Roblox’s default physics for knockback, use a custom tween-based or velocity-based system that updates consistently across clients.

Example Adjustment:

Here’s a revised sequence ensuring minimal delay:

-- Immediate teleport
hitChar:PivotTo(char.HumanoidRootPart.CFrame * CFrame.new(0, 1.5, -2))

-- Pre-calculate knockback data
local knockbackDirection = char.HumanoidRootPart.CFrame.LookVector
local knockbackForce = Vector3.one * 40000
local knockbackDuration = LoveHug.Config.KbTime

-- Perform unanchor and knockback in quick succession
CombatService.EndGrab(char) -- Ensure this is fast and server-side
task.defer(function() -- Defer to the next frame to avoid overlap
    states:Add({"Stun", "Ragdoll"}, LoveHug.Config.StunTime)
    Knockback.Add(hitChar, knockbackDirection, LoveHug.Config.KbDistance, knockbackDuration, knockbackForce)
end)

If the issue persists, the root cause may lie in either how the CombatService.EndGrab function handles unanchoring or how the knockback is processed across clients. Let me know if you can share more details about those functions!
by ai

1 Like

I’m willing to bet this was just written by ChatGPT… I think we all appreciate people trying to help and chiming in, but I don’t think posting answers written by ChatGPT is the right move.

3 Likes

I know, but this is a simple solution that can be solved by using a single ai for this

1 Like

Have you tried other solutions other than the anchor and unanchor. In my experience, anchoring and unanchoring a player is really buggy. If its just that you don’t want the other player to move during the ‘grab and throw’ maybe you could put the other player in a humanoid state, such as platform standing or even a ‘seated’ state. Maybe even just use a ‘seat’ part that you weld to the attacker, and have the victim be forced to sit in it, but playing a non sitting animation. Its less buggy than the whole anchor thing. Just some suggestions from when I had a game where you could carry another player (also I had to reduce the other players weight, such as setting all parts to massless except the humanoidrootpart)

1 Like

The thing with that is that the player collision is also disabled so if I just only disable their movement or set their humanoid state they will fall through the map on the server. I’d also have to set the network ownership which would probably cause the same problem.

After doing some research I would heavily recommend following the approach of this post: How to weld two rigid bodies without one interfering with the other's physics? - #17 by dthecoolest. Instead of anchoring and cframing you would set the network ownership to the player grabbing them and use align position and orientation with rigidity enabled to position the enemys root part.

i’ll try and out and see what happens!

I’d say the difference is quite negligible but there is probably an extent to how responsive you can actually get this to look.

1 Like

After looking back and testing in studio setting network ownership is the worst way to go. For the best experience play to player wise at least is anchoring their character on the server. “Stun” the enemy to prevent them from moving. And then have each player cframe the grab. That way it looks smooth for the player being grabbed and there will always be minor lag since telling players to stop cframing will always be delayed. One things I think that helps negate is maybe using a spring of some sort. I’m not sure for example what legends battlegrounds does but grabbing in that game you can see it smooths out the player to the grab position. For npcs only you would pivot their position before un anchoring them but still have clients move them for the grab.