I recently made a leaderstats datastore, but it consistently prints out an error message saying “value of type nil cannot be converted to a number” when I hop in a test session with 2 or more players. Can somebody tell me what the bug could be or what I’m doing wrong?
local deathdata, killdata, windata
local success, errormessage = pcall(function()
deathdata = ds:GetAsync("Deaths-"..player.UserId)
killdata = ds:GetAsync("Kills-"..player.UserId)
windata = ds:GetAsync("Wins-"..player.UserId)
end)
if success then
Deaths.Value = deathdata
Kills.Value = killdata
Wins.Value = windata
end
game.Players.PlayerRemoving:Connect(function(player)
local success, errormessage = pcall(function()
ds:SetAsync("Deaths-"..player.UserId,player:WaitForChild("leaderstats"):WaitForChild("Deaths"):WaitForChild("Value"))
ds:SetAsync("Kills-"..player.UserId,player:WaitForChild("leaderstats"):WaitForChild("Kills"):WaitForChild("Value"))
ds:SetAsync("Wins-"..player.UserId,player:WaitForChild("leaderstats"):WaitForChild("Wins"):WaitForChild("Value"))
end)
end)
I only pasted the section of the script I put leaderstats in
And yes, I have a playeradded linked to it, the script is written correctly I just didn’t paste the full thing since it’s quite lengthy and irrelevant to the issue.
Took me a bit of testing to figure out what was going on, but it was actually the way you saved your data. I had the errors the other way around, your data was nil not the death, kills, and win instances.
use .Value not :WaitForChild("Value") since it is an attribute of the instance. WaitForChild() is meant for pausing code to wait for an instance to load into the game.
Btw, you also shouldn’t need to really use WaitForChild() regardless since you’ve already loaded in their data when they first joined the game.
The original script didn’t have waitforchild, I implemented that as an attempt to fix the issue. Leaderstats works fine and saves fine when I run test in studio and ingame. It starts showing the nil value error after I start running studio sessions with multiple instances. Why is that?
The error is happening because deathdata and the other variables are nil. The problem lies in the code assuming that a successful data load means there is data to be read. Success might be true even though there is no data, which is causing the variables to be nil. You have to implement a system which checks if the data loaded is nil. As easy way to do it is as follows:
local deathdata, killdata, windata
local success, errormessage = pcall(function()
deathdata = ds:GetAsync("Deaths-"..player.UserId) or 0
killdata = ds:GetAsync("Kills-"..player.UserId) or 0
windata = ds:GetAsync("Wins-"..player.UserId) or 0
end)
The or 0 will set the value of the variable to 0 incase the value returned from the GetAsync function is nil. This ensures there is a default value.
Well the WaitForChild() is unnecessary and like I said only works to search for child instances (see documentation here). I ran the same code in studio (using .Value and not WaitForChild("Value")) and the code worked fine. You might be still receiving the error cause your values are still being saved as nil or haven’t been overwritten (if there is one player left, I recommend using game:BindToClose(), so the game saves the data before your server gets shut down).
Try using print() statements for the data when you retrieve it as well as before you save it to see if you are saving and retrieving proper values.