Parallel Luau going very slowly

  1. What do you want to achieve?
    I would like to use parallel luau with my terrain generator to lighten the lag and increase the rate at which chunks are loaded in.

  2. What is the issue?
    I tried using parallel luau, though I think I’m doing it wrong. I saw an example where someone created a bunch of actors with bindable functions under them and bound a function to each and ran them. I tried to recreate this and surprisingly I had no lag on my old computer but the terrain is now generating incredibly slowly even though it’s not lagging the main game. It’s going at less than 1/30 the speed of running the terrain generator synchronized.

  3. What solutions have you tried so far?
    This is the main part of the current code:

for cx = 1, scale do
		-- Pause terrain generator every 1/yield times to reduce lag.
		local actor ="Actor", terrainActor)
		local bindable ="BindableFunction", actor)

		local function binded()
			for cz = 1, scale do
				-- Get Height
				local height = htab[cx][cz]
				local height1 = height+1

				local mcx = mats[cx]
				local ocx = occs[cx]

				for cy = -yScale, yScale do
					-- Generate material
					local mat = worldGen.getMaterial(cy, height)
					local tY = cy+yScale+1

					mcx[tY][cz] = mat

					-- Generate occupancy
					local val = worldGen.getOccupancy(cy, height, tY, x, z, cx, cz)

					ocx[tY][cz] = val

		bindable.OnInvoke = binded


	local region = genRegion(x, z)

	-- Create terrain
	terrainService:WriteVoxels(region, 4, mats, occs)

These are the relevant functions of the main script:

-- Get material for height.
worldGen.getMaterial = function(cy, height)
	cy = cy + yScale
	height = height + yScale

	if cy < height then
		if cy < height*0.2 then
			return basalt
		elseif cy < height*0.4 then
			return salt
		elseif cy < height*0.6 then
			return slate
		elseif cy < height*0.95 then
			return stone
			if cy > mountainZone then
				return stone
			elseif cy > fieldZone then
				return grass
				return sand
		if cy > yScale then
			return air
			return water

worldGen.getOccupancy = function(cy, height, tY, x, z, cx, cz)
	local val = 0

	if cy < math.floor(height) then
		val = 1
	elseif cy < height then
		val = height - cy
		-- v This creates a random object (or nothing) on the surface
		genDecoration(tY, x, z, cx, cy, cz)
	elseif cy <= 0 then
		val = 1

	return val

Sorry for the lack of comments on most of the code.

You’re toggling between synchronization and parallel quite often and there’s a limit to how many times it can switch in a set time period, that could be why. Also, you are now supposed to use task.wait() to re-sync the thread according to the announcement post?

I also heard something about bindable events being extremely slow when used in an unsynchronized thread, it might have something to do. I personally use attributes for communication between the threads

I re-read the post that I learned it from and apparently it was bindable events rather than bindable functions. I’ve fixed this but now the issue is that they aren’t synchronized again by the end and I am not sure how to wait until they are synchronized again (task.wait() doesn’t help).

You use task.wait() just as you would use task.synchronize(); run it right before performing serial tasks

I did but that didn’t do anything (I tested it both with and without) besides doing what a usual wait() would do.

I made it wait() until finishing the calculations (as determined by the actors being deleted so none would be left in the end). This ended up being a lot faster to the point where it was probably able to be used, but not nearly as fast as just running it in serial, still. The only thing that it really did was reduce the lag (as it barely lags the game at all doing this), though it is still way slower.