2.There appears to be an error the a numbervalue can’t be converted to a number
3.I have tried lots of solutions but none worked
here’s the script:
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Test")
local function saveData(player)
local tableToSave = {
player.leaderstats.Level.Value;
player.leaderstats.Exp.Value;
player.leaderstats.RequiredExp.Value;
}
local success, errorMessage = pcall(dataStore.SetAsync, dataStore, player.UserId, tableToSave)
if success then
print("Data has been saved")
else
print("Data has not been saved")
end
end
--Variables
game.Players.PlayerAdded:Connect(function(Player)
--Leaderstats
local leaderstats = Instance.new("Folder", Player)
leaderstats.Name = "leaderstats"
local Level = Instance.new("NumberValue", leaderstats)
Level.Name = "Level"
Level.Value = 1
local Exp = Instance.new("NumberValue", leaderstats)
Exp.Name = "Exp"
Exp.Value = 0
local RequiredExp = Instance.new("NumberValue", leaderstats)
RequiredExp.Name = "RequiredExp"
RequiredExp.Value = Level.Value ^ 10
-- Level up and Exp --
Exp.Changed:Connect(function(Changed)
if Exp.Value >= RequiredExp.Value then
Exp.Value = 0
Level.Value += 1
RequiredExp.Value = Level.Value ^ 10
print(RequiredExp.Value)
end
local data = nil
local success, errorMessage = pcall(function()
data = dataStore:GetAsync(Player.UserId)
end)
if success and data then
Player.leaderstats.Level.Value = data[1]
Player.leaderstats.Exp.Value = data[2]
Player.leaderstats.RequiredExp.Value = data[3]
else
print("Data has not been loaded")
end
end)
end)
game.Players.PlayerRemoving:Connect(function(player)
saveData(player)
end)
game:BindToClose(function()
for _, player in ipairs(game.Players:GetPlayers()) do
task.spawn(saveData, player)
end
end)
I can explain more in depth on why it is the same if you want. Just DM me!
Also, the OP should use ProfileService to reliably save data. It uses DatastoreService, but it wraps the whole system nicely so you have no problems. I like it.
Also, I found out the hard way that going with Datastore2 is a bad idea. It is simpler, but lacks key features you’ll need in the future, unlike ProfileService. If you’re not going to be making a full game out of this, you can go with the simplier Datastore2, but I wouldn’t recommend it anymore.
If anyone else can help here pls do … if this don’t work out, (it should).
I got it to load and save right. But ran into that request to queue warning …
It was from PlayerRemoving firing a save then also firing a save on BindToClose, as that was the only player there … So I just set up a return off the PlayerRemoving, if going to BindToClose save anyways. That took away the queue warning. I hope this is it … many prints you may want to remove.
tested attempt
local HttpService = game:GetService("HttpService")
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Test")
local saveQueue = {}
local function saveData(player)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
warn("Leaderstats not found for player " .. player.Name)
return
end
local dataToSave = HttpService:JSONEncode({
Level = leaderstats.Level.Value,
Exp = leaderstats.Exp.Value,
RequiredExp = leaderstats.RequiredExp.Value
})
if not dataToSave then
warn("Failed to encode data for player " .. player.Name)
return
end
local success, errorMessage = pcall(dataStore.SetAsync, dataStore, player.UserId, dataToSave)
if success then
print("Data has been saved for player " .. player.Name)
else
warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
end
end
local function saveAllData()
if #saveQueue == 0 then
return
end
local success, errorMessage
local batch = {}
for _, playerData in ipairs(saveQueue) do
table.insert(batch, {
key = playerData.Player.UserId,
value = playerData.Data
})
end
success, errorMessage = pcall(dataStore.SetAsync, dataStore, batch)
if not success then
warn("Failed to save data: " .. errorMessage)
end
saveQueue = {}
end
local function loadData(player)
local success, data = pcall(dataStore.GetAsync, dataStore, player.UserId)
if success and data then
local decodedData = HttpService:JSONDecode(data)
if type(decodedData) == "table" then
player.leaderstats.Level.Value = decodedData.Level or 1
player.leaderstats.Exp.Value = decodedData.Exp or 0
player.leaderstats.RequiredExp.Value = decodedData.RequiredExp or (player.leaderstats.Level.Value ^ 10)
print("Data loaded for player " .. player.Name)
else
warn("Data for player " .. player.Name .. " is invalid")
end
else
warn("Failed to load data for player " .. player.Name)
end
end
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
local Level = Instance.new("NumberValue", leaderstats)
Level.Name = "Level"
Level.Value = 1
local Exp = Instance.new("NumberValue", leaderstats)
Exp.Name = "Exp"
Exp.Value = 0
local RequiredExp = Instance.new("NumberValue", leaderstats)
RequiredExp.Name = "RequiredExp"
RequiredExp.Value = Level.Value ^ 10
Exp.Changed:Connect(function()
if Exp.Value >= RequiredExp.Value then
Exp.Value = 0
Level.Value += 1
RequiredExp.Value = Level.Value ^ 10
print("Player " .. player.Name .. " leveled up!")
end
end)
loadData(player)
end)
game.Players.PlayerRemoving:Connect(function(player)
local players = game.Players:GetPlayers()
if #players == 1 then
return
end
saveData(player)
print("Player " .. player.Name .. " is leaving. Saving data...")
end)
game:BindToClose(function()
for _, player in ipairs(game.Players:GetPlayers()) do
saveData(player)
end
saveAllData()
print("Server is shutting down. Saving data for all players...")
end)
delete data
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Test")
local function deleteAllData()
local success, errorMessage = pcall(dataStore.RemoveAsync, dataStore, "All")
if success then
print("All data has been deleted")
else
print("Failed to delete all data: " .. errorMessage)
end
end
deleteAllData()
You have to have a few things set up in Game Setting / Security
Allow HTTP Requests / on and Enable Studio Access to API Service / on
and also, Save to Roblox done after you add the script.
Run the delete data script once to clean all messed up data.
So you can start fresh …
I’d just like to point out you don’t need JSONEncode and JSONDecode when saving a dictionary/table to the DataStore. As long as the item consists only of booleans, numbers or strings, it will save just fine anyway.