I’ve been trying to create a knockback system for my game in Roblox, but no matter what I try, I just can’t get it to feel smooth and responsive. I want it to look good on all clients without any delay, but I’m hitting a wall with this. I’ve included a clip from ABA as an example of the kind of knockback I’m aiming for.
So far, I’ve tried:
Using BodyVelocity and BodyForce to apply the knockback.
Messing with network ownership to make sure it’s synced across all clients.
But even after all of that, the knockback still feels delayed or jittery.
What I’m really looking for:
Responsiveness: I want the knockback to be instant and feel snappy for both the player doing the knockback and the one getting hit.
Smoothness: It should look smooth for everyone, without any stuttering or lag.
Sync: I need the knockback to be in sync between the server and all clients.
If anyone has experience with this or knows a good way to handle it, I’d really appreciate any tips. Should the knockback be handled entirely on the server, or should I split the work between the server and clients? Any help will be appreciated.
It looks perfectly smooth to me (The noob being hit get’s knockbacked at the moment you hit him with your hand), and why doesn’t Body Velocity and force worked? Also, can you show footage of both you and another person in the same video? (Like a splited screen or smth) Testing network on npc’s isn’t a good idea because they are handled by the server
The player who initiated the knockback has some lag on the knockback its not as smooth and there is also a little bit of delay is there a way to eliminate that?
I use ApplyImpulse() on the server then send a fire an event to the client which applies the impulse aswell on the client.
Server
if EnemyHRP then
local Force = 200
local UpwardForce = 100
local KnockbackForce = (HRP.CFrame.LookVector * Force) + Vector3.new(0, UpwardForce, 0)
EnemyHRP:SetNetworkOwner(nil)
EnemyHRP:ApplyImpulse(KnockbackForce)
-- ARGS: [LookVector, KnockbackPower] --
RP.Events.Knockback:FireAllClients(EnemyHRP, EnemyCharacter, KnockbackForce)
EnemyHRP:SetNetworkOwner(EnemyPlayer)
end
Client
if TargetCharacter == LocalPlayer.Character then
if TargetHRP and TargetHRP:IsA("BasePart") then
TargetHRP:ApplyImpulse(KnockbackForce)
end
end
The server is well, a server, meaning if you do something from the server it shows for all the clients, so why the need of executing it for all of the other clients aswell? Wouldn’t that delay it more? Also (Maybe because I don’t really create battleground games), why did you set the network owner at first of the enemy root part to nil?
Sure but why would you set it for the server to own the physics? I want to try and understand the logic so I can try to think of a way to make it not delayed, so if you explained it to me, it would be very nice!
I expected that by having the server control the physics, all clients would see the knocked back player, while sending the event to every client would ensure that players who got knocked back would also see their own knockback. This was my thought process during when I was coding it.
But the server already does that! Here’s an example: Jimmy is angry at Tommy, so Jimmy pushes Tommy, if the physics is controlled by the server, that means that ALL clients sees the push, meaning Tommy will see himself getting pushed by Jimmy, aswell as Jimmy and everyone else. If you want to approach a battlegrounds like knockback, I noticed that or they seem to make the ownership the player who attacked or no one at all! Hope this helped
If I set the ownership to the player who is knocking back the enemy. It doesn’t knock them back at all, it only knocks them back If I set this to nil. Could this be because, I am handling the physics on the server?
Okay… I just noticed something. It looks delayed for you because you are playing the knockback to all clients, yourself included, so that’s the reason why. Since you are hitting a dummy, controlled by the server, server who also controls knockback, it should be instant, also, in the example footage it shows you hitting a dummy, a npc, who is controlled by the server, so of course there won’t be any delay.
Solution (Maybe?): Don’t set the impulse manually through all clients since the server does it already (For you)
Yes, I have deleted the client script and the fire event.
All I have:
if EnemyHRP then
local Force = 250
local UpwardForce = 100
local KnockbackForce = (HRP.CFrame.LookVector * Force) + Vector3.new(0, UpwardForce, 0)
EnemyHRP:SetNetworkOwner(nil)
EnemyHRP:ApplyImpulse(KnockbackForce)
end