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.
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:
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:
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
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.
I’m just asking, is there any difference between coroutine and task?
I don’t know much about coroutines so I’m not sure.
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.
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.
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
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.
coroutines
fire code alongside a thread, task.spawn
does it with the engine sheduler.
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)
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
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
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.