I wrote a datastore module, yet I keep getting the error above when attempting to write to the datastore on value change.
Module:
local dataStoreService = game:GetService("DataStoreService")
local playerDataStore = dataStoreService:GetDataStore("GameData")
local ON_COOLDOWN = false
local COOLDOWN_DURATION = 7
local function getDataTemplate()
return {
Gems = 0;
Taps = 0;
Rebirths = 0;
}
end
local function deepCopy(original)
local copy = {}
for k, v in pairs(original) do
if type(v) == "table" then
v = deepCopy(v)
end
copy[k] = v
end
return copy
end
local function reconcileTable(target, template)
for k, v in pairs(template) do
if type(k) == "string" then -- Only string keys will be reconciled
if target[k] == nil then
if type(v) == "table" then
target[k] = deepCopy(v)
else
target[k] = v
end
elseif type(target[k]) == "table" and type(v) == "table" then
reconcileTable(target[k], v)
end
end
end
end
local data = {}
data._playerData = {}
function data:GetPlayerKey(player)
assert(type(player) == "userdata")
local key = "Player_" .. player.UserId
return key
end
function data:GetPlayerData(player)
if self._playerData[player] then return self._playerData[player] end
local playerKey = self:GetPlayerKey(player)
local attempts = 0
local playerData = nil
local success,message
repeat
attempts = attempts + 1
success,message = pcall(function() playerData = playerDataStore:GetAsync(playerKey) end)
if not success then
warn("Failed to load data ! Error: " .. message)
wait(3)
end
until success or attempts >= 5
if success then
local template = getDataTemplate()
if data then
reconcileTable(data,template)
self._playerData[player] = data
return data
else
print("New Player")
self._playerData[player] = template
return template
end
else
warn("Failed to load PlayerData. Using default template...")
self._playerData[player] = getDataTemplate()
return getDataTemplate()
end
end
function data:FetchData(player)
if self._playerData[player] then
return self._playerData[player]
else
warn("No data exists for Player " .. player.Name .. ".")
return getDataTemplate() or nil
end
end
function data:UpdateValue(player,valName,newVal)
print("Update Called")
if not self._playerData[player] then return end
if not self._playerData[player][valName] then print("UH OH!")return end
self._playerData[player][valName] = newVal
print("Updated !")
if not ON_COOLDOWN then
ON_COOLDOWN = true
local key = self:GetPlayerKey(player)
local success,message = pcall(function() playerDataStore:SetAsync(key, self._playerData[player]) end)
if not success then
warn("Failed to SetAsync PlayerData ! Error: " .. message)
end
coroutine.resume(coroutine.create(function()
wait(COOLDOWN_DURATION)
ON_COOLDOWN = false
end))
end
end
function data:SavePlayerData(player)
if not self._playerData[player] then return end
local newData = self._playerData[player]
self._playerData[player] = nil
local attempts = 0
local success,message
local key = self:GetPlayerKey(player)
repeat
attempts = attempts + 1
success,message = pcall(function() playerDataStore:UpdateAsync(key, function(old) return newData end) end)
if not success then
warn("Failed to save PlayerData ! Error: " .. message)
wait(7)
end
until success or attempts >= 5
end
return data
No errors, except in the output.