Im trying to make a script that will save the position of players tools in their hot bar for selecting tools. but i am encountering issues here are my scripts:
Localscript in StarterPlayerScripts:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local mouse = Players.LocalPlayer:GetMouse()
local player = Players.LocalPlayer
local fetchFunc = ReplicatedStorage:WaitForChild("FetchPlayerData")
local placeEvent= ReplicatedStorage:WaitForChild("PlaceToolEvent")
local ServerStorage = game:GetService("ServerStorage")
local toolsFolder = ServerStorage:WaitForChild("Tools")
-- Ghost‑placement setup
local function setupTool(tool)
if not tool:IsA("Tool") or not tool:FindFirstChild("Handle") then return end
local ghost, placing
tool.Equipped:Connect(function()
placing = true
ghost = tool:Clone()
for _, p in ipairs(ghost:GetDescendants()) do
if p:IsA("BasePart") then
p.Transparency = 0.5
p.CanCollide = false
end
end
ghost.Parent = workspace
-- follow mouse:
local conn
conn = mouse.Move:Connect(function()
if placing and ghost.PrimaryPart then
ghost.PrimaryPart.CFrame = CFrame.new(mouse.Hit.p)
else
conn:Disconnect()
end
end)
end)
tool.Activated:Connect(function()
if placing then
placing = false
if ghost then ghost:Destroy() end
local cf = tool.Handle.CFrame
local comps = { cf:GetComponents() } -- 12‑number array
placeEvent:FireServer(tool.Name, comps)
tool:Destroy()
end
end)
tool.Unequipped:Connect(function()
placing = false
if ghost then ghost:Destroy() end
end)
end
-- Watch for any new tools in Backpack or Character
player.Backpack.ChildAdded:Connect(setupTool)
player.CharacterAdded:Connect(function(char)
char.ChildAdded:Connect(setupTool)
end)
-- On join, fetch saved counts & placements
local counts, placements = fetchFunc:InvokeServer()
-- 1) Clear existing “known” tools in Backpack+Character
for _, t in ipairs(player.Backpack:GetChildren()) do
if t:IsA("Tool") and toolsFolder:FindFirstChild(t.Name) then
t:Destroy()
end
end
local char = player.Character or player.CharacterAdded:Wait()
for _, t in ipairs(char:GetChildren()) do
if t:IsA("Tool") and toolsFolder:FindFirstChild(t.Name) then
t:Destroy()
end
end
-- 2) Spawn the autosaved counts into the Backpack
for toolName, count in pairs(counts) do
local tpl = toolsFolder:FindFirstChild(toolName)
if tpl then
for i = 1, count do
tpl:Clone().Parent = player.Backpack
end
end
end
-- 3) Spawn the world‑placed tools at their saved CFrames
for _, entry in ipairs(placements) do
local tpl = toolsFolder:FindFirstChild(entry.toolName)
if tpl and tpl.PrimaryPart then
local m = tpl:Clone()
m:SetPrimaryPartCFrame(CFrame.new(unpack(entry.cf)))
m.Parent = workspace
end
end
-- StarterPlayerScripts/ToolPersistenceClient.lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local mouse = Players.LocalPlayer:GetMouse()
local player = Players.LocalPlayer
local fetchFunc = ReplicatedStorage:WaitForChild("FetchPlayerData")
local placeEvent= ReplicatedStorage:WaitForChild("PlaceToolEvent")
local ServerStorage = game:GetService("ServerStorage")
local toolsFolder = ServerStorage:WaitForChild("Tools")
-- Ghost‑placement setup
local function setupTool(tool)
if not tool:IsA("Tool") or not tool:FindFirstChild("Handle") then return end
local ghost, placing
tool.Equipped:Connect(function()
placing = true
ghost = tool:Clone()
for _, p in ipairs(ghost:GetDescendants()) do
if p:IsA("BasePart") then
p.Transparency = 0.5
p.CanCollide = false
end
end
ghost.Parent = workspace
-- follow mouse:
local conn
conn = mouse.Move:Connect(function()
if placing and ghost.PrimaryPart then
ghost.PrimaryPart.CFrame = CFrame.new(mouse.Hit.p)
else
conn:Disconnect()
end
end)
end)
tool.Activated:Connect(function()
if placing then
placing = false
if ghost then ghost:Destroy() end
local cf = tool.Handle.CFrame
local comps = { cf:GetComponents() } -- 12‑number array
placeEvent:FireServer(tool.Name, comps)
tool:Destroy()
end
end)
tool.Unequipped:Connect(function()
placing = false
if ghost then ghost:Destroy() end
end)
end
-- Watch for any new tools in Backpack or Character
player.Backpack.ChildAdded:Connect(setupTool)
player.CharacterAdded:Connect(function(char)
char.ChildAdded:Connect(setupTool)
end)
-- On join, fetch saved counts & placements
local counts, placements = fetchFunc:InvokeServer()
-- 1) Clear existing “known” tools in Backpack+Character
for _, t in ipairs(player.Backpack:GetChildren()) do
if t:IsA("Tool") and toolsFolder:FindFirstChild(t.Name) then
t:Destroy()
end
end
local char = player.Character or player.CharacterAdded:Wait()
for _, t in ipairs(char:GetChildren()) do
if t:IsA("Tool") and toolsFolder:FindFirstChild(t.Name) then
t:Destroy()
end
end
-- 2) Spawn the autosaved counts into the Backpack
for toolName, count in pairs(counts) do
local tpl = toolsFolder:FindFirstChild(toolName)
if tpl then
for i = 1, count do
tpl:Clone().Parent = player.Backpack
end
end
end
-- 3) Spawn the world‑placed tools at their saved CFrames
for _, entry in ipairs(placements) do
local tpl = toolsFolder:FindFirstChild(entry.toolName)
if tpl and tpl.PrimaryPart then
local m = tpl:Clone()
m:SetPrimaryPartCFrame(CFrame.new(unpack(entry.cf)))
m.Parent = workspace
end
end
ServerScriptService:
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local RS = game:GetService("ReplicatedStorage")
-- Remotes (all RemoteEvents)
local SaveHotbarEvent = RS:WaitForChild("SaveHotbarEvent") -- client→server
local RequestHotbarEvent = RS:WaitForChild("RequestHotbarEvent") -- client→server
local HotbarOrderEvent = RS:WaitForChild("HotbarOrderEvent") -- server→client
local store = DataStoreService:GetDataStore("PlayerHotbarOrder")
local cache = {} -- [ userId ] = { [slot]=toolName, … }
-- Load cache on join
Players.PlayerAdded:Connect(function(plr)
local ok, data = pcall(function()
return store:GetAsync(tostring(plr.UserId))
end)
cache[plr.UserId] = (ok and type(data)=="table") and data or {}
end)
-- Save cache on leave
Players.PlayerRemoving:Connect(function(plr)
pcall(function()
store:SetAsync(tostring(plr.UserId), cache[plr.UserId])
end)
cache[plr.UserId] = nil
end)
-- Client tells us “slot X = toolName”
SaveHotbarEvent.OnServerEvent = function(plr, slotIndex, toolName)
if type(slotIndex)=="number" and type(toolName)=="string" then
cache[plr.UserId][slotIndex] = toolName
end
end
-- Client requests their saved hotbar
RequestHotbarEvent.OnServerEvent = function(plr)
-- send them their table (or {} if none)
HotbarOrderEvent:FireClient(plr, cache[plr.UserId] or {})
end