I need a more efficient way to use bindable events for tools

There are 2 scripts that I want to focus on.

The first one is a tool that launches a fireball.

local debounce = false
local rS = game:GetService("ReplicatedStorage")
local bindableEvent = rS.SaurGlobal
local count = 10
local tool = script.Parent

tool.Activated:Connect(function()
	if debounce == false then
		debounce = true
		spawn(function()
			bindableEvent:Fire(1)
			repeat
			local GB = script.Parent.STAFF:Clone()
			GB.Parent = workspace
			GB["peak staff"]:WaitForChild("Script").Disabled = false
			GB:SetPrimaryPartCFrame(GB:GetPrimaryPartCFrame() * CFrame.new(Vector3.new(0,0,math.random(-90,90))))
			task.wait(0.05)
			count -= 1
			until count == 0
			task.wait(3)
			debounce = false
			count = 10
		end)
	end
end)

local function GLOBALCOOLDOWN()
	debounce = true
	tool.Name = "GLOBAL CD"
	task.wait(2)
	tool.Name = "Înūviar."
	debounce = false
end

bindableEvent.Event:Connect(GLOBALCOOLDOWN,2)

The 2nd one.

local debounce = false
local rS = game:GetService("ReplicatedStorage")
local remoteEvent = rS.SaurDialogue
local bindableEvent = rS.SaurGlobal
local tool = script.Parent

tool.Activated:Connect(function()
	if debounce == false then
		debounce = true
		spawn(function()
			bindableEvent:Fire(2)
			local GB = script.Parent.STAFF:Clone()
			GB.Parent = workspace
			GB["peak staff"]:WaitForChild("Script").Disabled = false
			remoteEvent:FireAllClients()
			task.wait(15)
			debounce = false
		end)
	end
end)

local function GLOBALCOOLDOWN()
	debounce = true
	tool.Name = "GLOBAL CD"
	task.wait(4)
	tool.Name = "Æzøhr."
	debounce = false
end

bindableEvent.Event:Connect(GLOBALCOOLDOWN,1)

Both of them do work however here’s the issue, when I use either of the tools the global cooldown instantly gets activated for both tools. This is not something I expected and I do not know how to solve this problem without creating more bindable events, which is extremely repetitive. When I use one of the tools, Înūviar. or the first script, the tool continously does it repeatably and it has to do something with the bindable event, which I do not know how to pass some values for the function that does the global cooldown to know what’s being passed so it disables the tool until the cooldown is over.

For a shorter explanation, when I use any of the tools, the global cooldown function is instantly activated for both, which is something I do not want (in summary I want it so that only one or the other tools later to receive the global cooldown and not the tool I’m currently using).

The tool’s global cooldown system does work, but it’s causing some side effects that I don’t know how to solve and some results I don’t want. If there is anybody that can help, please do. I’d greatly appreciate the help received to help solve my problem with these scripts!

Okay let’s break this down, why do you need a global cooldown in the first place?

There are 2 tools that are connected to each other, what I call a staff. The reason for the global cooldown is to balance the gameplay of people spamming attacks left and right (for example the player could simply spam the first script for the tool called Înūviar. and then use Æzøhr. to create a near undodgable mess with near unavoidable damage) which is why I want to implement a global cooldown for the tools. I also need the system as the 2nd script’s tool Æzøhr. has a remoteEvent firing to a dialogue system and there are other tools that I plan to make that will have the dialogue system as well.

Okay so If I’m understanding correctly the global cooldown is basically so a player can’t use one tool and then use another tool immediately after?

Yes. That’s the purpose of the global cooldown. I tried to implement it but there are some side effects that are unintended, such as me being able to use one of the tools, Înūviar. (1st script) even when it’s during “global cooldown” and instantly being able to use Æzøhr. (2nd script) the moment it goes off cooldown. Not to mention I do not know how to make it so that only one other tool or more receives it while the one I’m using doesn’t receive the global cooldown.

Honestly I think you should scrap the bindable event and use a module

Alright so I think the easiest way to do this would be when a player uses a tool, have a variable in a module called like lastUseTime, and it can initially be nil, and then set it to somethin like tick(), and let’s say the player switches to another weapon and uses that; before we let them we can check if tick() - module.lastUseTime is greater than a certain number

I feel like this approach cuts down complexity and is pretty straight forward!

Do I create a moduleScript for it or is it built in the script?

Well you have different tools in different scripts I presume, so youll need to require the module in all of them to have access to the lastUseTime variable

Yes, they are in different scripts but do I have to create a modulescript for all of the tools or is built in the serverscripts? That’s the one thing I’m confused about.

You would only need 1 module script

It would look something like this

-- Module
local module = {}

module.useDelayInBetweenTools = .35
module.lastUseTime = nil

reutrn module

------------------------------//

-- Fireball Script
local module = require("MODULE_PATH")

local debounce = false
local rS = game:GetService("ReplicatedStorage")
local bindableEvent = rS.SaurGlobal
local count = 10
local tool = script.Parent

tool.Activated:Connect(function()
	if debounce == false and (tick() - module.lastUseTime) > module.useDelayInBetweenTools then
        module.lastUseTime = tick()
		debounce = true
		spawn(function()
			bindableEvent:Fire(1)
			repeat
			local GB = script.Parent.STAFF:Clone()
			GB.Parent = workspace
			GB["peak staff"]:WaitForChild("Script").Disabled = false
			GB:SetPrimaryPartCFrame(GB:GetPrimaryPartCFrame() * CFrame.new(Vector3.new(0,0,math.random(-90,90))))
			task.wait(0.05)
			count -= 1
			until count == 0
			task.wait(3)
			debounce = false
			count = 10
		end)
	end
end)

I’m confused now. What am I supposed to do? There’s not a lot I know what to do and I have absolutely 0 experience with modulescripts besides knowing how to whitelist players in modulescripts.

It doesnt matter module scripts are basically used so you can access methods and variables across multiples scripts, with this in mind, we can access the lastTimeUsed whenever a tool is activated

So where should I put the moduleScript? I already encountered a error, that being this.

Players.borenreef.Backpack.Înūviar..DupeScript:12: attempt to perform arithmetic (sub) on number and nil 

Where do I put the moduleScript? Inside the tools, players?

I feel like you might still be a beginner but thats alright, so just put it in ReplicatedStorage, and then you require its path from there

So what’s causing the error for line 12? Players.borenreef.Backpack.Înūviar..DupeScript:12: attempt to perform arithmetic (sub) on number and nil I did what you said, putting the moduleScript in replicatedstorage for now. However I do not know what’s causing this error whatsoever.

Set lastUseTime to 0 in the module

Now it works. So can I essentially put the modulescript into any other tool and it would not fire as long as its under global cooldown?

No your keeping the module script where it’s at in ReplicatedStorage, so that all the tool scripts you need can access it, then inside all of them youd be requiring the module and doing the same checks I showed you and then of course setting lastUseTime to tick() when it has passed the condition

So yeah if you dont have that check using lastUseTime from the module then that specific tool will be able to be fired even if youve fired a tool immediately before

That was some poor wording from me, my bad. I meant to say that if I did the same thing, requiring moduleScript, etc from your edits of my fireball script it would work.
Well the global cooldown script works, I think I learned something pretty valuable. Thank you for your help!

1 Like

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