How To Do Plot Saving?

I am trying to make a sandbox tycoon and I have the plot system done but I cant figure out how to save any object that is above or touching the plot

Here’s where stuff is located

3 Likes

You could give them a tag of the players name or if you store the plots objects in a folder, then you can do a for loop, though the folder or the collenctionserivce, when they leave and save then delete them.

Here are the basic steps:

  1. You need cloneables, preferably in ReplicatedStorage

  2. When a save needs to happen, serialize all of the data you need to re-create the items and save it in the DataStore

  3. When a load needs to happen, deserialize all of the data, cloning the items back onto the plot (with their data populated)

Writing custom serialization code can be a hassle (as is interacting with DataStoreService), but it is what you need to do to store data like this if you don’t want to learn a custom library, like ProfileService

1 Like

Hello Thanks For Replying How Do You Serialize Parts I Don’t Understand What Serialize In This Context Means

so it’s pretty complicated, actually it’s easy once you understand, I only understood plot saving after four years of development.

Let’s say you have a table of parts you want to save, now you need to convert that table into a table that uses no instances and only bool or string data

local instanceTable = {workspace.Part}
local serialTable = {}

for index, value in instanceTable do
    serialTable[index] = {
          Color = value.Color, -- and so on.
    }
end

then you would have to use :GetAsync() and :SetAsync() or something like that. I recommend using a tutorial if you don’t know what it means still.

2 Likes

Yeah it’s actually pretty simple to understand. When you save data using the DataStoreService, it needs to be in the form of a Lua table with basic values, which are string, number, and boolean

For example, if you want to save the position (Vector3) of an item on the plot, you have to convert that position value to a table, such as:

local serializedPos = { pos.X, pos.Y, pos.Z }

-- save to data store

and when you load the data back in, you have to convert it back to the right format:

-- get from data store

local deserializedPos = Vector3.new(unpack(serializedPos))
1 Like

If you are unfamiliar with the DataStoreService, you should try to minimize the number of calls to DataStores when you can - so you don’t hit the API limit.

You should load data for deserialization and then initialization, keep a reference to the deserialized data for the server to check against and modify. Whenever you need to save the data, you can serialize it and update the data to the DataStore

1 Like

So Basically Sterilizing Is Just Saving The Values Of The Part?

1 Like

Yes sir. It saves the properties to the player’s data. then deserializes it. You may want to consider saving

  • Model Name
  • Model Position
  • Model Color (If you allow coloring)
  • Model Orientation (If you allow X degree rotation)

Then you load all of that, importance is to save the Model Name as that will be your reference for when you need to figure out which model to put where. Store all the models you want in ReplicatedStorage.Assets.Models as an example. Then just find the Model Name and Clone it!

1 Like

Yup that’s about it, just sVe avey parts uniquely in dictionary.

I personally use Profile Service to save this data.
Only save when the player leaves the game, and some saves every 5 minutes in case of a server crash.
Save a table to this, you can create custom types if you’d like, and include attributes like the coordinates so your game can quickly retrieve them and place them.
So lets say the player placed a blue cube at -100, 5, -300, but of course that isnt gonna be the same location every time they load presumably, because they may claim a different plot, so find the difference from whatever point you’d like, I like starting at the lowest x, y, and z coordinates so that our new 0,0,0 point in respect to the plot is in a corner. Find this value based on the corner, then save that.
So now Shedletsky has his data as:

PlayerData = {
     PlacedBlocks = {
          [1] = {
               ["Name"] = "BlueBlock",
               ["XYZ"] = Vector3.new(4,1,5),
               ["Orientation"] = Vector3.new(0,0,0)
          }
}

etc. etc.

But how would I load it to a diffrent pot in the game I am making there is a plot syestem and I want it to be when the player joins they get a plot and their stuff loads in how would I do this because wouldn’t it load the stuff where the player left

Whats the diffrence from using datastoresrvice and profialservice

So like this?
function Starilize(Model: Model) return { Name = Model.Name, Position = Model.PrimaryPart.Position, Size = Model.Size, Color = Model.Color, Anchored = Model.PrimaryPart.Anchored, Transparency = Model.PrimaryPart.Transparency, CanCollide = Model.PrimaryPart.CanCollide, Material = Model.PrimaryPart.Material, Orientation = Model.PrimaryPart.Orientation } end

Yes but i wouldn’t worry about saving the color and stuff as of yet, just the Name, Orientation, Size, Position Also keep in mind of what you are adding to your game, if you do not want players to resize models then do not what so ever save it into your datastore as it causes clutter and will fill up your datastore with junk. You should only save the name, orientation and position. If someone can verify this for me CFrame might be better to store but there is more values and more accuracy to that which could cause your data to fill up.

Only save what you need or else you’ll experience major loading times increased.

The answer to what @4UnderscoreRa’s said the difference between using DataStoreService (DSS) and ProfileService (PS) is that DSS you have to create your own security and session locks and all of that.
While PS handles all of it for you, it’s just a service that a community member made. It’s highly recommended to use another Service than to use DSS because like i said you have to deal with the hassle of verifying your player data saved, handling edge cases if some corruption happens e.t.c so PS or any Data Store Module is better for generic needs and is seen as the norm. (Unless you want to make your own Data Store Module for your games needs)

To finally answer your other question about loading it in is by making a deserialize function which takes your table and deserializes it, imagine it as encrypting a message then decrypting it, that’s what serialize and deserialize does. When you deserialize you do the opposite of the serialize function so you need to pass through the player’s data table that you serialized into the function this function will reference the ReplicatedStorage asset’s name and clone it and position it to the player’s placed location using :PivotTo().

1 Like

Like what the other commenter said, datastore service is a built in service, meaning its quite barebones and is only what you specifically need, but theres a lot more to data systems than setasync and getasync. Profile service is a module created by a developer, not roblox like datastoreservice is, so you’d have to copy it from github or get it from the toolbox. It handles a lot of the backend things and is really good for just saving a table and letting it handle the rest.
You can see all your datastore entries on https://www.superbiz.gg, which lets you put an SDK in your game to help you monetize your game and give you extra insights, but one of their tools lets you inspect all datastore entries on your game through their site.
Here is a example from a test game I made:

Visualizing it might help you understand datastores better, especially since you can use this site to delete entries and see all data in a dropdown instead of printing a table and it getting lost in your output.

2 Likes

Wouldn’t PivotTo() just make the objects load at the center of the base

No because PivotTo uses the model’s primary part, its like SetPrimaryPartCFrame(CFrame) but PivotTo() is the successor to it and way less performant heavy.

1 Like

How Becuse If The Primanypartscframe is what I am saving then the cframe would = the plots, right?

Sorry, i don’t understand what you mean? You are saving the Primary Part’s CFrame of the model, then when you decide to load it when you need too, use the Model:PivotTo() function to move it to where the player placed it?

1 Like