local Settings = {}; Settings.ModelId = "rbxassetid://MODEL_ID_HERE" Settings.BlacklistedProperties = { "PartPack", "Parent", "Shape", "Beam" } -- Don't remove any of these, only add some that you want blacklisted Settings.BlacklistedClasses = { "Script", "LocalScript", "ModuleScript" } -- Don't remove any of these, only add some that you want blacklisted Settings.DebugMode = false -- (MAY CAUSE LAG IF ON) Toggle if the script will print all progress, like changing properties and adding objects --! Ignore anything past this -- Services local ReplicatedStorage = game:GetService("ReplicatedStorage"); local InsertService = game:GetService("InsertService"); -- Variables local _RetroStudio = ReplicatedStorage:FindFirstChild("_RetroStudio"); local Remotes = _RetroStudio.Remotes local HashLibrary = require(_RetroStudio.HashLib); local Properties = require(_RetroStudio.PermissionData.ClassData); local Hint = Instance.new("Hint", workspace); Hint.Text = "Getting model to copy (if this message won't change, then there has been an error.)" local CreatedInstances = {}; -- Types type Creation = { Class: string, Parent: Instance, Properties: { [string]: any }, } -- Functions local Debug = function(...) if Settings.DebugMode then print(...); end end local GenerateHash = function() local Clock = os.clock(); return HashLibrary.md5((("\224\182\158%*\224\182\158"):format(Clock))), Clock end local Create = function(Data: Creation) if table.find(Settings.BlacklistedClasses, Data.Class) then return Debug("Ignored class:", Data.Class); end local Hash, Clock = GenerateHash(); local Arguments = { [1] = Data.Class, [2] = Data.Parent, [3] = Hash, [4] = Clock, } local Result = Remotes.CreateObject:InvokeServer(table.unpack(Arguments)); for Name, Property in next, (Data.Properties or {}) do local Arguments = { [1] = { [1] = Result }, [2] = Name, [3] = Property, } Remotes.ChangeObjectPropertyAndReturn:InvokeServer(table.unpack(Arguments)) end return Result end local Copy = function(Target: Instance) local FromName = Properties.FromName[Target.ClassName] local ClassProperties = FromName and FromName.PropertiesFromName if ClassProperties then local CopyProperties = (function() local Properties = {}; for Property, Data in next, ClassProperties do local Default = Data.DefaultValue if not table.find(Settings.BlacklistedProperties, Property) then local Success, Result = pcall(function() return Target[Property] end) if (Success) and (Default == nil or Result ~= Default) then Debug("Setting", Target.Name, "property:", Property); Properties[Property] = Result end end end return Properties end)() local Result = Create({ Class = Target.ClassName, Parent = workspace, Properties = CopyProperties, }); return Result end end local GetLength = function(Dictionary: { [string]: any }) local Length = 0 for Index, Value in next, Dictionary do Length += 1 end return Length end -- Init local Old = InsertService:LoadLocalAsset(Settings.ModelId); local Model = Instance.new("Folder"); Old.Parent = Model local DescendantsList = (function() local Descendants = {} for _, Object in next, Model:GetDescendants() do if (not table.find(Settings.BlacklistedClasses, Object.ClassName)) and (Properties.FromName[Object.ClassName]) then table.insert(Descendants, Object); end end return Descendants end)(); local ParentsSet = 0 local ExpectedDescendantCount = #DescendantsList for Index, Descendant in next, DescendantsList do task.spawn(function() local Created = Copy(Descendant); local Tries = 0 if not Created then repeat task.wait(1) Tries += 1 Created = Copy(Descendant); until Created or Tries >= 3 end Hint.Text = string.format("%d/%d objects created", GetLength(CreatedInstances), ExpectedDescendantCount); if Created then Debug("Object created:", Created); CreatedInstances[Descendant] = Created else ExpectedDescendantCount -= 1 end end) task.wait(.2) end repeat task.wait() until GetLength(CreatedInstances) >= ExpectedDescendantCount for _, Descendant in next, DescendantsList do local OriginalParent = Descendant.Parent local Created = CreatedInstances[Descendant] if Created then local NewParent = CreatedInstances[OriginalParent] or workspace if OriginalParent == Model then NewParent = workspace end ParentsSet += 1 Hint.Text = string.format("Setting parents for the objects (%d/%d)", ParentsSet, GetLength(CreatedInstances)) Debug("Setting parent for", Created.Name, ":", NewParent) local Arguments = { [1] = { [1] = Created }, [2] = "Parent", [3] = NewParent, } Remotes.ChangeObjectPropertyAndReturn:InvokeServer(table.unpack(Arguments)) end end Remotes.ChangeHistoryInteractionRequested:FireServer("AddCheckpoint") Hint.Text = ("Finished building"); task.wait(5); Hint:Destroy(); Model:Destroy();