local Z=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local I=game:GetService("\080\108\097\121\101\114\115")local S=false local C=Instance.new("\082\101\109\111\116\101\070\117\110\099\116\105\111\110")C.Name="\072\111\116\082\101\108\111\097\100\101\100"C.Parent=Z local function f(Z,I,S)table.insert(I,Z.Changed:Connect(S))for Z,C in ipairs(Z:GetChildren())do f(C,I,S)end end local function L(Z)local I=Z:Clone()I.Parent=Z.Parent Z:Destroy()end local n=nil local y={}function y.start(Z)local y=Z.watch local i=Z.beforeUnload local s=Z.afterReload local U={}local function k()if S then return end print("\083\099\104\101\100\117\108\101\100 \104\111\116 \114\101\108\111\097\100\033")S=true for Z,I in ipairs(U)do I:Disconnect()end wait(.1)n=i()for Z,I in ipairs(y)do L(I)end wait(.1)for Z,I in ipairs(I:GetPlayers())do C:InvokeClient(I)end s()S=false end spawn(function()for Z,I in ipairs(y)do table.insert(U,I.DescendantAdded:Connect(k))f(I,U,k)end end)end function y.getSavedState()return n end return y
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local reloadScheduled = false

local reloadBindable = Instance.new("RemoteFunction")
reloadBindable.Name = "HotReloaded"
reloadBindable.Parent = ReplicatedStorage

local function listenToChangesRecursive(root, connections, callback)
    table.insert(connections, (root.Changed:Connect(callback)))

    for _, child in ipairs(root:GetChildren()) do
        listenToChangesRecursive(child, connections, callback)
    end
end

local function replace(object)
    -- Do you ever get that feeling that everything in your house has been
    -- replaced by an exact replica?

    local new = object:Clone()
    new.Parent = object.Parent
    object:Destroy()
end

local savedState = nil

local HotReloadServer = {}

function HotReloadServer.start(options)
    local objectsToWatch = options.watch
    local beforeUnload = options.beforeUnload
    local afterReload = options.afterReload

    local connections = {}

    local function changeCallback()
        if reloadScheduled then return end

        print("Scheduled hot reload!")

        reloadScheduled = true

        for _, connection in ipairs(connections) do
            connection:Disconnect()
        end

        wait(0.1)

        savedState = beforeUnload()

        for _, object in ipairs(objectsToWatch) do replace(object) end

        wait(0.1)

        for _, player in ipairs(Players:GetPlayers()) do
            reloadBindable:InvokeClient(player)
        end

        afterReload()

        reloadScheduled = false
    end

    spawn(function()
        for _, object in ipairs(objectsToWatch) do
            table.insert(connections,
                         (object.DescendantAdded:Connect(changeCallback)))

            listenToChangesRecursive(object, connections, changeCallback)
        end
    end)
end

function HotReloadServer.getSavedState() return savedState end

return HotReloadServer
