local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local perksStore = DataStoreService:GetDataStore("PerksStore")
local PerksEvent = ReplicatedStorage:FindFirstChild("PerksEvent")
local defaultData = {
owned = {},
equipped = {},
points = 0,
}
local function saveData(player, data)
if not data then
warn("not saved", player.Name)
return
end
print("saving:", player.Name, data)
local success, err = pcall(function()
perksStore:SetAsync("perks_"..player.UserId, data)
end)
print("Saved:", success, err)
end
local function loadData(player)
print("loading data", player.Name)
local data
local success, err = pcall(function()
data = perksStore:GetAsync("perks_"..player.UserId)
end)
print("results lol", success, err, data)
if success and data then
return data
else
return table.clone(defaultData)
end
end
Players.PlayerAdded:Connect(function(player)
local data = loadData(player)
local json = HttpService:JSONEncode(data)
player:SetAttribute("PerksData", json)
PerksEvent:FireClient(player, data)
end)
Players.PlayerRemoving:Connect(function(player)
local str = player:GetAttribute("PerksData")
if str then
local data = HttpService:JSONDecode(str)
saveData(player, data)
end
end)
game:BindToClose(function()
for _, player in ipairs(Players:GetPlayers()) do
local str = player:GetAttribute("PerksData")
if str then
local data = HttpService:JSONDecode(str)
saveData(player, data)
end
end
end)
PerksEvent.OnServerEvent:Connect(function(player, action, perkName)
local str = player:GetAttribute("PerksData")
if not str then return end
local data = HttpService:JSONDecode(str)
if action == "Buy" then
if data.points > 0 and not table.find(data.owned, perkName) then
table.insert(data.owned, perkName)
data.points -= 1
end
elseif action == "Equip" then
if table.find(data.owned, perkName) and not table.find(data.equipped, perkName) then
table.insert(data.equipped, perkName)
end
elseif action == "Unequip" then
for i, v in ipairs(data.equipped) do
if v == perkName then
table.remove(data.equipped, i)
break
end
end
elseif action == "Request" then
PerksEvent:FireClient(player, data)
return
end
local json = HttpService:JSONEncode(data)
player:SetAttribute("PerksData", json)
saveData(player, data)
PerksEvent:FireClient(player, data)
end)
Version two..
This may work for you
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local perksStore = DataStoreService:GetDataStore("PerksStore")
local PerksEvent = ReplicatedStorage:WaitForChild("PerksEvent")
local defaultData = {owned = {}, equipped = {}, points = 0}
local db = {}
local function saveData(player, data)
if not data then return end
local key = "perks_"..player.UserId
db[player.UserId] = true
pcall(function()
perksStore:UpdateAsync(key, function() return data end)
end)
db[player.UserId] = nil
end
local function loadData(player)
local key = "perks_"..player.UserId
local ok, data = pcall(function() return perksStore:GetAsync(key) end)
return (ok and data) or table.clone(defaultData)
end
Players.PlayerAdded:Connect(function(player)
local data = loadData(player)
player:SetAttribute("PerksData", HttpService:JSONEncode(data))
PerksEvent:FireClient(player, data)
end)
Players.PlayerRemoving:Connect(function(player)
local str = player:GetAttribute("PerksData")
if str then
saveData(player, HttpService:JSONDecode(str))
else
saveData(player, loadData(player))
end
end)
game:BindToClose(function()
for _, player in ipairs(Players:GetPlayers()) do
local str = player:GetAttribute("PerksData")
if str then
saveData(player, HttpService:JSONDecode(str))
else
saveData(player, loadData(player))
end
end
end)
PerksEvent.OnServerEvent:Connect(function(player, action, perkName)
local str = player:GetAttribute("PerksData")
if not str then return end
local data = HttpService:JSONDecode(str)
if action == "Buy" then
if data.points > 0 and not table.find(data.owned, perkName) then
table.insert(data.owned, perkName)
data.points -= 1
end
elseif action == "Equip" then
if table.find(data.owned, perkName) and not table.find(data.equipped, perkName) then
table.insert(data.equipped, perkName)
end
elseif action == "Unequip" then
for i, v in ipairs(data.equipped) do
if v == perkName then
table.remove(data.equipped, i)
break
end
end
elseif action == "Request" then
PerksEvent:FireClient(player, data)
return
end
player:SetAttribute("PerksData", HttpService:JSONEncode(data))
if not db[player.UserId] then saveData(player, data) end
PerksEvent:FireClient(player, data)
end)
Slight modification.. Make sure nothing is trying to save nil. Print check that.
This is forums scripting help.. Post something constructive or not at all..
Still not saving perks when i buy
Is API access is enabled, so it can work with the datastore?
Because Attributes can’t store tables idk friend told me
yes, i turn on api access in settings
soo what right now, i can’t stil solve problem
I’m updating my post for before ^ as we go.. Hard to get these perfect unless I totally recreate it.
I don’t want to leave something that isn’t working however..
I’m going to PM you one of my more complicated scripts working with what you’re doing here.
It’s not just what you’re doing, but it is working with JSON and the datastore.
Hope that is enough information to help you out.. good luck!
Debug the attribute and see if its correct, they might have string limit