I try to create save data system but the system doesn’t work well. Are there any solutions?
Problem: when player rejoin the server, player’s Win and BeyPoints value are reset 100BP.
Notes: there are no error message.
local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")
local database = DataStoreService:GetDataStore("data")
local sessionData = {}
function PlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
--Win
local Win = Instance.new("IntValue")
Win.Name = "Win"
Win.Parent = leaderstats
--Points
local BeyPoints = Instance.new("IntValue")
BeyPoints.Name = "BeyPoints"
BeyPoints.Parent = leaderstats
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData=pcall(function()
return database:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(playerData)
task.wait(3)
end
until success or attempt == 5
if success then
print("Connected to database")
if not playerData then
print("Assignig default data")
playerData = {
["Win"] = 0,
["BeyPoints"] = 100
}
end
sessionData[player.UserId] = playerData
else
warn("Unable to get data for", player.UserId)
player:Kick("Try to connect server again :-O")
end
Win.Value = sessionData[player.UserId].Win
Win.Changed:Connect(function()
sessionData[player.UserId].Win = Win.Value
end)
BeyPoints.Value = sessionData[player.UserId].BeyPoints
BeyPoints.Changed:Connect(function()
sessionData[player.UserId].BeyPoints = BeyPoints.Value
end)
leaderstats.Parent = player
print(player, "is participating")
end
Players.PlayerAdded:Connect(PlayerAdded)
function PlayerLeaving(player)
if sessionData[player.UserId] then
local success = nil
local errorMsg = nil
local attempt = 1
repeat
success, errorMsg=pcall(function()
database:SetAsync(player.UserId, sessionData[player.UserId])
end)
attempt += 1
if not success then
warn(errorMsg)
task.wait(3)
end
until success or attempt == 5
if success then
print("Data saved for", player.Name)
else
warn("Unable t save for", player.Name)
end
end
print(player, "is leaving")
end
Players.PlayerRemoving:Connect(PlayerLeaving)
function ServerShutdoen()
if RunService:IsStudio() then
return
end
print("Server shutting down")
for i, player in ipairs(Players:GetPlayers()) do
--task.spawn(function()
PlayerLeaving(player)
--end)
end
end
game:BindToClose(ServerShutdoen)
Well, to start, the reason you may have no error messages is because you have a pcall wrapped around your data store’s GetAsync function:
If you remove the pcall (for now). See if there’s an error. I suspect that you don’t have that one setting enabled (forgot what it’s called for like the 20th time).
Think it was called “Enable API services for your game”.
Thank you for replying!
I just removed pcall, but basically there was no error message.
However, it seems that PlayerLeaving function doesn’t work and success remain nil.
If you are saving multiple values for each player you are probably trying to save a table, which you can not save in roblox datastores. To bypass this you have to convert the table into a JSON string when saving and when loading the JSON String you convert it into a table:
local httpService = game:GetService("HttpService")
local t = {1;2;"a"}
t = httpService:JSONEncode(t) -- Table to JSON
t = httpService:JSONDecode(t) -- JSON to Table
Thank you for replying!
But, I’ve never heard that JSON String and I can’t understand how to put this system into my code completly.
So, if you have a time, would you tell me how to put JSON String into my code concretely ?
local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")
local database = DataStoreService:GetDataStore("data")
local httpService = game:GetService("HttpService")
local sessionData = {}
function PlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
--Win
local Win = Instance.new("IntValue")
Win.Name = "Win"
Win.Parent = leaderstats
--Points
local BeyPoints = Instance.new("IntValue")
BeyPoints.Name = "BeyPoints"
BeyPoints.Parent = leaderstats
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData=pcall(function()
return database:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(playerData)
task.wait(3)
end
until success or attempt == 5
if success then
print("Connected to database")
if not playerData then
print("Assignig default data")
playerData = {
["Win"] = 0,
["BeyPoints"] = 100
}
else
playerData = httpService:JSONDecode(playerData)
sessionData[player.UserId] = playerData
end
else
warn("Unable to get data for", player.UserId)
player:Kick("Try to connect server again :-O")
end
Win.Value = sessionData[player.UserId].Win
Win.Changed:Connect(function()
sessionData[player.UserId].Win = Win.Value
end)
BeyPoints.Value = sessionData[player.UserId].BeyPoints
BeyPoints.Changed:Connect(function()
sessionData[player.UserId].BeyPoints = BeyPoints.Value
end)
leaderstats.Parent = player
print(player, "is participating")
end
Players.PlayerAdded:Connect(PlayerAdded)
function PlayerLeaving(player)
if sessionData[player.UserId] then
local success = nil
local errorMsg = nil
local attempt = 1
repeat
success, errorMsg=pcall(function()
database:SetAsync(player.UserId, httpService:JSONEncode(sessionData[player.UserId]))
end)
attempt += 1
if not success then
warn(errorMsg)
task.wait(3)
end
until success or attempt == 5
if success then
print("Data saved for", player.Name)
else
warn("Unable t save for", player.Name)
end
end
print(player, "is leaving")
end
Players.PlayerRemoving:Connect(PlayerLeaving)
function ServerShutdoen()
if RunService:IsStudio() then
return
end
print("Server shutting down")
for i, player in ipairs(Players:GetPlayers()) do
--task.spawn(function()
PlayerLeaving(player)
--end)
end
end
game:BindToClose(ServerShutdoen)