I've got most of it to work. However I can't get it to automatically set it's parent. I have to add it manually and that's a pain in the butt. Example of the generated script.
local function Create(ty) return function(data) local obj = Instance.new(ty) for k, v in pairs(data) do if type(k) == 'number' then v.Parent = obj else obj[k] = v end end return obj end end Create'Part'{ Anchored = true; BrickColor = BrickColor.new(199); Locked = true; Size = Vector3.new(512, 1.20000005, 512); CFrame = CFrame.new(0, -0.610000014, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1); Name = "BasePlate"; Position = Vector3.new(0, -0.610000014, 0); };
And the actual source code.
local tablename = "ref" local n = "\n" local t = "\t" function IsVarName(name) return name:match("^[%a_][%w_]-$") == name end local makeinstance = [[%s = Instance.new(%q)]] local makeservice = [[%s = game:GetService(%q)]] local ObjectMemory = {} local function FormatInstance(s,o,p) if not ObjectMemory[o] then ObjectMemory[o] = {} end ObjectMemory[o][p] = s return nil end local function FormatProtectedString(s) return string.format("%q",s) -- local eq = s:match("=+") -- eq = eq and #eq or 0 -- return "["..string.rep("=",eq+1).."["..s.."]"..string.rep("=",eq+1).."]" end local function FormatUDim(s) return string.format([[UDim.new(%g, %g)]],s.Scale,s.Offset) end local function FormatUDim2(s) return string.format([[UDim2.new(%g, %g, %g, %g)]],s.X.Scale,s.X.Offset,s.Y.Scale,s.Y.Offset) end local function FormatBrickColor(s) return [[BrickColor.new(]]..s.Number..[[)]] end local function FormatRay(s) return [[Ray.new(]]..table.concat({s.Origin,s.Direction},", ")..[[)]] end local function FormatRegion3(s) return [[Region3.new(]]..table.concat({s.CFrame.p+s.Size/2,s.CFrame.p-s.Size/2},", ")..[[)]] end local function FormatVector2int16(s) return nil end local typeconvert = { ["*default"] = [[%s]]; ["*enum"] = [[%s]]; ["void"] = nil; ["bool"] = [[%s]]; ["float"] = [[%s]]; ["Float"] = [[%s]]; ["int"] = [[%s]]; ["double"] = [[%s]]; ["number"] = [[%s]]; ["string"] = [[%q]]; ["Content"] = [[%q]]; ["ProtectedString"] = FormatProtectedString; ["Vector2"] = [[Vector2.new(%s)]]; ["Vector3"] = [[Vector3.new(%s)]]; ["CFrame"] = [[CFrame.new(%s)]]; ["CoordinateFrame"] = [[CFrame.new(%s)]]; ["Color3"] = [[Color3.new(%s)]]; ["Vector2int16"] = FormatVector2int16; ["Instance"] = FormatInstance; ["Object"] = FormatInstance; ["UDim"] = FormatUDim; ["UDim2"] = FormatUDim2; ["BrickColor"] = FormatBrickColor; ["Ray"] = FormatRay; ["Region3"] = FormatRegion3; } local Properties = {} ----------------------------------------------------------------------------------------------------- local function count(t) local c = 0 for _ in pairs(t) do c = c + 1 end return c end local Properties = {} local enums = {} local ex = { ["DataCost"]=true; ["Parent"]=true; ["RobloxLocked"]=true; ["Archivable"]=true; ["ClassName"]=true; } function FillProperties(class,up) if class.type == "enum" then enums[class.name] = true end if class.properties and #class.properties > 0 or (up and count(up) > 0) then Properties[class.name] = {} if up then for name,type in pairs(up) do Properties[class.name][name] = type end end if class.properties then for n,prop in pairs(class.properties) do if not ex[prop.name] and not prop.deprecated then Properties[class.name][prop.name] = prop.type end end end end if class.subclasses then for n,sub in pairs(class.subclasses) do FillProperties(sub,Properties[class.name]) end end end ----------------------------------------------------------------------------------------------------- local refmem = {} local mem = {} local off = 1 local function recurse(object, parent, tab) local output,tab = "",tab or 0 if not object.Archivable then return output end if not mem[object.ClassName] then local e,o = pcall(game.GetService,game,object.ClassName) if not e or not o then local e,o = pcall(Instance.new,object.ClassName) if e then mem[object.ClassName] = {o,false} end else mem[object.ClassName] = {o,true} end end if mem[object.ClassName] then local default,isservice = mem[object.ClassName][1],mem[object.ClassName][2] if isservice then return output end output=output..string.rep(t,tab)..string.format([[Create'%s'{]],object.ClassName)..n tab = tab + 1 if Properties[object.ClassName] then for p,m in pairs(Properties[object.ClassName]) do if pcall(function() default[p] = default[p] return default[p] end) then if object[p] ~= default[p] or isservice then if type(m) == "function" then m = m(object[p],off,p) end if m ~= nil then if IsVarName(p) then output = output..string.rep(t,tab)..p.." = "..string.format(m,tostring(object[p]))..";"..n else output = output..string.rep(t,tab).."['"..p.."'] = "..string.format(m,tostring(object[p]))..";"..n end end refmem[object] = off end end end end if pcall(function() object:GetChildren() end) then local p = off for _,item in pairs(object:GetChildren()) do off = off + 1 local o = recurse(item,p,tab) if #o > 0 then output=output..o else off = off - 1 end end end tab = tab - 1 output = output .. string.rep(t,tab) .. "};"..n end return output end function serialize(object) off = 0 local out = "" if type(object) == "table" then for i,v in pairs(object) do out = out..recurse(v) end else out = out..recurse(object) end --[[ for o,prop in pairs(ObjectMemory) do for name,value in pairs(prop) do if refmem[value] then if IsVarName(name) then out = out..tablename.."["..o.."]."..name.." = "..tablename.."["..refmem[value].."]"..n else out = out..tablename.."["..o.."][\""..name.."\"] = "..tablename.."["..refmem[value].."]"..n end end end end]] for i in pairs(ObjectMemory) do ObjectMemory[i] = nil end for i in pairs(refmem) do refmem[i] = nil end local v = Instance.new("Script") v.Name = "Serialization Output" v.Archivable = false v.Disabled = true v.Source = [[local function Create(ty) return function(data) local obj = Instance.new(ty) for k, v in pairs(data) do if type(k) == 'number' then v.Parent = obj else obj[k] = v end end return obj end end ]] .. out return v end Scrgui = Instance.new("ScreenGui", game.Players.LocalPlayer.PlayerGui); Scrgui.Name = "Scrgui" Textbt = Instance.new("TextButton", game.Players.LocalPlayer.PlayerGui.Scrgui); Textbt.Name = "Serialize"; Textbt.Position = UDim2.new(0,202,0,250); Textbt.Size = UDim2.new(0,100,0,25); Textbt.Text = "Chat"; function onClick(mouse) if not Properties then print("Serialization: external database has not yet loaded") return end local root = game:GetService("Selection"):Get() local output = serialize(root) output.Parent = workspace game:GetService("Selection"):Set{output} end Textbt.MouseButton1Click:connect(onClick) coroutine.wrap(function() local tries = 3 while tries > 0 do local asset = game:GetObjects("rbxassetid://63856918") if asset and #asset > 0 then local ClassDatabase = asset[1] if ClassDatabase then local GetDB = loadstring(ClassDatabase.Value) if GetDB then local db = GetDB() for n,class in pairs(db) do FillProperties(class) end for name,set in pairs(Properties) do for prop,type in pairs(set) do if enums[type] then set[prop] = typeconvert["*enum"] elseif typeconvert[type] then set[prop] = typeconvert[type] else set[prop] = typeconvert["*default"] end end end break end end end tries = tries - 1 end if tries <= 0 then error("Serialization: could not access external database",0) end end)()
Here's an example output.
As you can see it's missing it's parent.