Hello, can you help me create a system that saves (with the DataStore) the “Furniture” that the player has placed?
And that the save is loaded when the player returns to the game.
Thank you very much if you help me!
I have a similar feature in my plot-based building game and I use this module: Converter Module: Instance ↔ Table | Save Instances to DataStores and More!
Using this module, you convert an instance to a table, save that table using DataStoreService and then load it in and convert it back to an instance. You can turn all the furniture into a model and convert it.
If this is anything more than basic parts, such as interactable objects for example, I would recommend just having an array per object that includes its position, orientation, and either a name or id to reference which object it is (and also any other data that may be relevant, such as the color). Saving every individual part is a bit excessive and bloated. If you use only numbers, you can also compress the size down with binary (but that’s only really needed if dealing with something massively large scale as the data limit per key is 4mb/4 million characters).
The module literally does the same thing but it saves a lot of time.
No, what that module appears to do is convert instances into a string. This wastes a lot of resources both to process and also wastes a lot of space in your datastore. While it may work for your needs, this is typically not the correct way to do this and certainly not optimized for any sort of game.
It has multiple functions, you can change it into an array, dictionary, or whatever. And this doesn’t really do anything bad performance-wise because I have been using it for a long time in my game. No complaints from other users either.
It doesn’t matter what type of “value” it is. Data is stored as a string when it’s in a datastore. A datastore’s limit is 4mb, which is 4 million bytes. Each (string) character is 1 byte. When you use JSONEncode, you’re converting an array/table into a json string. What you’re doing is very inefficient and wasteful. You should instead save objects minimally to save on processing and datastore space. Again, just because something you use works doesn’t mean it’s a good way to do something.
Idk I myself love it I have not had any issues, it saves properties as well but if he wants to waste the time he could spend on something else, then he can do it manually
What I’m saying is that you shouldn’t choose a very inefficient method to do something so basic. Saving parts like that module does actually does have specific use-cases where that’s exactly what you want. But the way you’re using it is very wasteful. Also, I say this with any module, I firmly believe that people should understand how to do things before using somebody else’s code. If you don’t, you’ll fail to learn anything and will be stuck with poorly optimized code and not improving as a programmer.
I’m not saying you can’t do what you’re doing, but it’s not within your best interest to do so. If you look at the documentation, DataStores are very easy to use and creating a custom save system is very quick and simple. If you’re wanting to do anything even remotely advanced with data, you’re gonna have to learn regardless:
I would recommend serializing the furniture in what the player changes. What I mean is you could store:
- What type/object of furniture it is (A table, a door, a couch?)
- Where it is placed (position)
- How it is oriented
- Custom colorization and customization (special meterials, design variants, and others)
- Any other setting the player can choose
When it is time to reload the furniture from the datastore, you load back the furniture’s model from the type set in this table, and adjust its position, size, orientation, colors, materials, etc. as is described in your table.
Against what is being suggested by some others above, I do not recommend directly serializing 1:1 the parts and other instances within the item of furniture, because as @MightyDantheman has mentioned:
- It is very inefficent and means that there is less items that can be stored (4MB limit of data per value)
- Any scripts or modules placed inside the furniture won’t load and won’t work.
Best of luck in your game!
Only other tips for serialization of models would be this:
- Clamp the positions so you don’t have something like Vector3.new(1.00052,4.42882,5.543). You can clamp to the tens decimal place like Vector3.new(1, 4.4, 5.5). (Only after you clamp them, then serialize it to a string! Cant save vectors!)
- Clamp orientation as well, like above.
- Use an ID system. 1=Door, 2=Couch, etc.
Love the replies from both majdTRM and MightyDantheman, I suggest listening to them. Goodluck!
Just curious, why would you need to clamp the position for serializing (unless you mean this is just another thing to consider o/s of serialization).
EDIT: Ah I see, can’t save vectors… But can’t you just convert them to tables? { X = 1.00052, Y = 4.42882, Z = 5.543 }
To add to this, each decimal is treated as another character, which wastes potentially valuable space. It only upsets my OCD. Aside from not being able to store specific value types directly, this is also a great time to use binary to convert numbers into characters to save on space.
I clamp positions like in my example to prevent long unnecessary strings. You can turn:
"x25.502501y5.294z6.0603"
to "x25.5y5.3z6.1"
which is way shorter when dealing with lots of objects.
Less string = less data.
Can you expand on this? Is binary conversion just compression?
Well yes, if you’re serializing them as strings. But if you serialize them as tables you wouldn’t have this issue. Also CMIIW, but serializing numbers as strings is less efficient because you’re storing them in base 10, rather than base 2, even if doubkes take up more space than ints.
E.g. 827377229 would be saved as 9 bytes as a string, but only 8 as a double. If yoh really want to save space, you could serialize it as a short, but you would need your own function to convert the number to a binary string
That depends on how you are saving it. If you run:
print(game:GetService('HttpService'):JSONEncode(1.1245))
You’ll find that it prints exactly what you put in. JSON isn’t doing any magic to save space, it’s just converting arrays and tables into a string format.
As a JSON, yes. JSON, I suppose, is meant to be more human readable than space efficient. But why wouldn’t you just save it as a table? I’m sure it would take up less space than a JSON representation of the same thing…
So basically, each character is a byte and a byte is 8 bits. You can store a surprising amount of data in one byte, but I won’t get into the details unless you really want me to (using Minecraft as an example). But the main thing here is that you can convert a large number into only a few string characters that still exactly represent that longer number.
why wouldn’t you just save it as a table?
I encourage you to print your JSONEncode output to see how your data is actually being saved. A table isn’t a special datatype, it’s still just text.
Would you recommend having my serialized plot data (all objects) fit into one string? Then one big de/serializer function to deal with it?