Tool is not a valid member of ServerStorage "ServerStorage"

This is a local script inside StarterPlayerScripts.

local Dialog = game.Workspace["Sabway Worker"].Head.Dialog
local plr = game:GetService("Players").LocalPlayer
local tool = game.ServerStorage.Tool

Dialog.DialogChoiceSelected:Connect(function(plr,choice)
	if choice == Dialog.DialogChoice then
		local clone = tool:Clone()
		clone.Parent = plr.Character
	end
end)```
1 Like

You can’t access ServerStorage from a LocalScript.

1 Like

Oh, I will put it in ReplicatedStorage then.

1 Like

Well, it really depends on your use case here. If you give a player a tool from ReplicatedStorage in a LocalScript and then the player holds that item out, no one else will be able to see it. It might be better to use a RemoteEvent and give the sword to the player from the Server.

2 Likes

Oh, how would I do that? char limit

1 Like

In general, you could do the following:

  1. In ReplicatedStorage, add a RemoteEvent.
  2. Create a script in ServerScriptService.

Edit the code to fit the new Client-server communication.

Client Script

local Dialog = game.Workspace["Sabway Worker"].Head.Dialog
local plr = game.Players.LocalPlayer

Dialog.DialogChoiceSelected:Connect(function(player,choice)
	if choice == Dialog.DialogChoice then
        game.ReplicatedStorage.RemoteEvent:FireServer(plr)
	end
end)

Server Script

local tool = game.ServerStorage.Tool
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(plr)
    local clone = tool:Clone()
	clone.Parent = plr.Backpack
end)

This is remote events at the most basic level. You might want to change a few things for yourself but this should set you on the right track.

1 Like
--LOCAL

local players = game:GetService("Players")
local localPlayer = players.LocalPlayer
local replicated = game:GetService("ReplicatedStorage")
local remote = replicated:WaitForChild("RemoteEvent")

local worker = workspace:WaitForChild("Sabway Worker")
local workerHead = worker:WaitForChild("Head")
local workerDialog = workerHead:WaitForChild("Dialog")
local dialogChoice = workerDialog:WaitForChild("DialogChoice")

workerDialog.DialogChoiceSelected:Connect(function(player, choice)
	if player == localPlayer then
		if choice == dialogChoice then
			remote:FireServer()
		end
	end
end)
--SERVER

local server = game:GetService("ServerStorage")
local tool = server.Tool
local replicated = game:GetService("ReplicatedStorage")
local remote = replicated.RemoteEvent

remote.OnServerEvent:Connect(function(player)
	local backpack = player.Backpack
	local toolClone = tool:Clone()
	toolClone.Parent = backpack
end)

You don’t need to explicitly pass the player instance to FireServer() that’s done internally automatically. It would be worth adding WaitForChild() calls in the local script to allow for the instances it references to replicate to the client first. Finally, you need to check if the player that selected the dialog matches the local player of which the local script is executing for, otherwise every client will end up firing the server.

2 Likes