Need help with remote event not continuing the process, even when it's "told to stop"

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("Handto")

local activeTransfers = {}  -- Store active transfers for each player

remoteEvent.OnServerEvent:Connect(function(player, targetPlayer, a)
	local sourcePlayer = player
	local targetCharacter = targetPlayer
	local sourceCharacter = sourcePlayer.Character
	print(a)
	if not targetCharacter or not sourceCharacter then
		return
	end

	if a == "1" then
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = true
		remoteEvent:FireClient(player, "Ready")

		local function giveTool(tool)
			local toolClone = tool:Clone()
			toolClone.Parent = targetCharacter
			tool.Parent = nil
		end

		while activeTransfers[transferKey] do
			wait(0.5)
			local nextTool = sourceCharacter:FindFirstChildOfClass("Tool")
			if nextTool then
				giveTool(nextTool)
			end
		end

		-- Cleanup after loop ends
		activeTransfers[transferKey] = nil
		return
	elseif a == "2" then
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = false
		return
	else
		return
	end
end)

it’s goal is to give every next tool to the target player until “2” comes from the same player, but even when “2” is sent, it doesn’t work? I’m not sure what’s wrong with it.

Could it potentially be the

while activeTransfers[transferKey] do
			wait(0.5)
			local nextTool = sourceCharacter:FindFirstChildOfClass("Tool")
			if nextTool then
				giveTool(nextTool)
			end
		end

Blocking the script from proceeding?

The issue isn’t with handing the tools, as the point is to non-stop adding tools to the target player’s inventory until “2” is called.

2 should be called, but it’s not “stopping” the loop where adds tools.

The loop basically is

When tool added to player's hand
put it in target player's backpack

when “2” is called, it should break the loop.

2 Likes

The tags got messed up so bad, I have NO clue why they did that. Let me fix them

1 Like

no

if a player sends “2” to that remote event it will break the loop so thats what probably blocks the script from even giving that tool

that player has too fast internet connection and it fires the remote faster than the loop could ever start which immediately breaks the loop because it sets activeTransfers[transferKey] to false

am i right?

1 Like

A bit unrelated but there’s a memory leak in that script. Consider a scenario where player sends 1 and disconnects before having a chance to send 2. In that case, activeTransfers[disconnectedPlayer.UserId] will be true forever, and over time that table will only grow in size.

EDIT: same thing with the character inside the loop potentially being null and the possibility of the function throwing. Solution is to introduce a check each loop iteration, break the loop and nullify the active transfer in case the check fails.

1 Like

Aside from what I mentioned above the script loops ok. Can we see how you fire the remote events on the client? The problem might be lurking there.

1 Like

ok lets fix that :+1:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("Handto")

local activeTransfers = {}  -- Store active transfers for each player
game:GetService("Players").PlayerRemoving:Connect(function(plr)
        if activeTransfers[tostring(plr.UserId)] then
              activeTransfers[tostring(plr.UserId)]=nil
        end
end)
remoteEvent.OnServerEvent:Connect(function(player, targetPlayer, a)
	local sourcePlayer = player
	local targetCharacter = targetPlayer
	local sourceCharacter = sourcePlayer.Character
	print(a)
	if not targetCharacter or not sourceCharacter then
		return
	end

	if a == "1" then
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = true
		remoteEvent:FireClient(player, "Ready")

		local function giveTool(tool)
			local toolClone = tool:Clone()
			toolClone.Parent = targetCharacter
			tool.Parent = nil
		end

		while activeTransfers[transferKey] do
			wait(0.5)
			local nextTool = sourceCharacter:FindFirstChildOfClass("Tool")
			if nextTool then
				giveTool(nextTool)
			end
		end

		-- Cleanup after loop ends
		activeTransfers[transferKey] = nil
		return
	elseif a == "2" then
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = false
		return
	else
		return
	end
end)
2 Likes

Sure thing!

This sends in “2”

script.Parent.MouseButton1Click:Connect(function()
	script.Parent.Parent.Visible = false
	game:GetService("ReplicatedStorage"):WaitForChild("Handto"):FireServer(nil,"2")
end)

game:GetService("ReplicatedStorage"):WaitForChild("Handto").OnClientEvent:Connect(function(m)
	print(m)
	if m == "Ready" then
		script.Parent.Parent.Visible = true
	end
end)

and this sends in “1”

local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local active = false
local players = game:GetService("Players")
local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist

script.Parent.MouseButton1Click:Connect(function()
	active = true
	task.wait(0.2)
	
	Mouse.Button1Down:Connect(function()
		print("a")
		local raycastResult = workspace:Raycast(mouse.UnitRay.Origin, mouse.UnitRay.Direction * 250, raycastParams)

		if raycastResult then
			local raycastHit = raycastResult.Instance
			if raycastHit then
				local raycastModel = raycastHit:FindFirstAncestorOfClass("Model")
				if raycastModel then
					print("e")
					game:GetService("ReplicatedStorage").Handto:FireServer(game.Players:GetPlayerFromCharacter(raycastModel), "1")
					active = false
				end
			end
		end
	end)
end)

1 Like

oh i get it now

what if that player is not currently holding the tool? guess what the tool is then parented under Player.Backpack thats probably why it doesnt give the tool to other player :thinking:

1 Like

The issue isn’t with handing the tools, as the point is to non-stop adding tools to the target player’s inventory until “2” is called.

2 should be called, but it’s not “stopping” the loop where adds tools.

The loop basically is

When tool added to player's hand
put it in target player's backpack

when “2” is called, it should break the loop.

1 Like

so maybe remove the loop and then it wont non-stop add the tools???

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("Handto")

local activeTransfers = {}  -- Store active transfers for each player
game:GetService("Players").PlayerRemoving:Connect(function(plr)
        if activeTransfers[tostring(plr.UserId)] then
              activeTransfers[tostring(plr.UserId)]=nil
        end
end)
remoteEvent.OnServerEvent:Connect(function(player, targetPlayer, a)
	local sourcePlayer = player
	local targetCharacter = targetPlayer
	local sourceCharacter = sourcePlayer.Character
	print(a)
	if not targetCharacter or not sourceCharacter then
		return
	end

	if a == "1" then
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = true
		remoteEvent:FireClient(player, "Ready")

		local function giveTool(tool)
			local toolClone = tool:Clone()
			toolClone.Parent = targetPlayer.Backpack
			tool.Parent = nil
		end

		
			local nextTool = sourceCharacter:FindFirstChildOfClass("Tool")
			if nextTool then
				giveTool(nextTool)
			end

		-- Cleanup after loop ends
		activeTransfers[transferKey] = nil
		return
	elseif a == "2" then
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = false
		return
	else
		return
	end
end)
1 Like

The point so it does non-stop add tools…

It’s supposed to continue doing so until “2” is sent

1 Like

I’m assuming that print(a) does print 2 in the output at some point? Assuming that is actually happening, it is probably because the wait(0.5) is at the start of your While loop. This means that it checks if the activeTransfers[transferKey] == true, then waits half a second, then adds the tool WITHOUT checking the key again. Simply move the wait(0.5) to the end of the loop so that the check happens IMMEDIATELY before adding the tool, otherwise there is half a second of room for error. If you desire the wait at the start of the loop, then just add another check after that to make sure the transferKey is still true.

Edit; also, side note, use task.wait instead of wait. It’s more accurate, accounting for actual time passed.

2 Likes

I’ll make the suggested changes, but I’ve isolated the error.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("Handto")

local activeTransfers = {}  -- Store active transfers for each player

remoteEvent.OnServerEvent:Connect(function(player, targetPlayer, a)
	local sourcePlayer = player
	local targetCharacter = targetPlayer
	local sourceCharacter = sourcePlayer.Character
	print(a)
	if not targetCharacter or not sourceCharacter then
		return
	end

	if a == "1" then
		print("One sent in.")
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = true
		remoteEvent:FireClient(player, "Ready")

		local function giveTool(tool)
			local toolClone = tool:Clone()
			toolClone.Parent = targetCharacter
			tool.Parent = nil
		end

		while activeTransfers[transferKey] do
			wait(0.5)
			print(activeTransfers[transferKey])
			local nextTool = sourceCharacter:FindFirstChildOfClass("Tool")
			if nextTool then
				giveTool(nextTool)
			end
		end

		-- Cleanup after loop ends
		activeTransfers[transferKey] = nil
		return
	elseif a == "2" then
		print("Two sent in.")
		local transferKey = tostring(player.UserId)
		activeTransfers[transferKey] = false
		print(activeTransfers[transferKey])
		return
	else
		return
	end
end)

Even when activeTransfers[transferKey] = false clearly tells it to have that key be false, it doesn’t anyway, which doesn’t make sense to me. I can tell this because the print(activeTransfers[transferKey]) said that it was still true.

You are printing that on more than one line. How do you know which line printed true? You can make it more disnguishable by adding different identifiers to each print, e.g.

print(tostring(“1 “ .. activeTransfers[transferKey]))

And on the other print change the number so you know where it came from.

Edit; I see it says “two sent it in”, ig you confirmed that printed before the bool printed true? If so that is odd.

Edit; please share the output so I know what printed exactly.

1 Like

You can click it in the output and it puts you to the line that it came from.

Looks like the whole issue was

	if not targetCharacter or not sourceCharacter then
		return
	end

The part that was supposed to tell it to “shut-up” was shutting itself up because I sent in a nil value just so I don’t get a missing argument error

script.Parent.MouseButton1Click:Connect(function()
	script.Parent.Parent.Visible = false
	game:GetService("ReplicatedStorage"):WaitForChild("Handto"):FireServer(nil,"2")
end)
1 Like

I did the rubber duck method of debugging. You take a rubber duck or an inanimate object, or even a friend and you try to explain the code to them. Whether or not they understand is not the point, but it’s where you’re able to point out where you went wrong when you start explaining it.

Instead of a rubber duck, I pretended I was talking to my FBI agent through my phone.

1 Like

Also, there were some bad practices others pointed out to me.

1 Like

Great! If the issue is resolved please mark a solution for others to find more quickly. I’m glad you figured it out!

Edit; just saw the solution marked, thanks!

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