I’m trying to achieve a system where the data will save using tables. I have a current method to save the plot but its not all that good. I feel as if it could be improved tons!
What is the issue?
The issue currently is it being inefficent and doesn’t work 10% of the time. I’m wondering if someone could help or explain to me better on how I could use a table to save the data of these objects. Each object should load in on the position based off where there plot is (as it changes per server) How should I go about loading in the data and saving the positions?
What solutions have you tried so far?
I have tried to save positions in tables and then load them in based off the centerpoint of the plot. Didn’t work so well for me.
Are you using a grid-like system? This might be very inefficient but did you think of labelling each time as an ID per plot and saving it as a table then converting it to JSON and storing it?
Example:
Plot_1_1 = {
"Wall",
"Painting" = {
X,
Y,
}
},
Plot_1_2 = {
"Wall",
},
Plot_1_3 = {
"Wall"
}
-- The first number argument is X and the second number argument is Y for table keys.
Another method is storing their CFrame values and when the game loads using a method to illiterate the table. Have a set of items stored somewhere that is the same names as the IDs use :FindFirstChild in their storage folder to find the correct items. Use the CFRAME argument within the item table to find the correct position of the item. If your game requires each item to have a plot value that might be a problem but it can be solved using a method checking if an item is in an area.
Example:
Table = {
CFRAME
OTHER INFO
}
Wall = {
CFRAME
OTHER INFO
}
Chair = {
CFRAME
OTHER INFO
}
Game loads in:
game.Players.PlayerAdded:Connect(function(plr)
local DataStore = DATASTORE HERE
for name,tableObject in pairs(DataStore) do -- illiterate through the table
if STORAGE:FindFirstChild(name) then -- Check if there is an item named after the ID
local foundObject = STORAGE:FindFirstChild(name):Clone() -- Clone the correct item
foundObject:SetPrimaryPartCFrame(tableObject[1]) -- Set the model position. If it is a part only replace it with .CFrame
-- If anything is required put it here
end
end
end)
If you have a primary part for all placeables, you can get those placeables’ primary part position by a basic CFrame formula. If I remember it right, it should be Plot.CFrame:inverse() * Object.PrimaryPart.CFrame
and it basically subtracts plot CFrame from object PP CFrame. You also can use xuefei’s suggested methods.
Saving every placeable to a folder will give you chance to form a table easily. Like…
local SavingTable = {}
for i,v in pairs(Placed:GetChildren()) do
local SavingCF = Plot.CFrame:inverse() * v.PrimaryPart.CFrame
table.insert(SavingTable, {SavingCF, ItemID, ...})
end
Finally, use JsonEncode to turn SavingTable into a string as iRexBot suggested because you can’t save MetaTables(Tables inside tables).
The console outputs that. The top string of numbers is the “SavingCF”
for i,v in pairs(TycoonValue.Value.Bin:GetChildren()) do
local SavingCF = TycoonValue.Value.TycoonBaseplate.CFrame:inverse() * v.PrimaryPart.CFrame
print(SavingCF)
table.insert(ServerData[plr].TycoonPlacements, {SavingCF, ItemData.Objects[v.Name][7]})
end
local EncodedData = HttpService:JSONEncode(ServerData[plr])
print(EncodedData)
Oh that’s a bit confusing
To be honest I never used this method. Maybe it is not possible to encode CFrame? In this case, you could save position and rotation instead of CFrame itself. Also feel free to use grilme’s method too, if it would be easier for you
The second baseplate is where I orginally placed the chairs, then I got the one closer to the camera and the chairs went wild, not even on a baseplate.
for i,v in pairs(ServerData[plr].TycoonPlacements) do
local CFramePosition = CFrame.new(unpack(v.Position))* CFrame.new(TycoonValue.Value.TycoonBaseplate.CFrame:components())
local GenerateObject = Items:FindFirstChild(v.ObjName):Clone()
GenerateObject.Parent = TycoonValue.Value.Bin
GenerateObject:SetPrimaryPartCFrame(CFramePosition)
end
for i,v in pairs(ServerData[plr].TycoonPlacements) do
local CFramePosition = CFrame.new(unpack(v.Position))* CFrame.new(TycoonValue.Value.TycoonBaseplate.CFrame:components())
local GenerateObject = Items:FindFirstChild(v.ObjName):Clone()
GenerateObject.Parent = TycoonValue.Value.Bin
GenerateObject:SetPrimaryPartCFrame(CFramePosition)
end
And saving
for i,v in pairs(TycoonValue.Value.Bin:GetChildren()) do
local SavingCF = {(v.PrimaryPart.CFrame * TycoonValue.Value.TycoonBaseplate.CFrame:Inverse()):components()}
--print(SavingCF)
table.insert(ServerData[plr].TycoonPlacements, {Position = SavingCF, ObjName = ItemData.Objects[v.Name][1]})
end
It spreads them out a ton, some not even near the baseplates.
No I implemented the method the Tiffblocks said in the post I sent, I can’t see anything wrong with it, wait for Tiff to reply because she will probably know.
I built a game in 2015 that allowed users to build on a plot, which they could save. I don’t think the saving itself works anymore, as I’m sure it used the old data persistence methods (e.g. Player:SaveString(), Player:LoadString()), but the actual packaging of plot data should still work.
I’ve just taken a look back at the code, and I’m pretty sure I could do much better now, but nevertheless, it may be of some help. See the attached place file.