Hello. I am trying to learn how parallel lua works. So, I’ve been looking at some code at the devhub, and I’ve pretty much learned how everything works, but what I don’t understand, is why the code won’t work if I remove a task.defer(function() --[[code]] end)
that is on line 20.
Here is the code:
-- Parallel execution requires the use of actors
-- This script clones itself; the original initiates the process, while the clones act as workers
local actor = script:GetActor()
if actor == nil then
local workers = {}
for i = 1, 32 do
local actor = Instance.new("Actor")
script:Clone().Parent = actor
table.insert(workers, actor)
end
-- Parent all actors under self
for _, actor in workers do
actor.Parent = script
end
-- Instruct the actors to generate terrain by sending messages
-- In this example, actors are chosen randomly
task.defer(function()
local rand = Random.new()
local seed = rand:NextNumber()
local sz = 10
for x = -sz, sz do
for y = -sz, sz do
for z = -sz, sz do
workers[rand:NextInteger(1, #workers)]:SendMessage("GenerateChunk", x, y, z, seed)
end
end
end
end)
-- Exit from the original script; the rest of the code runs in each actor
return
end
function makeNdArray(numDim, size, elemValue)
if numDim == 0 then
return elemValue
end
local result = {}
for i = 1, size do
result[i] = makeNdArray(numDim - 1, size, elemValue)
end
return result
end
function generateVoxelsWithSeed(xd, yd, zd, seed)
local matEnums = {Enum.Material.CrackedLava, Enum.Material.Basalt, Enum.Material.Asphalt}
local materials = makeNdArray(3, 4, Enum.Material.CrackedLava)
local occupancy = makeNdArray(3, 4, 1)
local rand = Random.new()
for x = 0, 3 do
for y = 0, 3 do
for z = 0, 3 do
occupancy[x + 1][y + 1][z + 1] = math.noise(xd + 0.25 * x, yd + 0.25 * y, zd + 0.25 * z)
materials[x + 1][y + 1][z + 1] = matEnums[rand:NextInteger(1, #matEnums)]
end
end
end
return {materials = materials, occupancy = occupancy}
end
-- Bind the callback to be called in parallel execution context
actor:BindToMessageParallel("GenerateChunk", function(x, y, z, seed)
local voxels = generateVoxelsWithSeed(x, y, z, seed)
local corner = Vector3.new(x * 16, y * 16, z * 16)
-- Currently, WriteVoxels() must be called in the serial phase
task.synchronize()
workspace.Terrain:WriteVoxels(
Region3.new(corner, corner + Vector3.new(16, 16, 16)),
4,
voxels.materials,
voxels.occupancy
)
end)
On line 20, there is a task.defer(function()
that has some code inside of it that will run to procedurally generate some randomly smooth terrain. This… is what is supposed to happen. The problem is that when you remove the task.defer
, it won’t run. But if I put a print that is supposed to run after the block of code that is supposed to be inside of the task.defer
, the print will print whatever I put inside of it, but the terrain won’t generate. What is happening here? Why does this code need to be deferred in order to run, but the print still runs?