No Loop Spam with Immediate Reactivation[SOLVED][COMPLEX]

I have a problem that will probably never get fixed because ChatGPT has the equivalent IQ of 155 but who knows. Maybe someone on this forum has an IQ higher than 155. I will show you my scripts and let’s see if anyone can solve both issues simultaneously without triggering one problem or the other.

Problem with the server script? When you spam the client input, the server event loop starts firing more than once until the sound finishes instead of once until the sound finishes. If you fix that problem and force the player to wait until the sound finishes before reactivating, you won’t have immediate reactivation of the sound and it will be silent until the sound finishes. This is a gun and we don’t want players to be unable to immediately reactivate the sound but we also don’t want the sound spamming because of it. Is this possible to fix? Or did I really just create an impossible to solve problem? Let me know. Thank you!

local UserInputService = game:GetService("UserInputService") 
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaySoundEvent = script.Parent.SoundEffects
local ToolEquipped = false
local Playing = false

function Equipped()
ToolEquipped = true
end

function Unequipped()
ToolEquipped = false
end

script.Parent.Equipped:Connect(Equipped)
script.Parent.Unequipped:Connect(Unequipped)

UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end

if (input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1)
and ToolEquipped and not Playing then
Playing = true
PlaySoundEvent:FireServer(true)  -- Notify the server to start the sound loop
end
end)

UserInputService.InputEnded:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1) and Playing then
Playing = false
PlaySoundEvent:FireServer(false)  -- Notify the server to stop the sound loop
end
end)``` --End of local script inside of tool





```local ReplicatedStorage = game:GetService("ReplicatedStorage") 
local PlaySoundEvent = script.Parent.SoundEffects
local Sound = script.Parent.Handle.Shoot
local ActivePlayers = {}  -- Track players holding the input
local IsPlaying = {}  -- Track which players are currently playing sound

PlaySoundEvent.OnServerEvent:Connect(function(player, shouldPlay)
 -- If the player wants to start the sound
if shouldPlay then
 -- Only start playing the sound if it's not already playing
if not IsPlaying[player] then
IsPlaying[player] = true  -- Mark the player as "sound playing"
 -- Play the sound immediately
Sound:Play()
 -- Check every time the sound ends if it should be restarted
while IsPlaying[player] do
-- Wait until the sound finishes playing
task.wait(Sound.TimeLength)
-- If the player is still holding input, restart the sound
if IsPlaying[player] then
Sound:Play()  -- Immediately start the sound again
end
end
end
else
-- Stop playing the sound when the input ends
IsPlaying[player] = false
Sound:Stop()  -- Stop the sound immediately
end
end)``` --End of server script inside of tool
1 Like

A couple things:

  1. When it comes to coding, ChatGPT has the intelligence of someone who has recently started coding LuaU (around 6 months)
  2. Is the problem here?
while IsPlaying[player] do
-- Wait until the sound finishes playing
task.wait(Sound.TimeLength)
-- If the player is still holding input, restart the sound
if IsPlaying[player] then -- **THE PROBLEM??** Should it be if ActivePlayers[Player] ?
Sound:Play()  -- Immediately start the sound again
Sound.Ended:Wait() -- **THE PROBLEM??** The sound keeps firing because there's no wait

end
end
end
else
-- Stop playing the sound when the input ends
IsPlaying[player] = false
Sound:Stop()  -- Stop the sound immediately
end
end)``` --End of server script inside of tool

Hope this helps! :smiley:
P.S If this is the solution mark it as so

1 Like

Hey thank you very much for getting back to me. I will test this as soon as I get back from lunch

1 Like

Nope. Not the solution. Soon as you spam the input it starts spamming play() within the loop instead of it only firing once per loop

1 Like

Honestly I hope someone else can help, I’m stuck haha (though I am sick).

1 Like

Yeah it’s extremely confusing I’ve been doing lua for years and I have to say this one has me fooled because it’s like okay sure I can totally craft a debounce of like 0.2 seconds or something but that still defeats the whole point which is instant feedback. It’s the little things like this that make games great people notice all the little details that go into what you make

Just if you are curious I found a temporary solution basically just by using the looped property on the sound you can fix this by using fireserver(true) to play() the sound and fireserver(false) to stop the sound but I’d like to actually see someone find the solution simulating the looped property with actual code.

1 Like

Wow I managed to figured this out on my own. To do this without using looped property you must do it exactly like I do it.

local UserInputService = game:GetService("UserInputService") 
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaySoundEvent = script.Parent["SFX"]
local ToolEquipped = false
local Playing = false

function Equipped()
ToolEquipped = true
end

function Unequipped()
ToolEquipped = false
end

script.Parent.Equipped:Connect(Equipped)
script.Parent.Unequipped:Connect(Unequipped)

UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end

if (input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1) and ToolEquipped and not Playing then
Playing = true
PlaySoundEvent:FireServer(true)
end
end)

UserInputService.InputEnded:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1) and Playing then
Playing = false
PlaySoundEvent:FireServer(false)
end
end)``` --End of local script



local PlaySoundEvent = script.Parent["SFX"]
local Sound = script.Parent.Handle.Shoot
local Length = 5.014 --this is the length of my sound minus 0.024 to account for task.wait() *Note: Do not set this to the exact length of your sound because otherwise the task.wait() in your loop will cause it to not replay the sound

coroutine.wrap(function()
while true do
task.wait(0.01)
if Sound.TimePosition >= Length then --Detect exactly when to repeat the sound the same way Roblox's looped property knows how to. Looped repeats it when the sound reached the end of its length
Sound:Play() --Runs once instantly when the time position of the sound has reached the end
end
end
end)()

PlaySoundEvent.OnServerEvent:Connect(function(player, shouldPlay)

if shouldPlay == true then

Sound:Play() --Runs once instantly on activation

elseif shouldPlay == false then

Sound:Stop() --Runs once instantly on stopped

end

end)``` --End of server script
1 Like