I’m writing my PlayerSetup script, to set up the leaderboard and player data when people connect, and for some reason, when loading data from my DataStore, it’s jumping to ‘success’, even though it’s apparently “attempting to index nil with a number”. I really can’t figure out what’s causing this.
PlayerSetup snippet
-- max height record
local maxHeight = Instance.new('IntValue')
maxHeight.Name = 'Record'
maxHeight.Parent = leaderstats
local data
local success, err = pcall(function()
data = playerDS:GetAsync(player.UserId)
end)
if success then
maxHeight.Value = data[1]
money.Value = data[2]
else
print("The player has no data!") -- will default to 0
end
(Note: It’s erroring on the maxHeight, no idea if ‘money’ will work or not.)
I don’t work with datastores very often, but from a cursory reading of your snippet, it appears that the issue would be that the data variable is not getting declared correctly. It’s evident that the call is being made from pcall properly (as the success state is obviously coming back true). Perhaps you might find this article helpful:
Alright! From what I remember from Datastores, usually calling a GetAsync on a key that doesn’t exist yet will just return nil instead of responding with an error, so the pcall is likely not erroring out. In the api reference, they achieve a similar effect using
local myGold
local success, err = pcall(function()
myGold = goldDataStore:GetAsync(playerKey) or STARTING_GOLD
end)
if success then
gold.Value = myGold
else
-- Failed to retrieve data
end
The “or” in the pcall initializes the value if the GetAsync is not storing a value for the specified key yet, and then the pcall is meant to protect against erroring in this situation.
But the error I’m getting seems to be that the… maxHeight is ‘nil’, not the datastore, actually…
‘trying to index nil with number’ sounds like it can’t find maxHeight. But putting player.CharacterAdded:Wait() in the script just causes it to hang.
Yeah, my guess is that the data variable is being assigned nil, and then when it tries to assign that to the int value it causes the error you’re seeing. Trying adding an “or 0” to the end of the GetAsync line and see if you get any more luck.
0[1] would error just like nil[1] does. The actual solution here is just checking if data exists and, if not, setting up default values for all its keys. Something like or {0, 0} would work.
@H_Baguette: pcall fails when it can’t retrieve data, not when it knows there is no data to receive.
I think this is your issue and why it isn’t working
local data -- data is nil here just setup variable
local success, err = pcall(function()
data = playerDS:GetAsync(player.UserId) -- this is accessing the datastore but returning nil because there is no data on the first Get... you have to save some data to return something other than nil
end)
if success then -- it is true because the datastore returned the GetAsync fine but it is Nil(data)
maxHeight.Value = data[1] -- then you are trying to access Nil here which is data with a number which is the [1]
money.Value = data[2]
else
print("The player has no data!") -- will default to 0
end
to fix this the below code should work by setting default data if there isn’t any
local data
local success, err = pcall(function()
data = playerDS:GetAsync(player.UserId)
end)
if success then
if data then -- player has data so load it into values
maxHeight.Value = data[1]
money.Value = data[2]
else -- player has no data so set some defaults
maxHeight.Value = 0
money.Value = 0
print("The player has no data!") -- will default to 0
end
else
print('The Datastore did not Load')
end
A few things that could help resolve this easier next time would be:
the save function part of the script so we can see how you are setting up and saving the actual data…
also is this a ordered datastore or just a normal one you are using
the full error you are getting
I should really stop trying to program when it’s five in the morning and I haven’t slept. Looking back on this thread, yeah, it seems pretty obvious what I was doing wrong. Thanks.