With your current code you are always assuming the players data exists when they join the game. This creates the issue that you have currently because the GetAsync function returns nil because their isn’t any data set to the key. This is why you should check if there is data already set to that key and if there isn’t you will need to set data to that key. Here is a really quick mock of something you could do to check if the players data exists:
local Success, Result = pcall(function()
return datastore:GetAsync(tostring(player.UserId))
end)
if Success then
if Result ~= nil then -- Checks if the players stats exist
-- In this case the players stats exist.
else
-- In this case the players stats don't exist so you need to set them:
datastore:SetAsync(tostring(player.UserId), defultStats) -- Creates a new key.
-- Do the relevant stuff to give the player their stats, in this case it will be the defult stats
end
else
warn("Something went wrong while loading data")
end
The code above loads the data set to the key and then if there is no data set to it then it will set the default stats to it.
GetAsync() only takes one parameter, the key. You send two? I think you meant to do this:
local data = datastore:GetAsync(player.UserId) or playerData
This way you get their stats or default to the starter if the DataStore is empty. Also, you should pcall it in case of DataStore errors, as the above reply shows.