There was a logic error in my code where it was saving to the wrong plot. I have figured it out so don't try to help me out it has be solved.
I asked a question about a week ago asking how to save and load tycoon data onto the correct plot and someone answered it and I thought that it had worked. It did until multiple players joined on the game (mostly devs).
The problem
My problem is that the tycoon data is loading onto the wrong plot. When you get the plot that the data was on before it loads even further away (but by 1 plot). I have made a very inefficient script because of the issue so it may look a bit messy when you look at the code. How I give the plot to the player is locate all the plots then loop around them and check if they have an owner (using object values). If so then skip the plot else give the player the plot. I also change the save folder name to the players username and have four string values (located in ReplicatedStorage) that have the same name of the plot that are equal to the players username. Using this I can find the plot. (This is a sandbox tycoon so I am using remote events to send the plot to the placement system and the plot editor).
I am trying to save the models position relative to the plots position using toObjectSpace() but have also tried PointToObjectSpace() and has given the same results.
Code samples
Here is the save function (all code is in a server script that is located in Workspace):
(I am not showing the DataStore variables but they are in the scripts in-game)
game.ReplicatedStorage.Events.SaveGame.OnServerEvent:Connect(function(plr)
local key = "plr-"..plr.UserId
local TycoonSave = {}
local Tycoon
for t, v in pairs(script.Parent.Plots:GetChildren()) do
if v then
if v.Plot.Owner.Value == plr and game.ReplicatedStorage.SetUp:FindFirstChild(v.Name).Value == plr.Name then
Tycoon = v[plr.Name]
break
end
end
end
for i, obj in pairs(Tycoon:GetChildren()) do
if obj then
table.insert(TycoonSave, {
["Name"] = obj.Name;
["CFS"] = { -- CFS = CFrames
["X"] = workspace.Plots:FindFirstChild(plot).Plot.CFrame:toObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).X;
["Y"] = workspace.Plots:FindFirstChild(plot).Plot.CFrame:toObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).Y;
["Z"] = workspace.Plots:FindFirstChild(plot).Plot.CFrame:toObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).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
game.ReplicatedStorage.Events.FinishedSave:FireClient(plr)
end)
For loading I have also tried pointToWorldSpace() but does not even load the modes on any plot.
Here is the load function:
-- Excuse my messy code and no comments
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
local tycoonPlot
for p, pl in pairs(script.Parent.Plots:GetChildren()) do
if pl then
if pl.Plot.Owner.Value == plr and game.ReplicatedStorage.SetUp:FindFirstChild(pl.Name).Value == plr.Name and pl[plr.Name] then
tycoonPlot = pl[plr.Name]
break
end
end
end
if Saved then
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 = tycoonPlot
if Model then
Model:SetPrimaryPartCFrame(tycoonPlot.Parent.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
local TycoonSave = {}
local Tycoon
for q, plt in pairs(script.Parent.Plots:GetChildren()) do
if plt then
if plt.Plot.Owner.Value == plr and game.ReplicatedStorage.SetUp:FindFirstChild(plt.Name).Value == plr.Name then
Tycoon = plt[plr.Name]
break
end
end
end
for index, c in pairs(Tycoon:GetChildren()) do
if c then
table.insert(TycoonSave, {
["Name"] = c.Name;
["CFS"] = {
["X"] = workspace.Plots:FindFirstChild(plot).Plot.CFrame:toObjectSpace(CFrame.new(c.PrimaryPart.CFrame.p)).X;
["Y"] = workspace.Plots:FindFirstChild(plot).Plot.CFrame:toObjectSpace(CFrame.new(c.PrimaryPart.CFrame.p)).Y;
["Z"] = workspace.Plots:FindFirstChild(plot).Plot.CFrame:toObjectSpace(CFrame.new(c.PrimaryPart.CFrame.p)).Z;
["R"] = c.PrimaryPart.Orientation.Y
}
})
end
end
local complete, message = pcall(function()
DataStore:SetAsync(key, TycoonSave)
end)
if not complete then
warn("Failed to over-right data"..tostring(message))
return
end
game.ReplicatedStorage.Events.FinishedSave:FireClient(plr)
end
end
game.Players.PlayerAdded:Connect(Load)
I have been editing this script for days but nothing has worked.
What I have tried
- Resetting player data
- Changing between PointToObject and WorldSpace() and toObject and WorldSpace()
- Editing the plot system
- Adding extra bits of code to test and see if they work (Testing other ideas that I had)
- Other
Another thing that is strange is if the plot is not changed between sessions the players data will load perfectly fine but will not for anyone else who joins.
The game is filtering enabled.
Not asking for a whole script just want to see if I am doing something wrong. Thanks for the help!
(I don't like asking the same question over and over again so if someone does answer this it is especially appreciated)

4 comments
LOL, Not gonna read all this... Here is a tip though: create int values in every button and increment its value throughout the tycoon... Then save another intvalue in the player and load everything from there... if item.Value < player.Int.Value then -- load... end
I am creating a sandbox tycoon not a button based one. I don't have buttons to put values into. Am I reading this wrong or did my question make you think I was making a button tycoon?
You explained it correctly he just didn’t read that part.
ok