Is MOST of the task and coroutine library useless?

Hm, not sure what you mean here. I don’t really use httpservice much or have had to for anything so I guess that’s why.

I think I said this in a post I made a long time ago but task.spawn() is useful for making things like loading wheels/throbbers. For example:

local function EnableLoadingWheel()
    LoadingWheel.Rotation += 1
end


local function StartLoadingSomething()
    local thread = task.spawn(EnableLoadingWheel)
    --load something
    task.cancel(thread)
end

task.spawn() is also useful for saving player data in game:BindToClose() because of the 30 second time limit before the server shuts down.

2 Likes

Sometimes you need multiple different things to run at the same time, but one task will halt everything else if you do it sequentially. Here’s one use case I have:

image

The World_PlayerConnected function contains places where the entire thread will be halted in order to wait for something to finish and/or take place. If I were to run this without task.spawn, each player will have to wait for the previous player’s connector function to run and finish before their data can be set up and configured. For multiple players in a server, this could take upwards of a few seconds for each player. By wrapping the function in a separate thread, I can run the function for each player without worrying about one of them “taking too long” and halting the loop for everyone else


Adding onto what @PolyLacticSugarcane said, I actually have that implemented as well:

image

Without task.spawn, the process would look like this:

Run method [Player1] → wait → Run method [Player2] → wait → Run method [Player3] → wait → so on and so forth.

But for this method in particular, waiting like that may cause some players to lose their data because the loop simply didn’t reach them in the 30 seconds maximum yield time, hence why task.spawn is used here

2 Likes

elevator script with a countdown coroutine so task.wait doesn’t affect the main loop

These are nice examples but it seems that mostly task.spawn isn’t really used much, you guys reminded me of that time I did use task.spawn for a bindtoclose event for saving data.

task.spawn is basically a coroutine that you can’t stop from running once called it seems.

You can stop it with task.cancel(), look at the StartLoadingSomething() function I provided above.

1 Like

I’m just asking, is there any difference between coroutine and task?

1 Like

I don’t know much about coroutines so I’m not sure.

1 Like

Yes, I just meant that coroutine gives you more options. you could yield the thread isntead of straight up cancelling the whole thing if you want it to stop.

1 Like

task.spawn allows you to run multiple functions at once and is more versatile than coroutine

coroutine while not allowing you to run multiple functions at the same time allows for more control over execution flow within a single thread.

1 Like

The task library is attached to the Roblox Engine’s task scheduler; the coroutine library is a built-in Lua feature from Lua 5.1

You can use coroutines and the task library together since they operate similarly

2 Likes

What do you mean by run multiple functions? Can you give an example?

Wrong language sorry lol.

There aren’t many differences between coroutines and task.spawn to be honest.

A better explanation would be that, coroutines give you more options like I said before. task.spawn whereas doesn’t.

1 Like

coroutines fire code alongside a thread, task.spawn does it with the engine sheduler.

1 Like

I will say that the task library’s methods are a better (more optimized) replacement of the legacy wait, spawn, and delay methods, and it also contains task.desynchronize and task.synchronize methods, which allow you to run your code on multiple cpu cores as opposed to just one (which is the default)

Parallel Luau

1 Like

i noticed some people on this thread are running with the misconception that corotiunes actually run simultaneously, but that isn’t the case

corotiunes are done via cooperative multitasking, each “thread” works together (via yielding, which can be done by task.wait , coroutine.yield, or other functions that supports yielding the thread) in order to create an illusion that multiple things are being done at the same time on one thread

1 Like

Is MOST of the task and coroutine library useless?

No. All of them are very useful, with the task library being so similar in nature with the coroutine library with threads that I would say they are both interchangeable for most cases with a few differences.

There are a lot of posts and documentation describing both the task library and coroutine library, as well as the differences between them, that I would recommend checking them out. Posting every pros, cons, and differences would just be a repeat of what other people in the past have said. I would also highly suggest you reading up on deferred behavior and how it differs from immediate behavior (there’s even an official post about this somewhere) as they are important when it comes to Roblox’s game engine behavior and race conditions.

In terms of use cases, these are extremely vital to some systems to write the most efficient and bug-free code possible, you probably just haven’t seem them yet. Here are some examples of mine utilizing threads:

Slow falling
Seat timed destroy
Queue system and yielding behavior (the module I linked also uses deferring which they explain inside the code itself)

but i use task.spawn() in my pathfinding code :frowning:

heartbeatConnection = runService.Heartbeat:Connect(function()
	if #enemiesFolder:GetChildren() > 0 then
		local enemies = enemiesFolder:GetChildren()

		for _, enemy in ipairs(enemies) do
			if enemy.EnemyType.Value == "MELEE" then
				local detectionBox = enemy:FindFirstChild("DetectionPart")
				local humanoid = enemy:FindFirstChildOfClass("Humanoid")


				local closestPlayer = nil
				local LOS = workspace:GetPartBoundsInBox(detectionBox.CFrame, detectionBox.Size)

				for _, v in pairs(LOS) do
					if v.Parent:FindFirstChild("Humanoid") then
						local targetPlayer = game.Players:GetPlayerFromCharacter(v.Parent)

						if targetPlayer then
							if closestPlayer == nil or (enemy.HumanoidRootPart.Position - targetPlayer.Character.HumanoidRootPart.Position).Magnitude < (enemy.HumanoidRootPart.Position - closestPlayer.Character.HumanoidRootPart.Position).Magnitude then
								closestPlayer = targetPlayer
							end
						end
					end
				end

				task.spawn(function()
					if closestPlayer then
						local targetPosition = closestPlayer.Character.Torso.PathfindPart.Position
						pathfindingModule.melee(humanoid, targetPosition)
					else
						humanoid:MoveTo(enemy.HumanoidRootPart.Position)
					end
				end)
			end
		end
	end
end)

I did read up on the documentation about the libraries, I just couldn’t think of any use cases much to be honest. I guess i’ll see when I have to use these when I’m scripting.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.