How to properly wrap a function in a Coroutine?

This is a simple question so I’ll get right to the point: what’s the proper way to wrap an already existing function in your script into a coroutine? For example, if I wanted to save all player’s data before the server shuts down like this:

function SavePlayerData()
...
end

game:BindToClose(function()
       --How do I properly wrap the function above in a coroutine here?
end)

Some may be wondering why this question is necessary, and it’s simply because I don’t see a lot of documentation on this and I primarily use coroutines to create new functions and run them simultaneously.

I think you might be looking for task.spawn.

task.spawn(SavePlayerData)
1 Like

I’ve heard task.spawn can be unreliable and sometimes take up to 15 seconds to do, is that not true? I might be confusing it with another function…

I don’t quite know, I have typically just used coroutines, preferably coroutine.wrap, like:

coroutine.wrap(function() task.wait(10) print("After 10 seconds") end)()

But I don’t know how good and reliable this is.

That’s really rare and it shouldn’t happen, even with the older spawn (not task.spawn) that you miht be confusing it with.
What are you doing that you need SavePlayerData to be in a coroutine though?

Also for what it’s worth, you can do this pretty easily with coroutine.wrap

local SavePlayerData = coroutine.wrap(function()
...
end)

game:BindToClose(SavePlayerData)

but I still wonder why you need this.

I didn’t show it in this example, but the BindToClose function is iterating through each player and saving their data, hence why I’d need a coroutine for it.

game:BindToClose(function()
	for _, player in ipairs(players:GetPlayers()) do
		coroutine.wrap(saveStats(player)) --This is how I wrote it in the script although it doesn't seem to work consistently(?)
	end
end)

Unless you have an excessive amount of waits inside of your save function (which you probably shouldn’t have when the game is trying to shut down) you shouldn’t need coroutines. You should be able to just loop over the players and save all of their data at once. You should have the DataStore throughput for that.

1 Like

I have no waits in my function, and I thought that I would need to use coroutines so the saves don’t yield long enough for them to get cut off (even if that scenario is unlikely)

This is similar to how I typically save when the server closes

Yeah, I just use multi-threading for this, just in-case

1 Like

Unless something changed, coroutines aren’t truly asynchronous. They don’t utilize multiple CPU cores. They utilize task scheduling. So one line of code from the first coroutine will run, then a line of code from the second, a line of code from the third, and then it loops around to run another line of code from the first. It takes just as long, but it divides the processing time between them.

Also BindToClose allows you to yield for a few seconds, so it shouldn’t be an issue. Once the function returns, the game will shut down. In fact, if you use coroutines, the game may shut down immediately and cut off your data saving because the function returned before the code inside finished running.

3 Likes

I’ll do some tests here in a bit and if not using coroutines seems to work I’ll mark it as the solution, thanks.

2 Likes

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