Parameter not being passed properly

This code is for a tool saving system. When you click its inventory slot, it deletes the tool and the following code is supposed to save it to the server:

LocalScript in tool:

local Tool = script.Parent
local Dupe
script.Parent.Destroying:Connect(function()
    game.ReplicatedStorage.Tools[Tool.Name]:Destroy()
    Dupe = script.Parent:Clone()
    print(Dupe)
    game.ReplicatedStorage.Tools.SaveTool:FireServer(Dupe)
end)

ServerScipt:

game.ReplicatedStorage.Tools.SaveTool.OnServerEvent:Connect(function(player, Dupe)
	print(player)
	print(Dupe)
	Dupe.Parent = game.ReplicatedStorage.Tools
end)

print(Dupe) on the server prints nil, but on the client prints Bucket. is it a parameter issue, or something else?

3 Likes

Dupe is nil on the server because objects created on the client are not registered by the server, which is awesome or else exploiters would be able to spawn Instances for everyone in the game and ruin it.

1 Like

What could I do then? I don’t think there’s a way to get tools in the player from the server?

If the Tool wasn’t created or added to the Player’s character or Backpack locally, the server will be able to access it. If equipped, the Tool is in the Player’s character; if not equipped, it is in the Player’s Backpack. Tools cloned from StarterPack, which are cloned and parented automatically, can be detected by the server.

So should I move the tools I have to StarterPack? Or does the equiping code need to be chaged? That’s all done in a LocalScript via an ImageButton
If needed, this is the script used to equip an item:

local Tool
local Item
script.Parent.MouseButton1Click:Connect(function(player)
	if script.Parent.Parent:FindFirstChild("Equipable") and script.Parent.Parent.Equipable.Value == true and game.ReplicatedStorage.ItemEquipped.Value == false then
		game.ReplicatedStorage.ItemEquipped.Value = true
		script.Parent.Parent.Equipable.Value = false
		
		Item = script.Parent.Parent.ItemName.Value
		Tool = game.ReplicatedStorage.Tools[Item]:Clone()
		Tool.Parent = game.Players.LocalPlayer.Character
		Tool.Parent = game.Players.LocalPlayer.Backpack
		Tool.Parent = game.Players.LocalPlayer.Character
		
		script.Parent.Parent.BackgroundColor3 = Color3.new(0.14902, 1, 0)
		
		script.Parent.Parent.Parent.Parent.Visible = false
	else if script.Parent.Parent:FindFirstChild("Equipable") and script.Parent.Parent.Equipable.Value == false and game.ReplicatedStorage.ItemEquipped.Value == true then
			script.Parent.Parent.Equipable.Value = true
			game.ReplicatedStorage.ItemEquipped.Value = false
			Tool:Destroy()

			Tool = nil
			Item = nil
			script.Parent.Parent.BackgroundColor3 = Color3.new(0,0,0)
			script.Parent.Parent.Parent.Parent.Visible = false
		end
	end
end)

No, you do not need to put the Tool(s) inside StarterPack.

Instead of creating the Tool locally, fire a RemoteEvent or invoke a RemoteFunction to tell the server to give you the Tool. As an argument, you can pass Item so that the server knows the Name of the Tool you want.

Using the remotes, you can also fire to or invoke the server when you want to unequip the Tool. On the server, you should do checks such as

  • making sure the Player doesn’t already have a Tool when it’s being requested,
  • and validating that the Player has a Tool when they want to “unequip” it.

These checks are unnecessary if the Player possessing or not possessing these Tools will not affect the server.

1 Like

Would this work?

Item = script.Parent.Parent.ItemName.Value
		game.ReplicatedStorage.Tools.EquipTool:FireServer(Item)
local Tool
game.ReplicatedStorage.Tools.EquipTool.OnServerEvent:Connect(function(player,Item)
	Tool = game.ReplicatedStorage.Tools[Item]:Clone()
	Tool.Parent = game.Players.LocalPlayer.Character
	Tool.Parent = game.Players.LocalPlayer.Backpack
	Tool.Parent = game.Players.LocalPlayer.Character
end)

Players.LocalPlayer is meant for the client only, so this will return nil on the server. You can just use the built-in player(: Player) argument passed to the RemoteEvent.OnServerEvent event connection. Then it shall work.

1 Like

So just use player.Character, player.Backpack, etc.?

Yes.

I need a certain amount of characters to post this.

Alright I’ll try that and see if it works

I forgot to mention that you don’t need all of those Tool.Parent statements, just one: Tool.Parent = player.Character or Tool.Parent = player.Backpack. If you want the Tool to spawn with the Player, you can create another clone and parent that duplicate to player.StarterGear.

I’ve tried doing that in the past. It did that because it puts the tool in but doesn’t equip it, so that’s why it’s like that

I also have a script that modifies a part (the contents) in the bucket. Material, color, transparency, etc. Do I need to change this to be server-done as well?

A good rule of thumb for when to do stuff in the server and when to do stuff on the client is:

  • Do you plan to replicate to some or all clients? If so, use the server.
  • Otherwise, use the client.

The goal in mind is to take the bucket in hand and put it on a rod on a campfire so it can cook bread dough inside the bucket.

As @matheus1109110 said, unless you want those properties to be registered by the server, you can change them on the client. If it’s not necessary or useful, you do not have to update those properties on the server.

If you ever want some action or visual to be replicated to all clients like effects or tweening (events that don’t need to be seen by the server), in order to take work off of the server’s back, you can call FireAllClients() on a RemoteEvent to tell the Players to do the work locally instead of creating Instances and changing their properties on the server. This is a basic explanation.

I think it might have to be done on the server, because I want the contents you add to stay when you unequip and re-equip the bucket. I might be able to do it by taking the StringValue containing the item’s name, pass it to the server, and match the name with a set of tables containing data for each different type of state the content can be in. Just this with a few extra steps:

local RS = game.ReplicatedStorage
local Content = script.Parent.Handle.Content
local BucketItem = script.Parent:WaitForChild("BucketItem")
local ContentInfo = {
	["Flour"] = {
		Material = Enum.Material.Snow,
		Color = Color3.new(0.960784, 1, 0.862745),
		TP = 0
	}
}
RS.Tools.UpdateBucketContents.Event:Connect(function(Item)
	local Info = ContentInfo[Item]
	if Item == "Flour" and BucketItem.Value == "Water" then
		script.Parent.BucketItem.Value = "BreadDough"
		Content.Transparency = 0
		Content.Material = Enum.Material.Mud
		Content.Color = Color3.new(0.92549, 0.682353, 0.435294)
	else
		BucketItem.Value = Item
		Content.Material = Info.Material
		Content.Color = Info.Color
		Content.Transparency = Info.TP
	end
end)

Update: The whole system has now been overhauled and functions properly. Here’s the code if anyone’s interested:

LocalScript inside of inventory slot.

local Item

script.Parent.MouseButton1Click:Connect(function(player)
	if script.Parent.Parent:FindFirstChild("Equipable") and script.Parent.Parent.Equipable.Value == true and game.ReplicatedStorage.ItemEquipped.Value == false then
		game.ReplicatedStorage.ItemEquipped.Value = true
		script.Parent.Parent.Equipable.Value = false
		Item = script.Parent.Parent.ItemName.Value
		game.ReplicatedStorage.Tools.EquipTool:FireServer(Item)
		script.Parent.Parent.BackgroundColor3 = Color3.new(0.14902, 1, 0)
		
		script.Parent.Parent.Parent.Parent.Visible = false
	else if script.Parent.Parent:FindFirstChild("Equipable") and script.Parent.Parent.Equipable.Value == false and game.ReplicatedStorage.ItemEquipped.Value == true then
			script.Parent.Parent.Equipable.Value = true
			game.ReplicatedStorage.ItemEquipped.Value = false
			game.ReplicatedStorage.Tools.DestroyTool:FireServer(Item)


			Item = nil
			script.Parent.Parent.BackgroundColor3 = Color3.new(0,0,0)
			script.Parent.Parent.Parent.Parent.Visible = false
		end
	end
end)

ServerScript counterpart

local Tool
game.ReplicatedStorage.Tools.EquipTool.OnServerEvent:Connect(function(player,Item)
	Tool = game.ReplicatedStorage.Tools[Item]:Clone()
	Tool.Parent = player.Character
	Tool.Parent = player.Backpack
	Tool.Parent = player.Character
end)

game.ReplicatedStorage.Tools.DestroyTool.OnServerEvent:Connect(function(player,Item)
	local Dupe = Tool:Clone()
	Tool:Destroy()
	Tool = game.ReplicatedStorage.Tools[Item]
	Tool:Destroy()
	Dupe.Parent = game.ReplicatedStorage.Tools

	

	Tool = nil
end)

LocalScript filling up bucket with water

local Content = script.Parent.Handle.Content
local Full = script.Parent:WaitForChild("Water").Value
local Item = script.Parent.BucketItem

script.Parent.Parent.Humanoid.Swimming:Connect(function()

	if not Full then
		print(Item.Value)
		game.ReplicatedStorage.Tools.BucketEvents.WaterFilling:FireServer(Item,Content)
		Full = true
		
		end
end)

ServerScript counterpart

game.ReplicatedStorage.Tools.BucketEvents.WaterFilling.OnServerEvent:Connect(function(player,Item,Content)
	if Item.Value == "Flour" then
		Item = "BreadDough"
		Content.Transparency = 0
		Content.Material = Enum.Material.Mud
		Content.Color = Color3.new(0.92549, 0.682353, 0.435294)
	
	else
		Content.Transparency = 0.35
		Content.Material = Enum.Material.Glass
		Content.Color = Color3.new(0, 0.682353, 1)
		Item.Value = "Water"
	end
end)

LocalScript updating the visual content inside the bucket

local RS = game.ReplicatedStorage
RS.Tools.BucketEvents.GetCurrentBucketItem.Event:Connect(function(Item)
	local CurrentItem = script.Parent.BucketItem
	RS.Tools.BucketEvents.UpdateBucketContents:FireServer(Item,CurrentItem)
	
	
end)

ServerScript counterpart

local ContentInfo = {
	["Flour"] = {
		Material = Enum.Material.Snow,
		Color = Color3.new(0.960784, 1, 0.862745),
		TP = 0
	}
}

game.ReplicatedStorage.Tools.BucketEvents.UpdateBucketContents.OnServerEvent:Connect(function(player,Item,CurrentItem)
	local Content = player.Character.Bucket.Handle.Content
	local Info = ContentInfo[Item]
	if Item == "Flour" and CurrentItem.Value == "Water" then
		CurrentItem.Value = "BreadDough"
		Content.Transparency = 0
		Content.Material = Enum.Material.Mud
		Content.Color = Color3.new(0.92549, 0.682353, 0.435294)
	else
		CurrentItem.Value = Item
		Content.Material = Info.Material
		Content.Color = Info.Color
		Content.Transparency = Info.TP
	end
end)

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