LinearVelocity suddenly forces players/dumies at a insane force despite having force restrictions in place

I am currently having a issue with LinearVelocity. Keep in mind there are multiple LinearVelocity objects being created by a hitbox to force away a player/dummy from the player’s position by the direction the attack is in.

Code

ALL CODE IS RUNNING ON THE SERVER

Legend:
Info: Info is a configuration value that stores attributes.
Attacked_Direction: An attribute value set by a separate module to display the attack’s position from hitting the dummy/player.
AmountOfDamageDealt: The amount of damage the player/dummy has received from one attack for calculating force.

Force Module

local VectorForce: LinearVelocity = {}
VectorForce.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
VectorForce.ForceLimitsEnabled = true
VectorForce.ForceLimitMode = Enum.ForceLimitMode.PerAxis
VectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
--VectorForce.ApplyAtCenterOfMass = true
--VectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0

local module = {}

--Current Force is defective btw

function module.CreateForce(instance: Instance, HumanoidRootPart, Direction: Vector3, AmountOfForce: number, Linger: number, MassScaling --[[, VectorForceVector3Force: Vector3]])
	if HumanoidRootPart == nil then print("NO VALID HUMANOIDROOTPART, RETURNING") return end
	if HumanoidRootPart.Anchored == true then return end
	local Info = instance:FindFirstChild("Info")
	if Info == nil then return end
	local Immunities  = Info:FindFirstChild("Immunities")
	if Immunities  == nil then return end
	if Immunities:GetAttribute("KnockbackImmunity") == true then return end
	--task.synchronize()
	
	warn(Direction)
	warn(AmountOfForce)
	warn(HumanoidRootPart.Mass * MassScaling * AmountOfForce)
	warn(Direction * (HumanoidRootPart.Mass * MassScaling) * AmountOfForce)
	
	local Attachment0 = Instance.new("Attachment")
	Attachment0.Parent = HumanoidRootPart
	local VectorForceClone: LinearVelocity = Instance.new("LinearVelocity")
	
	for PropertyName, Value in pairs (VectorForce) do
		VectorForceClone[PropertyName] = Value
	end
	
	VectorForceClone.Attachment0 = Attachment0
	local Formula = HumanoidRootPart.Mass * MassScaling
	local ActualFormula = (Direction * Formula * AmountOfForce)
	VectorForce.MaxAxesForce = Vector3.new(1,1,1) * math.huge
	VectorForce.VectorVelocity = ActualFormula

	VectorForceClone.Parent = HumanoidRootPart
	--HumanoidRootPart.AssemblyLinearVelocity = VectorForceVector3Force

	Debris:AddItem(VectorForceClone,Linger)
	Debris:AddItem(Attachment0,Linger)
	
	--task.delay(0.5,function()
	--	HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(0,0,0)
	--end)
	
	--task.desynchronize()
end

Stun System
Normal Knockback

DeathConnection = Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
	if Humanoid.Health <= 0 then
		DeathConnection:Disconnect()	
		StunConnection:Disconnect()
	elseif Humanoid.Health > 0 then
		if Humanoid.Health > PreviousHealth then PreviousHealth = Humanoid.Health return end
		if Info:GetAttribute("Stunned") == true then PreviousHealth = Humanoid.Health return end
		AmountOfDamageDealt = PreviousHealth - Humanoid.Health
		PreviousHealth = Humanoid.Health
		Info:SetAttribute("Running", false)
		
		Humanoid.WalkSpeed = 0
		
		local HRPPosition = (HumanoidRootPart.Position + Vector3.new(math.random(-100,100) / 100,0,0))
		local Direction = (HRPPosition - Info:GetAttribute("Attacked_Direction"))
		
		if Direction.Magnitude < 0.001 then
			Direction = Vector3.new(0,0,-1)
		else
			Direction = Direction.Unit
		end

		task.spawn(VectorForceModule.CreateForce,Character,HumanoidRootPart,Direction,2.5,0.1,1,Direction * 1.25)

		local CurrentState = Info:GetAttribute("AnimationDebounce")
		
		if Info:GetAttribute("AnimationDebounce") ~= true then
			Info:SetAttribute("AnimationDebounce", true)
		end
		
		local Animation = KnockbackAnimations[math.random(1,#KnockbackAnimations)]
		
		task.spawn(function()
			Animation.Stopped:Wait()
			Animation:AdjustSpeed(0)
			task.wait(0.2)
			Animation:AdjustSpeed(1)

			if Info:GetAttribute("AnimationDebounce") == true and Info:GetAttribute("Stunned") ~= true then
				Info:SetAttribute("AnimationDebounce", false)
				Humanoid.WalkSpeed = Info:GetAttribute("OriginalWalkspeed")
			end
		end)
		
		Animation:Play()
	end
end)

Stunned Knockback

StunConnection = Info:GetAttributeChangedSignal("Stunned"):Connect(function()
	if Info:GetAttribute("Stunned") == true and Info:GetAttribute("Blocking_Disrupted") ~= true then
		Info:SetAttribute("AnimationDebounce", true)
		Attack_Adjustment:SetAttribute("Godded", true)
		Info:SetAttribute("Running", false)
		Humanoid.WalkSpeed = 0
		
		local HRPPosition = (HumanoidRootPart.Position + Vector3.new(math.random(-300,300) / 100,0,0))
		local Direction = (HRPPosition - Info:GetAttribute("Attacked_Direction"))
		
		if Direction.Magnitude < 0.001 then
			Direction = Vector3.new(0,0,-1)
		else
			Direction = Direction.Unit
		end
	
		task.spawn(VectorForceModule.CreateForce,Character,HumanoidRootPart,Direction * -(5 * AmountOfDamageDealt),AmountOfDamageDealt * 10,0.1,1,Direction * Vector3.new(3,(AmountOfDamageDealt * 4.5),3))
		
		local ActualAnimation: AnimationTrack = nil

		if type(StunAnimation) == "table" then
			ActualAnimation = StunAnimation[math.random(1,#StunAnimation)]
		else
			ActualAnimation = StunAnimation
		end
		
		task.spawn(function()
			ActualAnimation:GetMarkerReachedSignal("Slowdown"):Wait()
			ActualAnimation:AdjustSpeed(0.5)
		end)

		task.spawn(function()
			ActualAnimation:GetMarkerReachedSignal("Disable"):Wait()
			ActualAnimation:AdjustSpeed(1)
			
			Humanoid.WalkSpeed = Info:GetAttribute("OriginalWalkspeed")
		end)
		
		task.spawn(function()
			ActualAnimation.Stopped:Wait()
			Info:SetAttribute("AnimationDebounce", false)
			Info:SetAttribute("Stunned", false)
			Attack_Adjustment:SetAttribute("Godded", false)
		end)
		
		ActualAnimation:Play()
	end
end)
Demonstrations of the bug

Dummy being forced away

Streamable Link Watch Voxelflict - Roblox Studio 2025-01-20 12-43-21 | Streamable
Raw Link (In Case Streamable Expires) https://cdn.discordapp.com/attachments/1173144201588908042/1331001618950389934/Voxelflict_-_Roblox_Studio_2025-01-20_12-43-21.mp4?ex=6790075a&is=678eb5da&hm=480af60f8c99458d3f4d14a41dced2417115290565beca44dc9af0f460ff186a&

Players being forced away

Streamable Link Watch Server - Roblox Studio 2025-01-20 12-42-23 | Streamable
Raw Link (In Case Streamable Expires) https://cdn.discordapp.com/attachments/1173144201588908042/1331001620745551985/Server_-_Roblox_Studio_2025-01-20_12-42-23.mp4?ex=6790075b&is=678eb5db&hm=9856a61a271636cc8d52fb0e7659a9539a45f5f2cb01be8c664f9404949093bd&

Disclaimer: Multiplie Knockbacks are intentional.

Currently my issue is the following: While hitting dummies/players normally (Where the dummy/player doesn’t fall down onto the ground) repeatably works fine, stunning the dummy/player once with a force stronger than regular attacks and then hitting them with a normal attack causes the dummy/player to be forced away at a insane force (The Core Issue, players are not forced away enough with a attack that should stun players and cause large knockback. Instead, the force from the attack that should stun is being held in for a unknown reason.), which should not be possible with the variables in place to stop such force from happening. Keep in mind all the LinearVelocity objects would have been destroyed by the time the player/dummy has no longer been stunned, so one LinearVelocity object creating this much force with parameters set in place is something I don’t understand why it’s happening.

I have also tried BodyVelocity and VectorForce. They all have had the same result. I could limit the amount of force for .MaxAxesForce, but thats a band-aid fix to such problem.

I’ve also printed .VectorVelocity. It does not show any NaN values, which is weird. Thus, I’m out of ideas and in need of such help. I’ve also noticed that someone else had a similar problem that was unresolved while making this post (although their LinearVelocity properties are different, they have had the same problem with knockbacks somehow flinging players at a insane force despite having arguments in place) here. If anyone would like to help, please do!

Update: The animations, adjusting force are not the problem. It seems as if the force is being held onto the player despite already being set to a finite amount, not a insane number that causes the dummy/player to fling. I do not know what is causing that to happen. It is also exclusively only happening when the player/dummy is stunned.

1 Like

Full Update: I have completely idenified the issue. LinearVelocity does not apply for the first time when I stun the player/dummy despite already calling the module function, which I find stupid.

Update: I found the issue. I was modifying the table in the module and not the LinearVelocity clone.