How to save parts, and the idea of Serialization

A little overthinking on saving EnumItem, just save EnumItem.Value and it will return the number and it will still work. Some parts could have been done better, but we appreciate your contribution to the community anyway.

1 Like

I’m getting the error invalid argument #1 to 'pairs' (table expected, got nil)
my code is

local ourFolder = workspace.Places[player.Name]:GetChildren()

    for _, v in pairs(ourFolder) do
        print("got item")
    end

    local result, Err = pcall(function()
        DS:SetAsync(player.UserId, Save.Encrypt(ourFolder))
    end)

it does print “got item”

Weirdly enough though the Value does actually change overtime it seems! As it did here

image

3 Likes

What are the odds of my words turned against me. :joy:

Well, glad you pointed that out. I see why we should use strings instead of a number. I appreciate it.

3 Likes

I’m currently working on a module called Instance Service. Which can save every type of instance using DataStore2. Fully configurable.
Everything works well right now. It’ll come out 2 weeks later.

I’d wanted to say that here because many people actually really wants to learn how to save parts.

2 Likes

One suggestion that may help your saving system(when using cframes) is to neglect one direction vector, let’s say rightVector since it can be reconstructed using :Cross() function among with the other 2 direction vectors.
So instead of saving actual matrix values obtained by using cf:GetComponents() you are saving 25% less.
This doesn’t help right away, but in huge data sizes, it may be a great improvement!

Also… there could be a problem when trying to save any vector that have many decimal digits since they charge up the string when serializing. One way to avoid this is to trim the resulted string, which may result a loss in data accuracy, but it provides more saving space.

1 Like

Indeed! There are many strategies to compress the size of saved data. I should mention the possible need of this in the article.

As well, there are even better ways to save CFrames! Only with 2 vectors in fact instead of 3. The first vector would hold the position, the second vector would encode the rotation of the CFrame in axis-angle form (the rotation of the cframe that is expressed by what’s returned from :ToAxisAngle()), this form requires an axis (a unit vector) and a rotation along that axis (a number/scalar) to describe a rotation.

Since the axis is a unit vector, we can encode the rotation through the that unit’s vector length, and we’d still know what the unit vector is simply by doing a .Unit operation.

local axis, rotation = cf:ToAxisAngle()
local saved_rotation = axis*rotation

-- save saved_rotation

local axis, rotation = saved_rotation.Unit, saved_rotation.Magnitude
local CFrame = CFrame.fromAxisAngle(axis, rotation)

-- load saved_rotation

(we’re not saving the position in this example, but it’s just saving another vector)

1 Like

I’ve created my module for saving objects!

1 Like

But what if we want to save models? Should we check if the type is a primarypart and then say that r = {CFrame}? How do we do that?

1 Like

This is indeed a certain section of serializing that I haven’t dabbled, which is saving instances. In reality I would make saving instances generic, that way I can simply list the PrimaryPart to be saved, and I would utilize this to save any other instance property, such as Part0 and Part1 of welds.
I explain how I do this here

Hey, I have a question. How do I save models? Because I want to save a player’s character in-game using datastore but I don’t know how because inside the character there are other things not only baseparts like special meshes, motors, animations, cloths, hats, pants, textures, and a lot of others. Please help. Thanks!

You can loop through the character, then serialize them and save them.

How? I mean the serializing part. I know how to looop.

@starmaq did explain how to serialize parts. Just read through the blog post carefully again.

ok let me read it againnnnnnnnnnnnn

I think you can do that using insertservice. I think here’s how you use it.

local insertservice = game:GetService("InsertService")

local asset = insertservice:LoadAsset(--asset id)

asset.Parent = workspace
1 Like

Just store a list of all the meshes, then instead of storing mesh id, simply store an ID which references to the mesh, then when creating the parts, instead of doing Instance.new() do MeshItem[MeshReferenceID]:Clone()

I find this method to work for most peoples use cases.

Just for your information, mesh id and Id of mesh are both the same

In this case not, the ID of a mesh is any kind of reference to the real mesh object. It can be any value you want. It just needs to specifically reference to that particular mesh at all times.

something like this?

workspace.MeshPart[meshid]:Clone()