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
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
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.
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)
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)
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
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)
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.
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.
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
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.