im really sorry if you guys got annoyed for this.
set it as the data instead of inserting, also partInstance.Position = Vector3.new(obj[3], obj[4], obj[5]) – im pretty sure that this wont work instead do this: Position = {X = obj[3], Y = obj[4], Z = obj[5]}
It’s probably because you can’t save tables directly to DataStores.
Try wrapping the table in HttpService:JSONEncode()
, which converts it into a string. When you load the table, use HttpService:JSONDecode()
to return it to its original state.
may you tell me how should i do that?
you can save tables in a datastore.
Please read this quoted post. That’s why I’m saying this, correct me if I’m wrong.
You can save tables in a datastore but to you can also specifically convert something that can’t be saved in a datastore into JSONEncode().
To save:
local success, err
repeat
success, err = pcall(function()
autoSavingStore:SetAsync(key, function()
return game:GetService("HttpService"):JSONEncode(data)
end)
end)
task.wait()
until success
To load:
local function load(player: Player)
local key = keyPrefix .. tostring(player.UserId)
local success, err
local data
repeat
success,err = pcall(function()
data = autoSavingStore:GetAsync(key)
end)
until success or not players:FindFirstChild(player.Name)
if not data then return end
if success then
data = game:GetService("HttpService"):JSONDecode(data)
Hmm. I didn’t know that. Thanks
is that correct?
local players = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")
local autoSavingStore = dataStoreService:GetDataStore("F3XAutoSave")
local keyPrefix = "Player: "
local function save(player: Player)
local key = keyPrefix .. tostring(player.UserId)
local data = {}
for i, obj: BasePart in ipairs(workspace:FindFirstChild("Builds"):WaitForChild(player.Name):GetDescendants()) do
if obj:IsA("BasePart") then
table.insert(data, {
-- PART PROPERTIES
obj.Name,
obj.CanCollide,
obj.Position.X,
obj.Position.Y,
obj.Position.Z,
obj.Orientation.X,
obj.Orientation.Y,
obj.Orientation.Z,
obj.Anchored,
obj.Size.X,
obj.Size.Y,
obj.Size.Z,
obj.Color.R,
obj.Color.G,
obj.Color.B,
(string.match(tostring(workspace.Baseplate.TopSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.BottomSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.LeftSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.RightSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.BackSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.FrontSurface), "%.(%w+)$")),
obj.Transparency,
obj.Reflectance,
string.match(tostring(obj.Material), "%.(%w+)$")
})
local success, err
repeat
success, err = pcall(function()
autoSavingStore:SetAsync(key, function()
return game:GetService("HttpService"):JSONEncode(data)
end)
end)
task.wait()
until success
end
end
end
local function load(player: Player)
local key = keyPrefix .. tostring(player.UserId)
local success, err
local data
repeat
success,err = pcall(function()
data = autoSavingStore:GetAsync(key)
end)
until success or not players:FindFirstChild(player.Name)
if not data then return end
if success then
data = game:GetService("HttpService"):JSONDecode(data)
for i, obj in ipairs(data) do
local partInstance = Instance.new("Part")
partInstance.Name=obj[1]
partInstance.CanCollide=obj[2]
partInstance.Position = Vector3.new(obj[3], obj[4], obj[5])
partInstance.CFrame *= CFrame.Angles(math.rad(obj[6]),math.rad(obj[7]),math.rad(obj[8]))
partInstance.Anchored=obj[9]
partInstance.Size = Vector3.new(obj[10], obj[11], obj[12])
partInstance.Color = Color3.new(obj[13],obj[14],obj[15])
partInstance.TopSurface = Enum.SurfaceType[obj[16]]
partInstance.BottomSurface = Enum.SurfaceType[obj[17]]
partInstance.LeftSurface = Enum.SurfaceType[obj[18]]
partInstance.RightSurface = Enum.SurfaceType[obj[19]]
partInstance.BackSurface = Enum.SurfaceType[obj[20]]
partInstance.FrontSurface = Enum.SurfaceType[obj[21]]
partInstance.Transparency = obj[22]
partInstance.Reflectance = obj[23]
partInstance.Material = Enum.Material[obj[24]]
end
else
warn(tostring(err))
end
end
players.PlayerAdded:Connect(load)
players.PlayerRemoving:Connect(save)
game:BindToClose(function()
for i, plr: Player in ipairs(players:GetPlayers()) do
save(plr)
end
end)
Yes, but this is probably not the cause for the error you’re facing.
i still get the error , it is not working
hold on a minute, i forgot to add the httpservice, i will add that rn mb
i added the httpservice variable and applied it but it still doesn’t work…
try changing the colon to an underscore in the keyPrefix
the key is customizable, also when i tried to change it , didnt work.
Hello,
I checked your script and the issue seems to occur because you’re using a function in SetAsync()
(which is what you should use for UpdateAsync
Here is the updated script:
local players = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")
local autoSavingStore = dataStoreService:GetDataStore("FX3AutoSave")
local keyPrefix = "Player_"
local function save(player: Player)
local key = keyPrefix .. tostring(player.UserId)
local data = {}
for i, obj: BasePart in ipairs(workspace:FindFirstChild("Builds"):WaitForChild(player.Name):GetDescendants()) do
if obj:IsA("BasePart") then
table.insert(data, {
-- PART PROPERTIES
obj.Name,
obj.CanCollide,
obj.CFrame.X,
obj.CFrame.Y,
obj.CFrame.Z,
obj.Orientation.X,
obj.Orientation.Y,
obj.Orientation.Z,
obj.Anchored,
obj.Size.X,
obj.Size.Y,
obj.Size.Z,
obj.Color.R,
obj.Color.G,
obj.Color.B,
(string.match(tostring(workspace.Baseplate.TopSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.BottomSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.LeftSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.RightSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.BackSurface), "%.(%w+)$")),
(string.match(tostring(workspace.Baseplate.FrontSurface), "%.(%w+)$")),
obj.Transparency,
obj.Reflectance,
string.match(tostring(obj.Material), "%.(%w+)$")
})
local success, err
repeat
success, err = pcall(function()
autoSavingStore:SetAsync(key, data)
end)
task.wait()
until success
if not success then
warn(tostring(err))
end
end
end
end
local function load(player: Player)
local key = keyPrefix .. tostring(player.UserId)
local success, err
local data
repeat
success,err = pcall(function()
data = autoSavingStore:GetAsync(key)
end)
until success or not players:FindFirstChild(player.Name)
if not data then return end
if success then
for i, obj in ipairs(data) do
local partInstance = Instance.new("Part")
partInstance.Name=obj[1]
partInstance.CanCollide=obj[2]
partInstance.CFrame = CFrame.new(obj[3], obj[4], obj[5])
partInstance.CFrame *= CFrame.Angles(math.rad(obj[6]),math.rad(obj[7]),math.rad(obj[8]))
partInstance.Anchored=obj[9]
partInstance.Size = Vector3.new(obj[10], obj[11], obj[12])
partInstance.Color = Color3.new(obj[13],obj[14],obj[15])
partInstance.TopSurface = Enum.SurfaceType[obj[16]]
partInstance.BottomSurface = Enum.SurfaceType[obj[17]]
partInstance.LeftSurface = Enum.SurfaceType[obj[18]]
partInstance.RightSurface = Enum.SurfaceType[obj[19]]
partInstance.BackSurface = Enum.SurfaceType[obj[20]]
partInstance.FrontSurface = Enum.SurfaceType[obj[21]]
partInstance.Transparency = obj[22]
partInstance.Reflectance = obj[23]
partInstance.Material = Enum.Material[obj[24]]
end
else
warn(tostring(err))
end
end
players.PlayerAdded:Connect(load)
players.PlayerRemoving:Connect(save)
game:BindToClose(function()
for i, plr: Player in ipairs(players:GetPlayers()) do
save(plr)
end
end)
Some people mentioned data serialization with JSONEncode & JSONDecode which might be a good practise but imo it makes data harder to manipulate and may fail.
Hope that helps!
thank you so muchhhh, this is worked just like what i wanted!
one question tho, how do i detect if the part have a decal so i add its options too
You could do:
if part:FindFirstChildWhichIsA("Decal") then
local decal = part:FindFirstChildWhichIsA("Decal")
-- save decal --
end
I’d advice you to create a recursive function that serializes the properties into a table outside of the SaveData func, so basically, you’re executing that serialize func on an instance which runs itself on all of the instance’s children and so on until you reach the end.