Can you run 2 functions while 1 is active?

I have a data handler script that has 2 functions : 1. Loads data. 2. Saves data.

I put a while loop in the data load function

while task.wait(2) do
		cash.Value = cash.Value + 10
	end

Is this going to impact the save data function?
Should i take this while loop out of the function or what should i do? Make another script?

Either use a coroutine or spawn,

task.spawn(function()
   while task.wait(2) do
		cash.Value = cash.Value + 10
	end
end)
2 Likes

you can use the coroutine function to allow your 2 functions to run simultaneously;

coroutine.wrap(function()
	while task.wait(2) do
		cash.Value = cash.Value + 10
	end
end)()

)

Is there a more efficient way to add money every so often or should i just use coroutines? What happens if i have 2 loops in 2 different scripts?

task.spawn is perfectly fine, a minor optimization would be to use task.defer instead. The while loop is great depending on how you use it. You can have two loops as well. It’s important to note that this isn’t really running 2 functions “at the same time” roblox schedules each coroutine to happen when one function gives up control (task.wait gives up control in this case) allowing other coroutines to run

1 Like

The solutions provided are all perfectly fine to use, and these are the most efficient ways.

1 Like

This is my code, as much as i tested it, it works. Could i just leave it like this?

local datastoreservice = game:GetService("DataStoreService")

local datastore = datastoreservice:GetDataStore("cashnjoins")


game.Players.PlayerAdded:Connect(function (player)

	local folder = Instance.new("Folder")
	folder.Parent = player
	folder.Name = "leaderstats"

	local cash = Instance.new("IntValue")
	cash.Parent = folder
	cash.Name = "Cash"
	
	local joins = Instance.new("IntValue")
	joins.Parent = folder
	joins.Name = "Joins"
	
	local data
	local success, err = pcall(function()
	data = datastore:GetAsync(player.UserId)
	end)
	if success then
		print(data)
		print("Data received")
	else
		print(err)
	end
	if data == nil then
		cash.Value = 10
		joins.Value = 1
	else
		cash.Value = data.Cash + 10
		joins.Value = data.Joins + 1
	end
	
	while task.wait(2) do
		cash.Value = cash.Value + 10
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local data = {

		Cash = player.leaderstats.Cash.Value,
		Joins = player.leaderstats.Joins.Value

	}
	
	
	
	local success, err = pcall(function()
	
			datastore:SetAsync(player.UserId,data)
			
	end)
	if success then 
		print("Data Saved")
	else
		print("Error")
		print(err)
	end
end)

I recommend making a different script for this kind of thing, to lessen the load on the server, because the other approach such as spawn is that it adds a new function to the load which will keep increasing and there is no way to stop the loop if the player has left it would only cause an error.

So for my recommended approach it is basically one loop and inside of the loop is that it get’s every player on the server and increment their cash that is basically it.

Edit: Of course we could optimize this even further using module scripts where inside of the table are just the cash instance, and just loop that table. And also you have to remove the cash instance from the table if the player have left.

3 Likes

Slight change up for you:

local datastoreservice = game:GetService("DataStoreService")

local datastore = datastoreservice:GetDataStore("cashnjoins")


game.Players.PlayerAdded:Connect(function (player)

   local folder = Instance.new("Folder")
   folder.Parent = player
   folder.Name = "leaderstats"

   local cash = Instance.new("IntValue")
   cash.Parent = folder
   cash.Name = "Cash"
   
   local joins = Instance.new("IntValue")
   joins.Parent = folder
   joins.Name = "Joins"
   
   local data
   local success, err = pcall(function()
   data = datastore:GetAsync(player.UserId)
   end)
   if success then
   	print(data)
   	print("Data received")
   else
   	print(err)
   end
   if data == nil then
   	cash.Value = 10
   	joins.Value = 1
   else
   	cash.Value = data.Cash + 10
   	joins.Value = data.Joins + 1
   end
coroutine.wrap(function()
   while task.wait(2) do
   	cash.Value = cash.Value + 10
   end
end)()
end)

game.Players.PlayerRemoving:Connect(function(player)
   
   local data = {

   	Cash = player.leaderstats.Cash.Value,
   	Joins = player.leaderstats.Joins.Value

   }
   
   
   
   local success, err = pcall(function()
   
   		datastore:SetAsync(player.UserId,data)
   		
   end)
   if success then 
   	print("Data Saved")
   else
   	print("Error")
   	print(err)
   end
end)
1 Like

That works fine, :Connect creates a new coroutine for every player added. You will recieve errors when players leave the game (but nothing will break), since cash will be deleted, try adding this condition to the while; checking if cash and it’s parent are valid

while task.wait(2) and cash and cash.Parent do
    cash.Value += 10
end
1 Like

Oooh that clears up a lot, cause i always wondered how do functions work together at the same time.

I’ve made a graph before that can help visualize it a little better. A common issue is programmers not knowing what functions are “Yielding” (i.e. they give up control of the thread), for example datastore:GetAsync is a yielding function, so other scripts and coroutines can run while it’s waiting for datastore data to come back, if the player leaves immediately then any player, cash, or joins uses will result in an error. Of course in your :Connected function such an error will not break anything else.

1 Like

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