Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

What is an efficient approach to remove many cloned instances in a Workspace?

Asked by 8 years ago

Hello, I am developing a basic flat-terrain generator, where bricks are generated over a square area with multiple layers. The problem is, there are factors that are keeping me from achieving this.

The following is my code; I will go by line references if needed since many of the commands are interconnected throughout the whole script, and the script itself is large. I wasn't sure how to auto-indent in a block formation as well, excuse me for that.

while true do

--create a group called "DirtBlockCloneGroup"
dirtBlockCloneModel= Instance.new("Model",game.Workspace)
dirtBlockCloneModel.Name= "DirtBlockCloneGroup"

local cloneBrickCount= 0
for timer= 1,0,-1 do --timer that counts from 3/ any # to 0 by seconds
    wait(1)
    print(timer)

    if timer== 0 then
    print("Done.")--ends timer, then does action below

x0= game.Workspace.DirtBlock.Position.X
y0= game.Workspace.DirtBlock.Position.Y
z0= game.Workspace.DirtBlock.Position.Z
--sets whatever position the original dirt block is in, stores ion variables
local original= Vector3.new(x0,y0,z0)

local zIncr= 3 --increments new clone blocks by changing z coordinate
--line below checks and gets testing plate size
local zSizeBase= game.Workspace.BasePlate.Size.Z
local zSizeCheck= 3--baseplate comparison, so clone won't pass plate boundaries

local xSizeBase= game.Workspace.BasePlate.Size.Z
local xSizeCheck= 3
local xIncr= 3

    for i= 1,4 do--sets how many layers of bricks
        for i= 1,(xSizeBase/3) do-- because it increments by 3 studs
            while zSizeCheck<zSizeBase do
                clone= game.Workspace.DirtBlock:Clone()-- creates clone
                clone.Name= "DirtBlockClone" -- changes name of dirt block
                clone.Parent= game.Workspace.DirtBlockCloneGroup --adds the instance into the Workspace
                clone.Position= Vector3.new(x0,y0,z0-zIncr)

                cloneBrickCount= cloneBrickCount+1

                zIncr= zIncr+3-- ex. 3 away from original, 6 away, 9 away etc.
                zSizeCheck= zSizeCheck+3

            end
        zSizeCheck= 0--these scripts reset the position, so it won't shift
        zIncr= 0
        x0= x0+3
        wait(0.001)--delay to minimize lag, edit between dev and release
        end
    y0= y0+3-- goes to the next level, 3 studs up
    x0= game.Workspace.DirtBlock.Position.X-- resets at original point
    end

    end--end of if for timer

end--end of for at very beginning
    print(cloneBrickCount)

--wait(1)-- no change
--for i=1,50000 do

--this period is the playing time before the map resets

--allow player to play buy freeing them from spawn area
game.Workspace.SpawnArea.SpawnBaseBottom.CanCollide= false
game.Workspace.SpawnArea.SpawnBaseBottom.Transparency= 1

--ex. for GUI, "Map resets in: ...

    for timeToReset= 5,0,-1 do
        wait(1)
        test2= Instance.new("Hint",game.Workspace)
        test2.Text= "Time left until map reset: "..tostring(timeToReset)
    end--end for

--players go back when map is regenerating
game.Workspace.SpawnArea.SpawnBaseBottom.CanCollide= true
game.Workspace.SpawnArea.SpawnBaseBottom.Transparency= 0.75

target= CFrame.new(60.5,3358,84.5)
for i, player in ipairs(game.Players:GetChildren()) do
    if player.Character and player.Character:FindFirstChild("Torso") then
        player.Character.Torso.CFrame= target+ Vector3.new(i*2,0,0)
    end
end
--wait(10)

wait(1)
game.Workspace.DirtBlockCloneGroup:Destroy()
wait(1)
--[[
    --alt to the single command above
    while game.Workspace.DirtBlockCloneGroup:FindFirstChild("DirtBlockClone") do
        game.Workspace.DirtBlockCloneGroup.DirtBlockClone:Destroy()
        wait(0.001)
    end
game.Workspace.DirtBlockCloneGroup:Destroy()
--]]

--[[
    --old code
for i=1,cloneBrickCount do--the exact amount of clones needed to be wrecked
game.Workspace.DirtBlockCloneGroup.DirtBlockClone:Destroy()
--111,555 bricks: =22,311*5
--wait(0.001)--edit between dev and release
end 

--]]

end--loop entire script

My first attempt was to count how many blocks were in the Workspace, which is, local cloneBrickCount= 0. Next, a for-loop was used to destroy every existing cloned brick:

for i=1,cloneBrickCount do--the exact amount of clones needed to be wrecked
game.Workspace.DirtBlockCloneGroup.DirtBlockClone:Destroy()
--111,555 bricks: =22,311*5
--wait(0.001)--edit between dev and release
end 

The problem is that there can be a variable number of bricks at each run between each map regeneration sequence. Too little of a value and not all the clones would be removed from the Workspace. Too much and the game will spawn an error saying that the brick does not exist.

My second attempt was to use a while-loop with a wait time:

while game.Workspace.DirtBlockCloneGroup:FindFirstChild("DirtBlockClone") do
        game.Workspace.DirtBlockCloneGroup.DirtBlockClone:Destroy()
        wait(0.001)
    end

The problem here is that the destroy method deletes a brick one at a time, and even with the wait time involved, it would take much longer to remove the clones efficiently than to rebuild the map (regeneration builds cloned bricks by the rows).

My latest attempt was to simply delete the model containing all the bricks (as shown in the code), but that can cause massive lag and possibly a server crash. The upside is that it is very fast.

The only other idea I had in mind was to us smaller wait times such as wait(0.0000000000001) if that makes a difference.

0
Not entirely sure of your problem, but the minimum wait time is a 30th of a second. Therefore wait(0) will delay the code approximately that much. Perci1 4988 — 8y
0
Hmm, I always thought wait(0) was like as if there was no wait period, so I did not include that beforehand. In the short run, I think that may help. However, even with a decent computer, server-side lag can slow map regeneration; in Studio the map degenerates quicker nonetheless as compared to online even if the wait time expected was the same. Houlardy642 28 — 8y
0
By the way, if you're not entirely sure, what areas may seem to be confusing? I can help clarify/ elaborate if needed. Houlardy642 28 — 8y
0
I've modularized your code, study it and you'll easily figure out how to do what you are asking. http://www.roblox.com/Generation-Code-item?id=267072730 Muoshuu 580 — 8y
View all comments (4 more)
0
Thanks, I'll be sure to take a look at it; it seems I will need some more work regarding these kinds of scripts. Houlardy642 28 — 8y
0
ReplicatedStorage is a new concept for me; I noticed a lot of the "kitchen" work is based in the generation script within ReplicatedStorage, while the main script in the Workspace passes on each function with a specified command, a very organized sequence. Regardless if I'm not sure you took in account that the first generation layer contained the original brick, I can still shape my script to mak Houlardy642 28 — 8y
0
My point was that wait(0.0000000000001) will not wait 0.0000000000001 seconds. It will wait about a 30th of a second, the same as wait(0) or wait(). I see your problem now, though, and Adark's answer looks good. Perci1 4988 — 8y
0
I was going to try and implement adark's suggestion, but I'm getting an error. I might post an update on my script, which is influenced by mu6666mu. Houlardy642 28 — 8y

1 answer

Log in to vote
1
Answered by
adark 5487 Badge of Merit Moderation Voter Community Moderator
8 years ago

One way to efficiently remove thousands of parts (or more!) is to only wait() every few Parts Destroy'd:

local count = 0
for _, v in ipairs(workspace.DirtBlockCloneGroup:GetChildren()) do
    v:Destroy()
    count = count + 1
    if count > 50 then
        count = count - 50
        wait()
    end
end
0
So, an error is avoided saying that fifty blocks will be deleted if there exists more than fifty, and when there is less the individual blocks are removed? Houlardy642 28 — 8y
0
All the code does is wait() once for every 50 blocks removed. It doesn't know nor care the actual total number of blocks it is removing. adark 5487 — 8y
0
I see. I could add conditions to my liking as I would like to detect the number of instances that were affected during the degeneration process. Houlardy642 28 — 8y
0
You'll have to add a second `count` counter variable, and never subtract from it like I do. adark 5487 — 8y
Ad

Answer this question