Cant create multiple threads in module function

Currently creating a StateHandler that essentially adds and removes “tags” associated with a player. For instance, when stunned, the StateHandler will add a “tag” to a dictionary under the player’s name.

i.e

[Player] = {
    Client = {
        Stunned = 1
    }
    Server = {}
    }

Keep in mind that you can be stunned multiple times, therefore it’s important that I can easily add/remove the number (frequency) associated with every tag.

However, I should also be able to add a tag for a certain amount of time before it gets automatically removed. This is where my problem is though, for some reason I can’t create multiple threads inside of the function, therefore it’s impossible for me to remove multiple tags that have a set duration using task.spawn/coroutine.wrap.

function StateHandler.AddClientState(EntityName, StateName, Duration)
	if not StateHandler.ActiveEntries.Client[EntityName] then
		warn("Could not find active client state entry for " .. EntityName)
		return
	end

	if not StateHandler.ActiveEntries.Client[EntityName][StateName] then
		StateHandler.ActiveEntries.Client[EntityName][StateName] = 1

		if Duration then
			task.spawn(function()
				print("Waiting")
				task.wait(Duration)
				print("Removing")

				StateHandler.RemoveClientState(EntityName, StateName)
			end)

		end
	else
		StateHandler.ActiveEntries.Client[EntityName][StateName] += 1
	end
end

function StateHandler.RemoveClientState(EntityName, StateName)	
	if not StateHandler.ActiveEntries.Client[EntityName] then
		warn("Could not find active client state entry for " .. EntityName)
		return
	end
	
	if StateHandler.ActiveEntries.Client[EntityName][StateName] then
		StateHandler.ActiveEntries.Client[EntityName][StateName] -= 1

		if StateHandler.ActiveEntries.Client[EntityName][StateName] <= 0 then
			StateHandler.ActiveEntries.Client[EntityName][StateName] = nil
		end
	end
end

Output:
image

In this case, I added the tag (Client1) twice to the dictionary for a duration of 3 seconds, the first time works as expected, however the second time I add the client state (line 3), it doesn’t create a new thread. (It doesn’t print out “Waiting” like it did the first time). Then once I display the entries, I see that it only removed it the first time, and never again after that.

I’d really appreciate any help with this, thanks.

The first time it works, but the second time fails because of this line.

When you try to add another tag or state the second time, this will evaluate as false as there is already an entry before the second one.

Which leads us to this line. I assume that you want this second tag to be removed with its own duration. Hence to solve this, you would have to copy the function from task.spawn() again.

Alternatively, using task.delay() is easier since you do not necessarily have to add a yielding function. I have changed some parts of your code and added a local function which handles your state removal.

local function YieldRemoveState(EntityName, StateName, Duration)
	task.delay(Duration, StateHandler.RemoveClientState, EntityName, StateName)
end

function StateHandler.AddClientState(EntityName, StateName, Duration)
	if not StateHandler.ActiveEntries.Client[EntityName] then
		warn("Could not find active client state entry for " .. EntityName)
		return
	end

	if not StateHandler.ActiveEntries.Client[EntityName][StateName] then
		StateHandler.ActiveEntries.Client[EntityName][StateName] = 1
	else
		StateHandler.ActiveEntries.Client[EntityName][StateName] += 1
	end
	
	if Duration then
		YieldRemoveState(EntityName, StateName, Duration)
	end
end

I hope this helps!

1 Like

Oh my god, I can’t believe I missed that. Thank you so much man, I really appreciate it.

As for using task.delay however, wouldn’t that yield the entire script unless you created a new thread first, or am I mistaken? For example, if I create a new stunned tag with the duration of 5, and then another tag with a duration of 3, wouldn’t it yield for an entire 8 seconds before the second tag is removed?

No, there’s a reason why it has the name task. task library has functions which creates threads and has the ability to yield those threads, and at the same time, not to disrupt or yield the main thread. I had tested your code in studio and it worked perfectly fine, so no need to worry.

1 Like

I gotcha, thanks for clearing that up for me.

And once again, I appreciate the help. :+1:

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