You can write your topic however you want, but you need to answer these questions:
- What do you want to achieve? Keep it simple and clear!
i have a working save data script that saves and loads the player’s avatar.
- What is the issue? Include screenshots / videos if possible!
the only issue is it isnt loading the player’s accessories.
here is my code for reference:
local datastores = game:GetService("DataStoreService")
local datastore = datastores:GetDataStore("DataStore")
local players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local properties = {"HeadColor", "LeftArmColor", "LeftLegColor", "RightArmColor", "RightLegColor", "TorsoColor"}
local playersData = {}
local lastsavedChar = {}
local function serializeData(plr)
local data = playersData[plr] or {} -- check if player has data or create empty table
local character = lastsavedChar[plr] -- we reference the last saved character
local bodyColors = character["Body Colors"]
for _, property in ipairs(properties) do
data[property] = bodyColors[property].Name
end
local shirt = character:FindFirstChild("Shirt")
if shirt then
data["Shirt"] = shirt.ShirtTemplate
end
local pants = character:FindFirstChild("Pants")
if pants then
data["Pants"] = pants.PantsTemplate
end
local shirtGraphic = character:FindFirstChild("ShirtGraphic")
if shirtGraphic then
data["ShirtGraphic"] = shirtGraphic.Graphic
end
local torsoMesh = character:FindFirstChild("TorsoMesh")
if torsoMesh then
data["TorsoMesh"] = torsoMesh.MeshId
else
data["TorsoMesh"] = "" -- No TorsoMesh equipped
end
local accessories = {}
for _, accessory in ipairs(character:GetChildren()) do
if accessory:IsA("Accessory") then
local parentModel = accessory.Parent
if parentModel then
table.insert(accessories, {
["AccessoryName"] = accessory.Name,
["ParentModelName"] = parentModel.Name
})
print("Found accessory:", accessory.Name)
else
warn("Parent not found for accessory:", accessory.Name)
end
end
end
data["Accessories"] = HttpService:JSONEncode(accessories)
playersData[plr] = data -- set player's data as modified data table
return data
end
local function deserializeData(player, data)
local character = lastsavedChar[player] -- we reference the last saved character
local bodyColors = character["Body Colors"]
for _, property in ipairs(properties) do
bodyColors[property] = BrickColor.new(data[property])
end
if data["Shirt"] then
local shirt = character:FindFirstChild("Shirt")
if shirt then
shirt.ShirtTemplate = data["Shirt"]
else
shirt = Instance.new("Shirt")
shirt.Name = "Shirt"
shirt.Parent = character
shirt.ShirtTemplate = data["Shirt"]
end
end
if data["Pants"] then
local pants = character:FindFirstChild("Pants")
if pants then
pants.PantsTemplate = data["Pants"]
else
pants = Instance.new("Pants")
pants.Name = "Pants"
pants.Parent = character
pants.PantsTemplate = data["Pants"]
end
end
if data["ShirtGraphic"] then
local shirtGraphic = character:FindFirstChild("ShirtGraphic")
if shirtGraphic then
shirtGraphic.Graphic = data["ShirtGraphic"]
else
shirtGraphic = Instance.new("ShirtGraphic")
shirtGraphic.Name = "ShirtGraphic"
shirtGraphic.Parent = character
shirtGraphic.Graphic = data["ShirtGraphic"]
end
end
if data["TorsoMesh"] then
local torsoMesh = character:FindFirstChild("TorsoMesh")
if torsoMesh then
torsoMesh.MeshId = data["TorsoMesh"]
else
if data["TorsoMesh"] ~= "" then
game.ServerStorage.TorsoMesh.Parent = character
print("Created new TorsoMesh with MeshId:", data["TorsoMesh"]) -- Debug print
else
print("No TorsoMesh data found.") -- Debug print
end
end
end
local decodedAccessories = game:GetService("HttpService"):JSONDecode(data["Accessories"])
for _, accData in ipairs(decodedAccessories) do
local parentModelName = accData["ParentModelName"]
local accessoryName = accData["AccessoryName"]
local parentModel = character
if parentModel then
local accessory = parentModel:FindFirstChild(accessoryName)
if accessory and accessory:IsA("Accessory") then
accessory.Parent = parentModel
print("Added accessory:", accessory.Name, "to parent model:", parentModelName)
else
warn("Accessory not found in parent model:", accessoryName, "for player:", player.Name)
end
else
warn("Parent model not found:", parentModelName, "for player:", player.Name)
end
end
serializeData(player)
end
local function onPlayerAdded(player)
local function onCharacterLoaded(character)
if (lastsavedChar[player]) then serializeData(player) end -- we check if this is the player's 2nd+ time respawning and if so, serialize the data from the old character for the new character to reference
local data = playersData[player]
while (data == nil and player:IsDescendantOf(players)) do
data = playersData[player] -- we know that it will either be the player's data or an empty table
task.wait()
end
lastsavedChar[player] = character -- set the new character
if (next(data) ~= nil) then deserializeData(player, data) end -- we check if the dictionary is not empty and if it is not, then we deserialize that data
end
player.CharacterAdded:Connect(onCharacterLoaded)
local success, result = pcall(function()
return datastore:GetAsync("BodyColors_"..player.UserId)
end)
if success then
playersData[player] = result or {}
else
warn(result)
end
end
local function saveData(plr, attempt)
--saves the player's data and attempts 3 times if it errors
if (attempt ~= nil and attempt > 3) then return end -- reached 3 attempts: return to avoid continuing
local plrData = serializeData(plr)
if (plrData ~= nil) then
--<< Player's data exists: save the data >>--
local success, error = pcall(function()
return datastore:UpdateAsync("BodyColors_" .. plr.UserId, function(o_data) -- o_data is the previous version of the data
local prev_data = o_data or {} -- in case o_data is nil, set as default
if (plrData.Version == prev_data.Version) then -- we check if the versions of the data are the same
-- update this data to the current
plrData.Version = plrData.Version and plrData.Version + 1 or 1
return plrData
else
-- do not update data, versions do not match
return nil -- returning nil prevents it from sending a write request
end
end)
end)
if (success) then
-- player's data has been saved!
print("data key: BodyColors_" .. plr.UserId .. " has been saved!")
playersData[plr] = nil
else
-- error occured, attempt to retry
warn(error)
saveData(plr, (attempt and attempt + 1 or 2)) -- add +1 to the current attempt or set as 2 if nil
end
end
end
players.PlayerAdded:Connect(onPlayerAdded)
players.PlayerRemoving:Connect(saveData)
game:BindToClose(function()
-- Check if the game is running and if it's in Studio
if game:GetService("RunService"):IsRunning() and game:GetService("RunService"):IsStudio() then
local to_Save = 0
-- Iterate through players to save their data
for _, plr in pairs(players:GetPlayers()) do
if playersData[plr] then
to_Save += 1 -- Increment to_Save for each player with stored data
task.spawn(function()
saveData(plr)
to_Save -= 1 -- Decrement to_Save when data is finished
end)
end
end
-- Yield until all data has been saved
while to_Save > 0 do
task.wait()
end
end
-- Shut the server down as all data has been saved
return
end)
also, i am reuploading this post because my last post did not get much attention and id like to get this resolved.