Hey there I’m facing a small issue with network ownership and client side velocity. I was making a combat system and stumbled on this issue: When setting the network ownership of the dummy to the attacker’s character, it’s causing the dummies to tip over when colliding slightly with them, such as in the reference, that issue doesn’t happen with normal player vs player since other players have clients…
REFERENCE : Watch 2025-01-28 11-36-12 | Streamable
How I set networkOwnerShip :
local rootPart = target:FindFirstChild("HumanoidRootPart")
if not rootPart or not rootPart:IsA("BasePart") then return end
rootPart:SetNetworkOwner(attacker)
How I handle knockback velocity on the client
function KnockbackHandler.applyKnockback(params: KnockbackParams)
if not (type(params) == "table") then return end
if not (typeof(params.target) == "Instance" and params.target:IsA("Model")) then return end
if not (typeof(params.direction) == "Vector3") then return end
if not (type(params.force) == "number") then return end
if not (type(params.duration) == "number") then return end
if not (type(params.verticalForce) == "number") then return end
if not (type(params.isCasterAdvance) == "boolean") then return end
local humanoid = params.target:FindFirstChild("Humanoid") :: Humanoid?
local rootPart = params.target:FindFirstChild("HumanoidRootPart") :: BasePart?
if not (humanoid and rootPart) then return end
if not (humanoid:IsA("Humanoid") and rootPart:IsA("BasePart")) then return end
local knockbackForce = params.direction * params.force
if params.verticalForce > 0 then
knockbackForce += Vector3.new(0, params.verticalForce, 0)
end
if params.isCasterAdvance then
knockbackForce = -knockbackForce
end
local attachment = rootPart:FindFirstChild("RootAttachment") :: Attachment? or Instance.new("Attachment", rootPart)
local alignPosition = Instance.new("AlignPosition")
alignPosition.Mode = Enum.PositionAlignmentMode.OneAttachment
alignPosition.Attachment0 = attachment
alignPosition.MaxForce = math.huge
alignPosition.Position = rootPart.Position + knockbackForce
alignPosition.Parent = rootPart
local vfxHandler = VFXHandler.new()
local knockbackVFX: KnockbackVFX = {}
local maxVFXDuration = 0
local groundDuration
if params.force >= 25 or params.verticalForce >= 0 then
groundDuration = if params.force > 30 then 0.5 else 0.1
maxVFXDuration = math.max(maxVFXDuration, groundDuration)
local groundVFX = vfxHandler:playGroundVFX(params.target, groundDuration)
if groundVFX then
knockbackVFX.groundVFX = groundVFX
end
end
if params.force > 30 then
local trailDuration = 2
maxVFXDuration = math.max(maxVFXDuration, trailDuration)
local trails = vfxHandler:playDashTrails({rootPart}, trailDuration)
if trails then
knockbackVFX.trails = trails
end
end
if next(knockbackVFX) then
activeKnockbacks[params.target] = {
vfxHandler = vfxHandler,
groundVFX = knockbackVFX.groundVFX,
trails = knockbackVFX.trails,
cleanupTime = os.clock() + maxVFXDuration + 0.5
}
end
task.delay(params.duration, function()
if alignPosition and alignPosition.Parent then
alignPosition:Destroy()
end
end)
if activeKnockbacks[params.target] then
task.delay(maxVFXDuration + 0.5, function()
local knockbackData = activeKnockbacks[params.target]
if knockbackData and os.clock() >= knockbackData.cleanupTime then
if knockbackData.vfxHandler then
knockbackData.vfxHandler:destroy()
end
activeKnockbacks[params.target] = nil
end
end)
end
end