I have learned how to make a save system for my sandbox tycoon I am working on but can't seem to get the saved data to load on to the correct plot with zero offset (What I mean by offset is that it is not aligned with the plot. It's slightly off if the plot). My save function looks like this:
The script is located in Workspace and it is a server script. It is not disabled.
local function Save(plr)
local key = "plr-"..plr.UserId
local TycoonSave = {}
local Tycoon = script.Parent.SaveFolder:GetChildren()
for i, obj in pairs(Tycoon) do
if obj then
table.insert(TycoonSave, {
["Name"] = obj.Name;
["CFS"] = { -- CFS = CFrames
["X"] = obj.PrimaryPart.CFrame.X;
["Y"] = obj.PrimaryPart.CFrame.Y;
["Z"] = obj.PrimaryPart.CFrame.Z;
["R"] = obj.PrimaryPart.Orientation.Y
}
})
end
end
local success, err = pcall(function()
DataStore:SetAsync(key, TycoonSave)
end)
if not success then
warn("Failed to over-right data"..tostring(err))
return
end
return TycoonSave
end
When I load my data back in I have tried adding and multiplying the plots CFrame to the models but that gave me and offset of about 10 studs on every axis except Y. Here is an example of the load function:
local function Load(plr)
local key = "plr-"..plr.UserId
local Saved
local success, err = pcall(function()
Saved = DataStore:GetAsync(key)
end)
if not success then
warn("Failed to read data"..tostring(err))
return
end
if Saved then
for q, objs in pairs(script.Parent.SaveFolder:GetChildren()) do
if objs then
objs:Destroy()
end
end
wait(1)
for i, obj in pairs(Saved) do
if obj then
local SavedModel = game.ReplicatedStorage.Models:FindFirstChild(obj.Name)
if SavedModel then
wait(0, 1)
local Model = SavedModel:Clone()
Model.Parent = workspace.SaveFolder
if Model then
Model:SetPrimaryPartCFrame(Plot.CFrame * CFrame.new(obj.CFS.X, obj.CFS.Y, obj.CFS.Z) * CFrame.Angles(0, math.rad(obj.CFS.R), 0))
Model.PrimaryPart.Transparency = 1
Model.PrimaryPart.CanCollide = false
end
end
end
end
wait(1)
else
-- save the data
end
I call the save function when the player clicks a button and when the player leaves. The load function is called when the player joins. The two functions are in one script.
Thanks for the help!

2 comments
Maybe try saving the values relative to the plot. Like Part A is 8 studs on the X and 6 studs on the Z, relative to the center of the plot (or the plot's center). Then, this will seamlessly load to each plot as it saved relative to each plot, not to the world.
Thats what I am trying to do. Not sure how to do that.