local K=function(K,D,C)local s=C or task RunService=C or RunService local N=GiveObjectPrimaryPart(K)N:SetPrimaryPartCFrame(CFrame.new(Vector3.new(20000,300,math.random(-10000,10000))))D=D or DefaultTime local w={}local P={}local M=0 for K,D in pairs(K:GetDescendants())do if D.ClassName~="\077\111\100\101\108"and D.ClassName~="\070\111\108\100\101\114"then if PriorityDeleteTypes[D.ClassName]then w[#w+1]=D else P[#P+1]=D end M+=1 end end local n=0 local d=false local F=false if M>50000 then warn("\068\101\108\101\116\105\110\103 \109\111\114\101 \116\104\097\110 \053\048\107 \105\110\115\116\097\110\099\101\115 \099\097\110 \099\097\117\115\101 \097 \098\117\102\102\101\114 \111\118\101\114\102\108\111\119\033\033")end D=math.max(D,M/10000)local c=0 local v v=RunService.Heartbeat:Connect(function(K)n+=K local C=(n/D)*M local s=math.ceil(C-c)c=C if not d then if#w<=0 then d=true else d=DeleteAmountOfObjectsInTable(w,s)if not d then return end end end if not F then if#P<=0 then F=true N:Destroy()v:Disconnect()else F=DeleteAmountOfObjectsInTable(P,s)if not F then return else N:Destroy()v:Disconnect()end end else N:Destroy()v:Disconnect()end end)repeat s.wait()until d end return K
-- Change to variable
local TrickleDeleteScene = function(Obj, Time, timeMockLib)
	-- Used for testing
	local taskLib = timeMockLib or task
	RunService = timeMockLib or RunService

	-- Give the Object a PrimaryPart(and put it inside a Model)
	local Model = GiveObjectPrimaryPart(Obj)
	-- Move the Model far away so players don't see it unloading
	Model:SetPrimaryPartCFrame(CFrame.new(Vector3.new(20000, 300, math.random(-10000, 10000))))

	-- Set time to the default if no time is given
	Time = Time or DefaultTime

	-- Sort all descendants into two lists, and calculate how many instances are to be deleted.
	-- (We ignore Models and Folders during initial delete pass. These are all deleted together at the end. - (Unless they are a child of another instance which is deleted)
	local PriorityDelete = {}
	local RemainingToDelete = {}
	local TotalToDeleteNum = 0
	for _, Descendant in pairs(Obj:GetDescendants()) do
		if Descendant.ClassName ~= "Model" and Descendant.ClassName ~= "Folder" then
			if PriorityDeleteTypes[Descendant.ClassName] then
				PriorityDelete[#PriorityDelete + 1] = Descendant
			else
				RemainingToDelete[#RemainingToDelete + 1] = Descendant
			end
			TotalToDeleteNum += 1
		end
	end

	-- Setup variables for the next step
	local TimeTaken = 0
	local PriorityCleared = false
	local RemainingToDeleteCleared = false
	if TotalToDeleteNum > 50000 then
		warn("Deleting more than 50k instances can cause a buffer overflow!!")
	end
	Time = math.max(Time, TotalToDeleteNum / 10000) -- Deleting too many parts per frame causes the buffers to overflow.

	-- Delete all the items, first in the priority list and then the rest of the items.
	local LastDeleteGoal = 0
	local HeartbeatConnection
	HeartbeatConnection = RunService.Heartbeat:Connect(function(Delta)
		TimeTaken += Delta
		local DeleteGoal = (TimeTaken / Time) * TotalToDeleteNum
		local ToDeleteThisRound = math.ceil(DeleteGoal - LastDeleteGoal)
		LastDeleteGoal = DeleteGoal

		if not PriorityCleared then
			if #PriorityDelete <= 0 then
				PriorityCleared = true
			else
				PriorityCleared = DeleteAmountOfObjectsInTable(PriorityDelete, ToDeleteThisRound)
				if not PriorityCleared then
					return
				end
			end
		end

		if not RemainingToDeleteCleared then
			if #RemainingToDelete <= 0 then
				RemainingToDeleteCleared = true
				Model:Destroy()
				HeartbeatConnection:Disconnect()
			else
				RemainingToDeleteCleared = DeleteAmountOfObjectsInTable(RemainingToDelete, ToDeleteThisRound)
				if not RemainingToDeleteCleared then
					return
				else
					Model:Destroy()
					HeartbeatConnection:Disconnect()
				end
			end
		else
			Model:Destroy()
			HeartbeatConnection:Disconnect()
		end
	end)

	repeat
		taskLib.wait()
	until PriorityCleared
end

return TrickleDeleteScene
