I am trying to make a way to store data in my game(I’m still new to it). The data seems to be saving(I haven’t tested yet). Every few seconds, at random it seems, I get this warning in the output:
Is this normal or is it something I can fix?
ModuleScript from DevHub:
-- Set up table to return to any script that requires this module script
local PlayerStatManager = {}
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")
-- Table to hold player information for the current session
local sessionData = {}
local AUTOSAVE_INTERVAL = 60
-- Function that other scripts can call to change a player's stats
function PlayerStatManager:ChangeStat(player, statName, value)
local playerUserId = "Player_" .. player.UserId
assert(typeof(sessionData[playerUserId][statName]) == typeof(value), "ChangeStat error: types do not match")
if typeof(sessionData[playerUserId][statName]) == "number" then
sessionData[playerUserId][statName] = sessionData[playerUserId][statName] + value
print(value)
else
sessionData[playerUserId][statName] = value
print(value)
end
end
-- Function to add player to the "sessionData" table
local function setupPlayerData(player)
local playerUserId = "Player_" .. player.UserId
local success, data = pcall(function()
return playerData:GetAsync(playerUserId)
end)
if success then
if data then
-- Data exists for this player
sessionData[playerUserId] = data
else
-- Data store is working, but no current data for this player
sessionData[playerUserId] = {Cash = 0}
end
else
warn("Cannot access data store for player!")
end
end
-- Function to save player's data
local function savePlayerData(playerUserId)
if sessionData[playerUserId] then
local tries = 0
local success
repeat
tries = tries + 1
success = pcall(function()
playerData:SetAsync(playerUserId, sessionData[playerUserId])
end)
if not success then wait(1) end
until tries == 3 or success
local success, err = pcall(function()
playerData:SetAsync(playerUserId, sessionData[playerUserId])
end)
if not success then
warn("Cannot save data for player!")
end
end
end
-- Function to save player data on exit
local function saveOnExit(player)
local playerUserId = "Player_" .. player.UserId
savePlayerData(playerUserId)
end
-- Function to periodically save player data
local function autoSave()
while wait(AUTOSAVE_INTERVAL) do
for playerUserId, data in pairs(sessionData) do
savePlayerData(playerUserId)
end
end
end
-- Start running "autoSave()" function in the background
spawn(autoSave)
-- Connect "setupPlayerData()" function to "PlayerAdded" event
game.Players.PlayerAdded:Connect(setupPlayerData)
-- Connect "saveOnExit()" function to "PlayerRemoving" event
game.Players.PlayerRemoving:Connect(saveOnExit)
return PlayerStatManager
Also, here is a script that updates the data:
local ting = 0 --debouncer
local thumbType = Enum.ThumbnailType.HeadShot
local thumbSize = Enum.ThumbnailSize.Size420x420
local Players = game:GetService("Players")
local C = game.Workspace:GetChildren()
local PlayerStatManager = require(game.ServerStorage.SaveScript)
for i = 1,#C do
if C[i].Name == "Poster" then
local P = C[i]:GetChildren()
for i = 1,#P do
if P[i]:IsA("SurfaceGui") then
imageLabel = P[i]:FindFirstChild("ImageLabel")
end
end
end
end
script.Parent.Touched:Connect(function(hit)
if ting == 0 then --debounce check
ting = 1 --activate debounce
local check = hit.Parent:FindFirstChild("Humanoid") --Find the human that touched the button
if check ~= nil then --If a human is found, then
local user = game.Players:GetPlayerFromCharacter(hit.Parent) --get player from touching human
local stats = user:findFirstChild("leaderstats") --Find moneyholder
if stats ~= nil then --If moneyholder exists then
local Cash = stats:findFirstChild("Cash") --Get money
Cash.Value = Cash.Value + 10000
PlayerStatManager:ChangeStat(user, "Cash", Cash.Value)
local ID = user.UserId
local userId = tonumber(ID)
local content, isReady = Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)
imageLabel.Image = content
wait(5)
script.Parent.Parent.EmployDoor.CanCollide = true
wait(30) --wait-time before button works again
script.Parent.Parent.EmployDoor.CanCollide = false
end
end
ting = 0 --remove debounce
end
end)