Hello! I want an easy way to save parts to datastore. I read all about serializing parts but they are too complicated. So if there is a way to loop through an instance’s properties it would be so much more easier to save models. Because I want to save the player’s character’s model every time they join. If their character is already saved then I won’t do anything. The point is so that they can switch their avatar easily in the game. So does anyone know how to loop through and instance’s properties? Please help I know you are reading this thanks
What exactly do you need to save?
I’m not really sure what you mean when you say save their character.
You could have a structure that looks like the following:
local toSave = {}
toSave.rightArm = {Transparency = someValue, Color = someColor, Size = someSize}
Thank you so much, but do you have a code that loops through a player’s character and saves it into a dictionary of some sort? I want to use datastore with it. Thank you!
I’m not going to be available for the night (in my time). I believe a dictionary will not be possible since name collisions could happen.
Furthermore, I suggest you look at the Usage section of the topic, and then you try to implement your approach.
I was able to implement this functionality using recursion. You can generate a structure that can reverse-engineered back to an Instance. It uses pcall
because properties can be tagged as NotReplicated
, which could throw up an error. But why not blacklist the tag? Because this may cause unexpected behavior, where the Instance still has some missing properties to be set.
local RPI = require(7309570414).new();
local Classes = RPI:getClasses();
local function safeIndex(t, k)
local _, v = pcall(function()
return t[k];
end)
return v;
end
local function generateHierarchy(Instance)
local Hierarchy = {
Name = Instance.Name;
ClassName = Instance.ClassName;
Children = {};
Properties = {};
};
local Class = Classes[Instance.ClassName];
for _, Property in pairs(Class:getMembers({"Property"}, true, false, {"ReadOnly", "NotScriptable"})) do
Hierarchy.Properties[Property.Name] = safeIndex(Instance, Property.Name);
end
for _, Child in ipairs(Instance:GetChildren()) do
table.insert(Hierarchy.Children, generateHierarchy(Child));
end
return Hierarchy;
end
local function generateInstance(Hierarchy)
local Class = Classes[Hierarchy.ClassName];
local Instance = Class:new();
if (not (Instance)) then
return nil;
end
for propertyName, propertyValue in pairs(Hierarchy.Properties) do
Instance[propertyName] = propertyValue;
end
for _, Child in ipairs(Hierarchy.Children) do
Child = generateInstance(Child);
if (Child) then
Child.Parent = Instance;
end
end
return Instance;
end
There are some exceptions as well. Certain Instances are tagged as NotCreatable
, which is pretty self-explanatory.
Usage
With the code above appended, we can run generateHierarchy
to save an Instance, and generateInstance
to create it.
local myInstance = generateHierarchy(workspace.Baseplate);
...
generateInstance(myInstance).Parent = workspace; -- may give nil if Instance is NotCreatable
Hope this helps.
P.S. It seems this will not work with characters since they are mostly composed of MeshParts, which have their MeshId locked to Scripts. Still keeping this here though.