Advice on how I can improve my stun system

Feedback is appreciated!

This system gets a bindable event, checks if it is fired then checks if the humanoid is in the table already. Please read the script to better understand it. :smiley: Please give me feedback on what to change or do to make this more efficient. :slight_smile: Thanks!!

local stunned = {}

game:GetService("ReplicatedStorage"):WaitForChild("Stun").Event:Connect(function(hum, length, ws)
	if table.find(stunned, hum) then
		local count = length
		
		--Count loop
		while table.find(stunned, hum) do
			if count ~= 0 then
				count -= .1
				print("Remaining: "..count.." | Current WalkSpeed: "..ws)
			end
			wait(.1)
		end
		
		hum.WalkSpeed = ws
		hum.JumpPower = 0
		table.insert(stunned, hum)
		wait(count)
		hum.WalkSpeed = 16
		hum.JumpPower = 50
		for i, v in pairs(stunned) do
			if v == hum then
				table.remove(stunned, i)
			end
		end
	else
		print("Not found. Stunning for: "..length.." sec/s.")
		table.insert(stunned, hum)
		hum.WalkSpeed = ws
		hum.JumpPower = 0
		wait(length)
		hum.JumpPower = 50
		hum.WalkSpeed = 16
		for i, v in pairs(stunned) do
			if v == hum then
				table.remove(stunned, i)
			end
		end
	end
end)

Hello!

I made some small changes, although your script didn’t need many. Walk speed change could have been moved to separate function so we don’t repeat ourselves (DRY principle). Despite table.find being really fast, there is a faster way to check if humanoid is in a table, since you are checking that repeatedly inside the count loop, and that is using dictionary-type tables.

stunned[humanoid] = true -- add to dictionary
stunned[humanoid] = nil -- remove from dictionary

--[[
    Humanoid is now an index as opposed to the previous case (table.insert), where
    it was an element with index of one:
        stunned = {
            [1] = humanoid;
        }
]]

Lastly, repeat-loop would be probably a better option compared to while-loop. Maybe you can even remove it, because it might not be needed at all.

local stunned = {}

local bindEvent = game:GetService("ReplicatedStorage"):WaitForChild("Stun")

local function stun(humanoid, count, ws)
	humanoid.WalkSpeed = ws
	humanoid.JumpPower = 0
	stunned[humanoid] = true
	wait(count)
	humanoid.WalkSpeed = 16
	humanoid.JumpPower = 50
	stunned[humanoid] = nil
end

bindEvent.Event:Connect(function(humanoid, length, ws)
	if stunned[humanoid] then
		local count = length
		repeat
			wait(.1)
			count -= .1
			print("Remaining: "..count.." | Current WalkSpeed: "..ws)
		until (count <= 0) or (not stunned[humanoid])
		
		stun(humanoid, count, ws)
	else
		print("Not found. Stunning for: "..length.." sec/s.")
		stun(humanoid, length, ws)
	end
end)

Have a meaningful day!

1 Like

Thanks sooo much! :smiley: Im gonna learn alot from this :slight_smile: !!