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.
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)
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.
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)
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.