Except my data store doesn’t properly save the leaderstats because I have printed the amount of coins you have and when I exit the game it says it has saved 0 coins. Any Solutions?
Script:
local mainDS = DSS:GetDataStore("CoinsData") -- Name of DataStore, can change for future projects
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:FindFirstChild("Events")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
local coins = Instance.new("IntValue", leaderstats)
coins.Name = "Coins"
local data = mainDS:GetAsync(player.UserId)
if data then
if data[1] then
coins.Value = data[1]
end
end
print("Data Loaded " ..coins.Value)
end)
game.Players.PlayerRemoving:Connect(function(player)
local leaderstats = player:WaitForChild("leaderstats")
local coins = leaderstats:WaitForChild("Coins")
mainDS:SetAsync(player.UserId, {coins.Value})
print("Data Saved " ..coins.Value)
end)
ProfileService will save the data more safely than DataStoreService.
DataStoreService saves user’s data to server. but it’s inefficient.
ProfileService saves the data to user profile. so it’s more efficient than DataStoreService.
Anyway, read more INFOS in the link.
You need ProfileService module and DataManager module. This is pretty complicated.
So I’ll give you a script:
local Players = game:GetService("Players")
local ProfileService = require(script.ProfileService)
local DATA_TEMPLATE = {
--Money = 500;
}
local ProfileStore = ProfileService.GetProfileStore("LeaderStatsStore", DATA_TEMPLATE)
local Profiles = {}
local function HandleLockedUpdate(globalUpdates, update)
local id = update[1]
local data = update[2]
globalUpdates:ClearLockedUpdate(id)
end
local function OnPlayerAdded(player)
local profile = ProfileStore:LoadProfileAsync(
"Player_"..player.UserId,
"ForceLoad"
)
if profile then
profile:AddUserId(player.UserId)
profile:Reconcile()
profile:ListenToRelease(function()
Profiles[player] = nil
player:Kick()
end)
if player:IsDescendantOf(Players) then
Profiles[player] = profile
local globalUpdates = profile.GlobalUpdates
for index, update in pairs(globalUpdates:GetActiveUpdates())do
globalUpdates:LockActiveUpdate(update[1])
end
for index, update in pairs(globalUpdates:GetLockedUpdates())do
HandleLockedUpdate(globalUpdates, update)
end
globalUpdates:ListenToNewActiveUpdate(function(id, data)
globalUpdates:LockActiveUpdate(id)
end)
globalUpdates:ListenToNewLockedUpdate(function(id, data)
HandleLockedUpdate(globalUpdates, {id, data})
end)
else
profile:Release()
end
else
player:Kick("Data Loading Failed.")
end
end
Players.PlayerAdded:Connect(OnPlayerAdded)
local function OnPlayerRemoving(player)
local profile = Profiles[player]
if profile then
profile:Save()
profile:Release()
end
end
Players.PlayerRemoving:Connect(OnPlayerRemoving)
local DataManager = {}
function DataManager:GetData(player)
local profile = Profiles[player]
if profile then
return profile.Data
else
return nil
end
end
function DataManager:GetProfileStore()
return ProfileStore
end
function DataManager:UpdateData(player, key, data)
local profile = Profiles[player]
profile.Data[key] = data
end
function DataManager:SaveData(player)
Profiles[player]:Save()
end
return DataManager
Please insert ProfileService module into DataManager module.
Now, call DataManager module by LeaderBoard script:
local DataManager = require(script.DataManager)
local DataNames = {
--Money = 500; -- You should put the data names same as which you put in DATA_TEMPLATE in DataManager module.
}
game.Players.PlayerAdded:Connect(function(player)
local Data = DataManager:GetData(player)
while Data == nil do
task.wait()
Data = DataManager:GetData(player)
end
local function OnValueChanged(key ,valueObjectValue)
DataManager:UpdateData(player, key, valueObjectValue)
end
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
for k, v in pairs(DataNames)do
local dataValue = Data[k]
if not dataValue then
continue
end
local dataType = type(dataValue)
local ValueObject
if dataType == "number" then
ValueObject = Instance.new("NumberValue")
elseif dataType == "string" then
ValueObject = Instance.new("StringValue")
elseif dataType == "boolean" then
ValueObject = Instance.new("BoolValue")
end
ValueObject.Name = v
ValueObject.Value = dataValue
ValueObject.Parent = leaderstats
ValueObject.Changed:Connect(function()
OnValueChanged(k ,ValueObject.Value)
end)
end
end)
Please insert DataManager module into LeaderBoard script.