Stun Module Error While Modifying it

Module Origin:Stun Handler V2.1 - #18 by crazygamespp

I ran into an issue while using this module.Everything works fine until I implemented a few lines for the stun to work more well with my game.The problem basicly makes all players who ever been stunned stay stunned forever.

Can anyone maybe help with what’s the problem with my module.
Help is appreciated! :smiley:

“CanAttack” is just a Bool Value thats located in a player character to determine if he or she is allowed to use a move.

local heartbeat = game:GetService("RunService").Heartbeat

local Stunned = {}

local clock = os.clock
local isChecking = false
local checkConnection
local currentTime
local stunnedHumanoids

local function stunChecker()
	currentTime = clock()
	stunnedHumanoids = 0
	
	for humanoid, data in pairs(Stunned) do
		if not data.stunned then continue end
		
		if currentTime >= data.duration then
			data.stunned = false

			data.changedConn:Disconnect()
			data.changedConn = nil

			if humanoid:IsDescendantOf(workspace) then
				humanoid.WalkSpeed = data.speed
				humanoid.JumpPower = data.jumpPower
				humanoid.JumpHeight = data.jumpHeight
				--local CanAttack = humanoid.Parent.CanAttack
				humanoid.Parent.CanAttack.Value = data.stunbool
				humanoid.Parent:SetAttribute("Stunned", false)
			end
		end
		
		stunnedHumanoids += 1
		-- print(string.format("waiting: %f", data.duration - currentTime))
	end
	
	if stunnedHumanoids == 0 then
		checkConnection:Disconnect()
		isChecking = false
	end
end


--//Stun Handler
return {Stun = function (humanoid, duration, CanAttack)
	if humanoid.Health <= 0 then return end
	
	if not Stunned[humanoid] then
		Stunned[humanoid] = {}
	end

	local data = Stunned[humanoid]
	currentTime = clock()
	
	if not data.stunned then -- not stunned
		data.stunned = true
		data.duration = currentTime + duration
		data.speed = humanoid.WalkSpeed
		data.jumpPower = humanoid.JumpPower
		data.jumpHeight = humanoid.JumpHeight
		data.stunbool = humanoid.Parent.CanAttack.Value
		humanoid.WalkSpeed = 0
		humanoid.JumpPower = 0
		humanoid.JumpHeight = 0
		CanAttack.Value = false
		
		humanoid.Parent:SetAttribute("Stunned", true)
		
	elseif data.duration - currentTime < duration then -- update duration if less time left
		data.duration = currentTime + duration
	end
	
	if not data.changedConn then
		data.changedConn = humanoid.Changed:Connect(function()
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
			humanoid.JumpHeight = 0
			CanAttack.Value = false
			end)
	end
	
	if not data.diedConn then
		data.diedConn = humanoid.AncestryChanged:Connect(function()
			data.diedConn:Disconnect()
			
			if data.changedConn then data.changedConn:Disconnect() end
			
			Stunned[humanoid] = nil
		end)
	end
	
	if not isChecking then
		isChecking = true
		checkConnection = heartbeat:Connect(stunChecker)
	end
end}

--local StunHandler = require(game.ReplicatedStorage.StunHandlerV2)

--StunHandler.Stun(hit.Parent.Humanoid, 10, hit.Parent.CanAttack)

Hey @YugaHinohara
I think its the CanAttack value which is being set after the stun duration is over. In the stunChecker function, where u have this code:

humanoid.Parent.CanAttack.Value = data.stunbool

This sets the CanAttack value to data.stunbool, which is the value of the CanAttack value at the time the stun was initiated. This means that even after the stun duration is over, the CanAttack value is still being set to false (or whatever value it had when the stun was initiated), which is why all players who have ever been stunned are staying stunned forever.

To fix this issue, you can modify the data table to include the original value of the CanAttack value, like this:

if not Stunned[humanoid] then
	Stunned[humanoid] = {
		stunbool = humanoid.Parent.CanAttack.Value,
	}
end

Then, in the stunChecker function, you can set the CanAttack value to the original value when the stun duration is over, like this:

humanoid.Parent.CanAttack.Value = data.stunbool

This should fix the issue and allow players to become unstunned after the stun duration is over. :smiley:

Hope it helped, or made sense
Sincerely Delusively

1 Like

It works perfectly fine and everything until today when I was just messing around in my game and the stun issue happened again.Same issue where I checked the Console and see no error from the module script.Though what I know is that the attribute named “Stunned” is gone from humanoid and yet all the properties of stun still remain active.
Seems like this bug happens at random time and I cant seem to trigger this bug at will.

I am clueless to why even this happened.

Hey again @YugaHinohara

It’s possible that there is some code or interaction in your game that is causing the “Stunned” attribute to be removed from the humanoid. If this attribute is being used by your stun module to determine whether a humanoid is currently stunned, then that could explain why the stun properties remain active even though the attribute is gone.

One way to investigate this issue would be to add some additional logging to your stun module to help you identify when the attribute is being removed, and what might be causing it. For example, you could add a print statement inside the stunChecker function to log the state of each stunned humanoid and whether or not it has the “Stunned” attribute. This might help you identify when the attribute is being removed and potentially narrow down the cause of the issue.

Another possibility is that there is some kind of race condition or synchronization issue in your code that is causing the stun module to get out of sync with the state of the game. If this is the case, it might be helpful to review your code and make sure that all relevant events and data are being properly synchronized and updated in a consistent and reliable manner.

Sincerely Delusively :smiley:

1 Like

I found the source of the problem on complete accident and manage to track it down but still is clueless to why the attribute is still staying the same.

image

How my iframe works in my game is that I create a Force Field and named it “Iframes”
Every time when I activate Iframes and use a skill that stuns myself it will make me stun forever.

(The red aura is the iframes activated)

Video showing the issue

Also sorry for the extremely insanely late reply since I was busy with personal stuff in my life.

I ran into this problem too, what lines of code did you add btw?

1 Like

I like how its been almost a year, yeah still haven’t found a solution to this yet.
:skull:

-- StunHandlerV2.lua
local StunHandlerV2 = {}
local Debris = game:GetService("Debris")

-- Table to keep track of players that are stunned and their stun durations
local stunnedPlayers = {}

-- Function to stun the humanoid for a given duration
function StunHandlerV2.Stun(humanoid, duration)
	-- Validate input
	if not humanoid or not humanoid:IsA("Humanoid") then
		warn("Invalid humanoid provided.")
		return
	end

	local character = humanoid.Parent
	local stunnedValue = character:FindFirstChild("Stunned") or Instance.new("BoolValue", character)

	-- Only create the BoolValue if it doesn't exist
	if not character:FindFirstChild("Stunned") then
		stunnedValue.Name = "Stunned"
	end

	-- If the humanoid is already stunned, update the stun duration
	if stunnedPlayers[humanoid] then
		-- Update the stun duration to the latest one
		stunnedPlayers[humanoid].endTime = tick() + duration
		return
	end

	-- Set the Stunned BoolValue to true and add the humanoid to the stunnedPlayers table
	stunnedValue.Value = true
	stunnedPlayers[humanoid] = {
		endTime = tick() + duration,  -- Store the time when stun should end
		stunBillboard = script.StunnedBillBoard:Clone() -- Store the stun billboard for cleanup
	}

	-- Parent the stun billboard to the humanoid's head
	local stun = stunnedPlayers[humanoid].stunBillboard
	stun.Parent = humanoid.Parent.Head
	Debris:AddItem(stun, duration)  -- Automatically remove after duration

	-- Disable the humanoid's abilities
	humanoid.WalkSpeed = 0
	humanoid.JumpPower = 0  -- Set jump height to 0
	humanoid.JumpHeight = 0

	-- Connection to handle humanoid death
	local diedConnection
	diedConnection = humanoid.Died:Connect(function()
		-- Clean up stun state on death
		stunnedValue.Value = false
		stunnedPlayers[humanoid] = nil
		-- Clean up the connection to prevent memory leaks
		diedConnection:Disconnect()
	end)

	-- Stun handler loop to manage the duration and keep updating
	task.spawn(function()
		while stunnedPlayers[humanoid] and tick() < stunnedPlayers[humanoid].endTime do
			task.wait(0.1) -- Small wait to avoid tight looping
		end

		-- Ensure humanoid is still valid before re-enabling abilities
		if humanoid and humanoid.Parent then
			humanoid.WalkSpeed = 16  -- Default walk speed
			humanoid.JumpPower = 50   -- Default jump power
			humanoid.JumpHeight = 7.2 -- Default jump height
		end

		-- Set the Stunned BoolValue to false and remove from stunned players
		stunnedValue.Value = false
		stunnedPlayers[humanoid] = nil

		-- Clean up the connection if it wasn't triggered
		if diedConnection then
			diedConnection:Disconnect()
		end
	end)
end

return StunHandlerV2

CREDITS TO CHATGPT LOL
Like I tried a lot of different methods, first only being replacing os.clock as It was accurate etc.
I moved module into the Server Script Service, etc etc

In the end I got fed up and just relied to ChatGPT to just make a whole new stun module.

The bool value named “Stunned” in my player character is the indicated whether if I could use any moves depending on the value. If true then it means I am stunned thus I can’t use any move. And the Billboard is a indicator of being stunned. So it can be removed, its not really needed.

Love the fact I replied and solved my own problem after like almost an year. :joy:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.