Coroutine not working

Hello,

What is this

That is required for executing the coroutine obviously. That is the reason why your coroutine wasn’t working in the first place.

Hello,

It sometimes works but not in a way that you might expect. It seems like the playerremoved works but the bindtoclose coroutine does not. (coroutine does not work at all)


As you can see, this is an unreliable and ineffective method to save data as it sometimes doesn’t work.

Can you show your latest code? please don’t give a screenshot, its hard for us to modify and give some of the code like that.

You should also use pcalls while saving/loading to avoid data load failures, which can result in data loss.

Hello,

local datastore = game:GetService("DataStoreService")
local moneystore = datastore:GetDataStore("Stats")
game.Players.PlayerAdded:Connect(function(p)
	local leader = Instance.new("IntValue",p)
	leader.Name = "leaderstats"
	local mon = Instance.new("NumberValue",leader)
	mon.Name = "Money"
	local so = Instance.new("StringValue",leader)
	so.Name = "Job"
	local ren = Instance.new("NumberValue",leader)
	ren.Name = "Reputation"
	local gor = moneystore:GetAsync(p.UserId)
	if gor~=nil then
		mon.Value = gor[1]
		so.Value = gor[2]
		ren.Value = gor[3]
	else
		gor = {mon.Value,so.Value,ren.Value}
	end
	for i,v in pairs(script.Notice:GetChildren()) do
		local sog = v:Clone()
		sog.Parent = p
	end
end)
game.Players.PlayerRemoving:Connect(function(p)
	moneystore:SetAsync(p.UserId,{p.leaderstats.Money.Value,p.leaderstats.Job.Value,p.leaderstats.Reputation.Value})
	print('sag')
end)
local function save(v)
	coroutine.wrap(function()
		moneystore:SetAsync(v.UserId,{v.leaderstats.Money.Value,v.leaderstats.Job.Value,v.leaderstats.Reputation.Value})
		print('jiesh')
	end)()
end
game:BindToClose(function()
	for i,v in pairs(game.Players:GetPlayers()) do
		save(v)
	end
end)

Everything seems pretty good, although you need to implement the use of pcalls in your script. To handle errors properly, and you can do like a repeat loop till data is saved successfully too.

Really simple Example, to get an idea:

local success, response
local tries = 0
 
local function saveData()
    local saveData = {v.leaderstats.Money.Value,v.leaderstats.Job.Value,v.leaderstats.Reputation.Value}
    success, response = pcall(moneystore.SetAsync, moneystore, v.UserId, saveData)
    tries += 1
end

repeat 
  wait(7) --So that you don't hit limit of 6 second gap.
  saveData()
until success == true or tries >= 3 --Will try 3 tries to save on max, or till you are not successful saving data.
1 Like

you forgot to use coroutine.resume

Hello,
Unfortunately, the example you have given does not solve my coroutine problem.

Hello,
Where would I put coroutine.resume

local function save(v)
local a = coroutine.wrap(function()
moneystore:SetAsync(v.UserId,{v.leaderstats.Money.Value,v.leaderstats.Job.Value,v.leaderstats.Reputation.Value})
print(‘jiesh’)
end)
coroutine.resume(a)
end

It was to be taken as an example and get an idea, not copy paste that code (If you did, not sure), I really recommend you getting more understanding of what is causing the problem. The coroutine isn’t what is really causing the problem. Make sure you aren’t getting any error in console, if you’re post them here so we can see the error.


@VeinTweek coroutine.wrap doesn’t return the newly created thread, it just returns the function so that will result in an error.

2 Likes

Hello,
This does not seem to work.

Hello,

Your method does not seem to work, and freezes studio.

local datastore = game:GetService("DataStoreService")
local moneystore = datastore:GetDataStore("Stats")
game.Players.PlayerAdded:Connect(function(p)
	local leader = Instance.new("IntValue",p)
	leader.Name = "leaderstats"
	local mon = Instance.new("NumberValue",leader)
	mon.Name = "Money"
	local so = Instance.new("StringValue",leader)
	so.Name = "Job"
	local ren = Instance.new("NumberValue",leader)
	ren.Name = "Reputation"
	local gor = moneystore:GetAsync(p.UserId)
	if gor~=nil then
		mon.Value = gor[1]
		so.Value = gor[2]
		ren.Value = gor[3]
	else
		gor = {mon.Value,so.Value,ren.Value}
	end
	for i,v in pairs(script.Notice:GetChildren()) do
		local sog = v:Clone()
		sog.Parent = p
	end
end)
game.Players.PlayerRemoving:Connect(function(p)
	moneystore:SetAsync(p.UserId,{p.leaderstats.Money.Value,p.leaderstats.Job.Value,p.leaderstats.Reputation.Value})
	print('sag')
end)
local success, response
local tries = 0
local function save(v)
	local a = coroutine.wrap(function()
		pcall(moneystore.SetAsync, moneystore, v.UserId, {p.leaderstats.Money.Value,p.leaderstats.Job.Value,p.leaderstats.Reputation.Value})
		print('jiesh')
	end)
	tries += 1
end
game:BindToClose(function()
	repeat
		wait(7)
		for i,v in pairs(game.Players:GetPlayers()) do
			save(v)
		end
	until success == true or tries >= 3
end)

As per your current script, doesn’t look like you’re even understanding the basics. I mean like you need to use some logic in this case.

Some mistakes I found out with a look:

  1. You aren’t executing the coroutine again, even though I already showed how to.
  2. I had shown you to retry the save function if failed, what you’re doing is just infinite loop it around all the players and running save function inside it, of course resulting in a crash.
  3. You aren’t even setting the success and response variable to the pcall’s return value.
  4. You’re trying to reference the variable p in the save function, which isn’t defined.

What you should be doing is something like this:

local datastore = game:GetService("DataStoreService")
local moneystore = datastore:GetDataStore("Stats")

game.Players.PlayerAdded:Connect(function(p)
	local leader = Instance.new("IntValue",p)
	leader.Name = "leaderstats"
	local mon = Instance.new("NumberValue",leader)
	mon.Name = "Money"
	local so = Instance.new("StringValue",leader)
	so.Name = "Job"
	local ren = Instance.new("NumberValue",leader)
	ren.Name = "Reputation"
	local gor = moneystore:GetAsync(p.UserId)
	if gor~=nil then
		mon.Value = gor[1]
		so.Value = gor[2]
		ren.Value = gor[3]
	else
		gor = {mon.Value,so.Value,ren.Value}
	end
	for i,v in pairs(script.Notice:GetChildren()) do
		local sog = v:Clone()
		sog.Parent = p
	end
end)

local function save(v)
	coroutine.wrap(function()
		local success, response
		local tries = 0
		local saveData = {v.leaderstats.Money.Value,v.leaderstats.Job.Value,v.leaderstats.Reputation.Value}

		success, response = pcall(moneystore.SetAsync, moneystore, v.UserId, saveData)

		repeat
            wait(7)
			success, response = pcall(moneystore.SetAsync, moneystore, v.UserId, saveData)
			tries += 1
		until not success or tries < 3 
	end)()
end


game.Players.PlayerRemoving:Connect(function(p)
	save(p)
end)

game:BindToClose(function()
	for i,v in pairs(game.Players:GetPlayers()) do
		save(v)
	end
end)

Hello,
The solution you gave is still not working.

local datastore = game:GetService("DataStoreService")
local moneystore = datastore:GetDataStore("Stats")

game.Players.PlayerAdded:Connect(function(p)
	local leader = Instance.new("IntValue",p)
	leader.Name = "leaderstats"
	local mon = Instance.new("NumberValue",leader)
	mon.Name = "Money"
	local so = Instance.new("StringValue",leader)
	so.Name = "Job"
	local ren = Instance.new("NumberValue",leader)
	ren.Name = "Reputation"
	local gor = moneystore:GetAsync(p.UserId)
	if gor~=nil then
		mon.Value = gor[1]
		so.Value = gor[2]
		ren.Value = gor[3]
	else
		gor = {mon.Value,so.Value,ren.Value}
	end
	for i,v in pairs(script.Notice:GetChildren()) do
		local sog = v:Clone()
		sog.Parent = p
	end
end)

local function save(v)
	coroutine.wrap(function()
		local success, response
		local tries = 0
		local saveData = {v.leaderstats.Money.Value,v.leaderstats.Job.Value,v.leaderstats.Reputation.Value}

		success, response = pcall(moneystore.SetAsync, moneystore, v.UserId, saveData)

		repeat
            wait(7)
			success, response = pcall(moneystore.SetAsync, moneystore, v.UserId, saveData)
			tries += 1
		until not success or tries < 3 
	end)()
end


game.Players.PlayerRemoving:Connect(function(p)
	save(p)
end)

game:BindToClose(function()
	for i,v in pairs(game.Players:GetPlayers()) do
		save(v)
	end
end)

Are you sure the script is saved and then the game is run? Are you sure the API Services are turned on in studio? Use the pcalls while loading data too, to ensure its loading the data without any errors. Try and see if it works in Roblox player but not studio.

Also wanted to ensure that you’re updating your data from the server side.

I also don’t recommend you to copy paste, first you need to have an understanding of what the code does.

Hello,
Yes, yes, yes.
I don’t even know how you manage to not save a script, or ever heard of the concept of saving scripts.
API services are obviously turned on in studio or else my leaderstats would just be 0.
Can’t you just give me a solution right on out? I don’t need pcalls if I have a solution right here.
Also, the code you wrote above for me is supposed to be a viable solution, and yes, I do have understanding of what the code does.
The problem is that the coroutine is not running at all, or it would print ‘jiesh’ in the earlier versions of my code.

If you’re imagining the devforum scripting category to write out your scripts with 100% perfection and no errors, then stop with that thought. This category is here to help you with the solution, what you’re thinking of solution is just copy pasting code in my opinion.

Anyways to the point, the reason your coroutine isn’t executing is because when you do coroutine.wrap around a function, it just makes a new thread for that function, but you will need to execute it as a function. Which I have told about 3 times yet, but your script didn’t seem to have the same changes.

Also just tested out the script that I had modified and given (the latest one), and it seems to work fine, it loads the data and everything is good. The most obvious mistake here that you can make is that, you’re updating the data from client side.

After you’ve made sure everything is like that, if you could give your latest code, then we can help you debug that code, because it doesn’t seem like you’re following up.

Hello,
There is absolutely nothing supporting the opinion in which my data is being saved on the client side. I have several videos showing that this is done in and only in a serverscript located in serverscriptservice.
Datastore literally cannot be accessed on the client side and will always give an error when doing so, which there is not.
Back to the topic, I’m sorry that I don’t know anything about coroutines and still don’t know. I don’t even know what a “thread” is or where to put resume or what it does. I’m just using my prior knowledge and quick reads on the developer hub to understand your replies to the best of my ability.
In addition, I don’t know what pcall does, where and how to use it, and what it’s used for.

Hello,
This is my code so far. I used pcall for the function.

local datastore = game:GetService("DataStoreService")
local moneystore = datastore:GetDataStore("Stats")

game.Players.PlayerAdded:Connect(function(p)
	local leader = Instance.new("IntValue",p)
	leader.Name = "leaderstats"
	local mon = Instance.new("NumberValue",leader)
	mon.Name = "Money"
	local so = Instance.new("StringValue",leader)
	so.Name = "Job"
	local ren = Instance.new("NumberValue",leader)
	ren.Name = "Reputation"
	local gor = moneystore:GetAsync(p.UserId)
	if gor~=nil then
		mon.Value = gor[1]
		so.Value = gor[2]
		ren.Value = gor[3]
	else
		gor = {mon.Value,so.Value,ren.Value}
	end
	for i,v in pairs(script.Notice:GetChildren()) do
		local sog = v:Clone()
		sog.Parent = p
	end
end)

local function save(v)
	pcall(coroutine.wrap(function()
		local success, response
		local tries = 0
		local saveData = {v.leaderstats.Money.Value,v.leaderstats.Job.Value,v.leaderstats.Reputation.Value}

		success, response = pcall(moneystore.SetAsync, moneystore, v.UserId, saveData)

		repeat
			wait(7)
			success, response = pcall(moneystore.SetAsync, moneystore, v.UserId, saveData)
			tries += 1
		until not success or tries < 3 
	end)())
end


game.Players.PlayerRemoving:Connect(function(p)
	save(p)
end)

game:BindToClose(function()
	for i,v in pairs(game.Players:GetPlayers()) do
		save(v)
	end
end)


It gives this error:
00:03:44.900 ServerScriptService.Script:28: missing argument #1 - Server - Script:28