Is MOST of the task and coroutine library useless?

Coroutines

I’ve been scripting for a while now, but I’ve literally never had to use coroutines ever,

l-- Function that runs in a coroutine
local function asyncTask()
    for i = 1, 5 do
        print("Task running: " .. i)
        task.wait(1)  -- Simulate a delay
    end
    print("Task completed")
end

-- Create a coroutine
local taskCoroutine = coroutine.create(asyncTask)

-- Start the coroutine
coroutine.resume(taskCoroutine)

print("Now I can run some other code down here aswell!")

Why not just do things in order the way you’re suppose to rather than doing multiple tasks at once?

I struggle to find any use cases of this, believe me I have made many systems and have been scripting for almost a year now but i’ve never had to use coroutines at ALL.

From what i’ve seen and done, it seems to me that basically the whole coroutine library is useless.

Task library

Now the task library is more useful, I definitely see the use of task.wait/task.delay and have used them alot. Those two are very useful.

Now the rest, I haven’t used at all really.

task.spawn starts a coroutine/function immediately through the engine scheduler, but is this really necessary? Again, haven’t had any need to start something THAT quickly. Usually code executes quite fast already in scripts, not sure why you would need to do that.

I guess some people I’ve seen want to make their while loops for example really fast? And the fastest they can do without crashing I guess would be to add task.spawn? Not sure why they’d want their loops to execute that quick though.

task.defer has a similiar behaviour to task.spawn so I won’t really get into that.

task.synchronize/task.desynchronize COULD be useful, I can’t really comment on those ones as I dont fully grasp the idea of parallel luau yet. But I will say that I haven’t had to use these two either and my games that I have worked on ran well and are fairly optimized.

I think the main one I see alot of people use is task.spawn though, which again don’t really see much use cases.

2 Likes

Also, I’m not hating on these libraries just for the sake of it. I wanna know more use cases of them and how useful they could be in certain systems or what not, I’ve tried my best to implement these if I could in anything but these just doesn’t seem to be useful in anything.

One use of task.spawn could be with datastores possibly, when calling getasync possibly? You might want to get the data quickly, but then again datastore limits.

By the way when I said code executes fast I meant if you don’t yield at all the code will run faster than the speed of light usually. So why use task.spawn?

coroutine.yield() and coroutine.running() can be used to pause a coroutine and store it somewhere to be resumed later, and coroutine.resume() can then be used to resume it. This can be useful if you want to create a custom event/signal class that has a :Wait() method.

Also, I would recommend using task.spawn() separately for every connected function in the fire/trigger method of a custom event/signal. Otherwise, if one of the connected functions yields, the others that haven’t yet been called will have their calling delayed potentially by a long time (depending on how long the yield is).

2 Likes

But again, any sort of systems that actually do this and need to use coroutines? All I can think of and all I can find are simple code samples instead of actual systems that may need coroutines.

Although it might not seem like it, think of how you would go about creating the Minigame system.

Task.spawn to manage time while loading the map

For coroutines, it’s hard to explain its purpose but it’s best known once you stepped out of your comfort zone and experience with things like creating some sort of shared data management module.

1 Like

I already have a minigame system, and haven’t really had to use this. Also, just realised that task.spawn literally does what a regular coroutine would do. But immediately? I guess coroutines are used to like yield or stop at certain times whereas task.spawn wouldn’t stop.

By the way wouldn’t it be worse using task.spawn/.coroutines for this? Since let’s say the map hasn’t loaded in time due to lag or what not. But the game is already starting, big problem. Versus just being in a serial execution.

1 Like

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