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

  1. Resetting player data
  2. Changing between PointToObject and WorldSpace() and toObject and WorldSpace()
  3. Editing the plot system
  4. Adding extra bits of code to test and see if they work (Testing other ideas that I had)
  5. 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

0

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

0

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?

0

You explained it correctly he just didn’t read that part.

0

ok