so i am trying to make datastore so levels, currency and stuff like that will be saved everything saves normally except the Max Exp (which is used when exp hits the max exp value to tell that u have enough exp to level up) when i rejoin the game Max Exp is set to 0 which makes instant level up and beacuse level uping is making the max exp * by 2. 0 * 2 = 0 which means you get instant level ups everytime. i have no idea on how to fix this issue so please help me!
Script:
local DataStoreService = game:GetService("DataStoreService")
local LeaderstatsDataStore = DataStoreService:GetDataStore("leaderstatsDataStoreKey222333444")
game.Players.PlayerAdded:Connect(function(plr)
local leaderstats = Instance.new("Folder", plr)
leaderstats.Name = "leaderstats"
local Inventory = Instance.new("Folder", plr)
Inventory.Name = "Inventory"
local Money = Instance.new("IntValue", leaderstats)
Money.Name = "Money"
Money.Value = 0
local Level = Instance.new("IntValue", plr)
Level.Name = "Level"
Level.Value = 1
local Exp = Instance.new("IntValue", leaderstats)
Exp.Name = "Exp"
Exp.Value = 0
local MaxExp = Instance.new("IntValue", Level)
MaxExp.Name = "Max"
MaxExp.Value = 10
Exp.Changed:Connect(function(val)
if Exp.Value >= MaxExp.Value then
Level.Value += 1
Exp.Value = 0
MaxExp.Value *= 2
end
end)
local playerUserId = "Player_"..plr.UserId
local data = LeaderstatsDataStore:GetAsync(playerUserId)
if data then
Money.Value = data["Money"]
Level.Value = data["Level"]
Exp.Value = data["Exp"]
MaxExp.Value = data["Max"]
else
Money.Value = 0
Level.Value = 0
Exp.Value = 0
MaxExp.Value = 10
end
end)
local function create_table(player)
local player_stats = {}
for _, stat in pairs(player.leaderstats:GetChildren()) do
player_stats[stat.Name] = stat.Value
end
return player_stats
end
game.Players.PlayerRemoving:Connect(function(plr)
local player_stats = create_table(plr)
local success, errormessage = pcall(function()
local playerUserId = "Player_"..plr.UserId
LeaderstatsDataStore:SetAsync(playerUserId, player_stats)
end)
if not success then
print("save error")
warn(errormessage)
end
end)
You’re assuming the player’s saved data contains a “Max” entry, which is usually a fair assumption to make. However, you’re not actually saving the player’s max exp value.
local function create_table(player)
local player_stats = {}
for _, stat in pairs(player.leaderstats:GetChildren()) do
player_stats[stat.Name] = stat.Value
end
return player_stats
end
Your create table function parses all the data that is parented to the player’s leaderstats folder, but Max is not parented to that folder, it’s parented to Level. So when you call this function, it pulls all of the available data, except Max.
Instead of using :GetChildren() on the player’s leaderstats, I would use :GetDescendants() in order to get every value contained in that folder.
Edit:
Another glance at the code shows me that Level isn’t even parented to the player’s leaderstats, so that value isn’t being saved at all. You can either have level parented to leaderstats and implement the change I recommended, or modify your create_table function to fetch the Level and Max values.
It should be as simple as changing Level to be parented to leaderstats instead of the player and replacing GetChildren with GetDescendants, or you could add these two lines of code to your create_table function
You would need to create a function that can serialize the data within that folder so that it can be saved and another function that can parse the serialized data and recreate the inventory folder.
Let’s say your folder is composed entirely of BoolValues, where true represents that the player has the item and false represents that the player does not have the item.
Your two functions could look something like this
function serializeInventory (player)
local inventoryTable = {}
for _,v in pairs (player.Inventory:GetChildren ()) do
inventoryTable[v.Name] = v.Value
end
return inventoryTable
end
function createInventoryTable (player, serializedData)
for i,v in pairs (serializedData) do
local inventoryItem = Instance.new ("BoolValue")
inventoryItem.Name = i
inventoryItem.Value = v
inventoryItem.Parent = player.Inventory
end
end
This is just the basic idea behind saving and loading complex data. It’s up to you to take the concept and figure out how to apply it to your project.
well i have it like this but i now have no idea how to make this
local DataStoreService = game:GetService("DataStoreService")
local LeaderstatsDataStore = DataStoreService:GetDataStore("leaderstatsDataStoreKey222333444555666677")
local InventoryDataStore = DataStoreService:GetDataStore("INVENTORYDATASTOREBABEEEYY2344")
game.Players.PlayerAdded:Connect(function(plr)
local leaderstats = Instance.new("Folder", plr)
leaderstats.Name = "leaderstats"
local Inventory = Instance.new("Folder", plr)
Inventory.Name = "Inventory"
local Money = Instance.new("IntValue", leaderstats)
Money.Name = "Money"
Money.Value = 0
local Level = Instance.new("IntValue", plr)
Level.Name = "Level"
Level.Value = 0
local Exp = Instance.new("IntValue", leaderstats)
Exp.Name = "Exp"
Exp.Value = 0
local MaxExp = Instance.new("IntValue", Level)
MaxExp.Name = "Max"
MaxExp.Value = 10
Exp.Changed:Connect(function(val)
if Exp.Value >= MaxExp.Value then
Level.Value += 1
Exp.Value = 0
MaxExp.Value *= 2
end
end)
local playerUserId = "Player_"..plr.UserId
local data = LeaderstatsDataStore:GetAsync(playerUserId)
local data2 = InventoryDataStore:GetAsync(playerUserId)
if data2 then
Inventory = data["Inventory"]
else
end
if data then
Money.Value = data["Money"]
Level.Value = data["Level"]
Exp.Value = data["Exp"]
MaxExp.Value = data["Max"]
else
Money.Value = 666
Level.Value = 0
Exp.Value = 0
MaxExp.Value = 10
end
end)
local function create_table(player)
local player_stats = {}
for _, stat in pairs(player.leaderstats:GetChildren()) do
player_stats.Level = player.Level.Value
player_stats.Max = player.Level.Max.Value
player_stats[stat.Name] = stat.Value
end
return player_stats
end
local function create_table2(plar)
local plar_stats = {}
for _, stat in pairs(plar.Inventory:GetChildren()) do
local statclone = stat:Clone()
plar_stats[stat.Name] = stat
end
end
game.Players.PlayerRemoving:Connect(function(plr)
local player_stats = create_table(plr)
local plar_stats = create_table2(plr)
local success, errormessage = pcall(function()
local playerUserId = "Player_"..plr.UserId
LeaderstatsDataStore:SetAsync(playerUserId, player_stats)
InventoryDataStore:SetAsync(playerUserId, plar_stats)
end)
if not success then
print("save error")
warn(errormessage)
end
end)