As the title says, I can’t apply dictionaries to my datastores. This is strange to me because I’ve done it in the past and my dictionary isn’t complicated.
Error:
DataStoreService: ValueNotAllowed: Dictionary is not allowed in data stores. API: SetAsync, Data Store: PoopFlingers
Here is my DataStore script:
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local KillsData = DataStoreService:GetOrderedDataStore("PoopFlingers","Kills")
local CoinsData = DataStoreService:GetOrderedDataStore("PoopFlingers","Coins")
local AbilitiesData = DataStoreService:GetOrderedDataStore("PoopFlingers","Abilities")
local Remotes = ReplicatedStorage.Remotes
local Bindables = ReplicatedStorage.Bindables
local Assets = ReplicatedStorage.Assets
local GlobalLeaderboard = workspace.GlobalLeaderboard
local sessionData = {}
local function RefreshLeaderboard()
for i,v in GlobalLeaderboard.SurfaceGui:GetChildren() do if not v:IsA("UIListLayout") then v:Destroy() end end
local success,pages = pcall(function()
return KillsData:GetSortedAsync(false,10)
end)
if success then
local entries = pages:GetCurrentPage()
for rank,entry in pairs(entries) do
local nE = string.gsub(entry.key,"kills","")
local id = tonumber(nE)
local name = Players:GetNameFromUserIdAsync(id)
local item = script.Place:Clone()
item.Parent = GlobalLeaderboard.SurfaceGui
item.Kills.Text = tostring(entry.value)
item.Title.Text = name
item.Order.Text = tostring(rank)
end
end
end
local function InitAbilities(player)
sessionData[player] = {}
for i,v in Assets.Shop:GetChildren() do
sessionData[player][v.Name] = false
end
end
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
local kills = Instance.new("IntValue")
kills.Name = "Kills"
local coins = Instance.new("IntValue")
coins.Name = "Coins"
leaderstats.Parent = player
kills.Parent = leaderstats
coins.Parent = leaderstats
local pK = tostring(player.UserId)
if not AbilitiesData:GetAsync(pK.."abilities") then
InitAbilities(player)
end
local coinsReceived,lastCoins = pcall(function()
return CoinsData:GetAsync(pK.."coins")
end)
if coinsReceived and lastCoins then
coins.Value = lastCoins
end
local killsReceived,lastKills = pcall(function()
return KillsData:GetAsync(pK.."kills")
end)
if killsReceived and lastKills then
kills.Value = lastKills
end
local abilitiesReceived,lastAbilities = pcall(function()
return AbilitiesData:GetAsync(pK.."abilities")
end)
if abilitiesReceived and lastAbilities then
for i,v in lastAbilities do
sessionData[player][i] = v
end
end
RefreshLeaderboard()
while true do
task.wait(50)
if player.leaderstats.Kills.Value ~= 0 then
KillsData:UpdateAsync(pK .. "kills",function(past)
return player.leaderstats.Kills.Value
end)
end
end
end)
Players.PlayerRemoving:Connect(function(player)
local pK = tostring(player.UserId)
if player.leaderstats.Coins.Value ~= 0 then
local success,result = pcall(function()
return CoinsData:SetAsync(pK .. "coins",player.leaderstats.Coins.Value)
end)
end
if player.leaderstats.Kills.Value ~= 0 then
local success,result = pcall(function()
return KillsData:SetAsync(pK .. "kills",player.leaderstats.Kills.Value)
end)
end
if sessionData[player] then
for i,v in sessionData[player] do print(i,v) end
local success,result = pcall(function()
return AbilitiesData:SetAsync(pK .. "abilities",sessionData[player])
end)
end
end)
Bindables.OnServer.Event:Connect(function(signal,name,player)
if signal == "Purchase" then
print(player,name)
sessionData[player][name] = true
end
end)
Remotes.ToServer.OnServerEvent:Connect(function(player,signal,pos)
if signal == "TriggerPoop" then
print(sessionData[player])
Bindables.OnServer:Fire("Projectile",player,pos,sessionData[player])
end
end)
task.spawn(function()
while true do
task.wait(10)
RefreshLeaderboard()
end
end)
I’m using the sessionData table to index players creating a table and then putting the names of abilities inside of that table with a boolean stating if that ability has been purchased by the player or not.
Working code with dictionaries in datastores:
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Data = DataStoreService:GetDataStore("monke_datastore")
local Remotes = ReplicatedStorage.Remotes
local Functions = ReplicatedStorage.Functions
local Items = ReplicatedStorage.Items
local Tools = Items.Tools
local sessionData = {}
local DataStore = {}
function DataStore:Start(player)
sessionData[player] = {}
sessionData[player]["Tools"] = {}
end
local function GetParent(tool)
if tool.Parent:IsA("Model") and Players:GetPlayerFromCharacter(tool.Parent) then
return Players:GetPlayerFromCharacter(tool.Parent)
elseif tool.Parent.Parent:IsA("Player") then
return tool.Parent.Parent
end
end
local function Upgrades(tool)
return function(attributeName)
if attributeName ~= "CurrentUpgrade" then return end
local serial = tool:GetAttribute("SerialNumber")
local att = tool:GetAttribute(attributeName)
local player = GetParent(tool)
sessionData[player]["Tools"][serial] = {att,tool.Name,serial}
end
end
function DataStore:CS()
for i,tool in CollectionService:GetTagged("Tool") do
tool.AttributeChanged:Connect(Upgrades(tool))
end
CollectionService:GetInstanceAddedSignal("Tool"):Connect(function(tool)
tool.AttributeChanged:Connect(Upgrades(tool))
end)
end
function DataStore:Init() -- All our tools should save and we should save our upgrade number in sessionData and in attributes
Players.PlayerAdded:Connect(function(player)
self:Start(player)
local key = tostring(player.UserId)
local folder = Instance.new("Folder")
folder.Name = "leaderstats"
local money = Instance.new("IntValue")
money.Name = "Money"
local bananas = Instance.new("IntValue")
bananas.Name = "Bananas"
local fish = Instance.new("IntValue")
fish.Name = "Fish"
CollectionService:AddTag(fish,"Currency")
CollectionService:AddTag(bananas,"Currency")
local successFish,resultFish = pcall(function()
return Data:GetAsync("fish"..key)
end)
if successFish and resultFish then
fish.Value = resultFish
end
local successBananas,resultBananas = pcall(function()
return Data:GetAsync("bananas"..key)
end)
if successBananas and resultBananas then
bananas.Value = resultBananas
end
local successMoney,resultMoney = pcall(function()
return Data:GetAsync("money"..key)
end)
if successMoney and resultMoney then
money.Value = resultMoney
end
local successTools,resultTools = pcall(function()
return Data:GetAsync("tools"..key)
end)
if successTools and resultTools then
for i,v in pairs(resultTools) do
sessionData[player]["Tools"][i] = v
local tool = Tools:FindFirstChild(sessionData[player]["Tools"][i][2]):Clone()
tool:SetAttribute("SerialNumber",sessionData[player]["Tools"][i][3])
tool:SetAttribute("CurrentUpgrade",sessionData[player]["Tools"][i][1])
tool.Parent = player.Backpack
end
end
player.CharacterRemoving:Connect(function(character)
if character.Humanoid.Health <= 0 then return end
local function FindTools()
for i,v in player.Backpack:GetChildren() do
local serial = v:GetAttribute("SerialNumber")
sessionData[player]["Tools"][serial] = {v:GetAttribute("CurrentUpgrade"),v.Name,serial}
end
local tool = character:FindFirstChildOfClass("Tool")
if tool then
local serial = tool:GetAttribute("SerialNumber")
sessionData[player]["Tools"][serial] = {tool:GetAttribute("CurrentUpgrade"),tool.Name,serial}
end
table.sort(sessionData[player]["Tools"],function(a,b) return a < b end)
end
FindTools()
local successTools,resultTools = pcall(function()
return Data:SetAsync("tools"..key,sessionData[player]["Tools"])
end)
end)
bananas.Parent = player
fish.Parent = player
money.Parent = folder
folder.Parent = player
end)
Players.PlayerRemoving:Connect(function(player)
local key = tostring(player.UserId)
local successMoney,resultMoney = pcall(function()
return Data:SetAsync("money"..key,player.leaderstats.Money.Value)
end)
local successBananas,resultBananas = pcall(function()
return Data:SetAsync("bananas"..key,player.Bananas.Value)
end)
local successFish,resultFish = pcall(function()
return Data:SetAsync("fish"..key,player.Fish.Value)
end)
end)
self:CS()
end
return DataStore