model copier
Key Required

model copier

🐰 RetroStudio 🔨LateLate 5K views 203 executesUpdated Aug 7, 2025
4.3/ 5(7 votes)
6186% Positive
Lua Script•193 lines (5700 chars)
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();

Features & Information

Some RetroStudio model copier i made out of boredom ⚠️ I'd recommend setting the game's time period to Mid-2015 to support the most materials and more ⚠️ (Only change Settings.BlacklistedProperties and Settings.BlacklistedClasses if you know what you're doing) ℹ️ To get the ModelId copy the numbers from the Model URL you found For example if you found a URL like https://create.roblox.com/store/asset/187789986/ Then the ModelId is "rbxassetid://187789986"
#retrostudio#id#model

Community Comments (2)

zxcvzxcvAug 9, 2025

peak update

hford4581hford4581May 24, 2026

It just crashes your game

More Scripts for 🐰 RetroStudio 🔨