Hello, I have a major problem with my Datastore script.
Yesterday, I have tried remaking and optimizing it, as I was using Alvinblox’s tutorial for Datastore scripts and that lead me to making the mistake of calling GetAsync or SetAsync several times for each value.
I have worked with others in a server to produce this script as a result:
-- local DataStoreService = game:GetService("DataStoreService")
local NKODataStore = DataStoreService:GetDataStore("NKODataStore")
local leaderstatsFolderVals = {"Level", "Kills"}
local statsFolderVals = {"CoinAmount", "EXPAmount", "Kills"}
-- This would be data that would be provided if the player was new
local defaultData = {
["CoinAmount"] = 0,
["EXPAmount"] = 0,
["Kills"] = 0
}
local function createDataTable(plrObj)
-- Creates a table that is easier to save into a DataStore
local DataTable = {}
for _, name in ipairs(statsFolderVals) do
DataTable[name] = 0
end
return DataTable
end
local function GetKey(plrObj: Player)
return "user-"..plrObj.UserId
end
local function getDataFromDatastore(plrObj: Player)
-- Don't call getDataFromDatastore too often, as it counts against the rate limit
local success, data = pcall(function()
return NKODataStore:GetAsync(GetKey(plrObj))
end)
if not success then
-- Data could not be loaded
print("Data was not loaded.")
-- We return 'nil' to tell the scripts we have to stop what they're doing
return nil
end
if data == nil then
-- This player is new
return defaultData
end
-- There was data before, so we return it
return data
end
local function AddValues(plrObj: Player)
-- Creating NumberValues inside of Player.leaderstats
local leaderstats = Instance.new("Folder", plrObj)
leaderstats.Name = "leaderstats"
for _, valName in ipairs(leaderstatsFolderVals) do
local numVal: NumberValue = Instance.new("NumberValue")
numVal.Name = valName
numVal.Parent = leaderstats
end
-- Creating NumberValues inside of Player.Statistics
local Statistics = Instance.new("Folder", plrObj)
Statistics.Name = "Stats"
for _, statName in ipairs(statsFolderVals) do
local statVal: NumberValue = Instance.new("NumberValue")
statVal.Name = statName
statVal.Parent = Statistics
end
-- Now, we load the data from a datastore and set it to the NumberValues created before!
local SavedData = getDataFromDatastore(plrObj)
print(SavedData)
for name, val in pairs(SavedData) do
local valObj = Statistics:FindFirstChild(name)
if valObj then
valObj.Value = val
end
end
end
local function saveData(plrObj: Player)
local success, errorMsg = pcall(function()
NKODataStore:UpdateAsync(GetKey(plrObj), function(previousData)
-- :UpdateAsync() is much more safer to use, at the cost of having to use a callback
return createDataTable(plrObj.UserId)
end)
end)
if success then
print("Player data saved successfully")
else
-- Might wanna warn the player that their data couldn't be saved
print("There was an error while saving player data")
warn(errorMsg)
end
end
game.Players.PlayerAdded:Connect(AddValues)
game.Players.PlayerRemoving:Connect(saveData)
while true do
-- Save periodically
for _, plrObj in ipairs(game.Players:GetPlayers()) do
if plrObj ~= nil then
saveData(plrObj)
task.wait(5)
end
end
task.wait(90)
end
Now, the problem I have is that on this function here, on line 67. The table, SavedData is nil for some reason. Thus, it is not loading any data.
local SavedData = getDataFromDatastore(plrObj)
print(SavedData)
for name, val in pairs(SavedData) do
local valObj = Statistics:FindFirstChild(name)
if valObj then
valObj.Value = val
end
end
I would like to solve this error myself but frankly, I’m stumped, especially when it comes to tables.
Thanks!