I have made a dictionary that stores the all the player data on the server, when i update the data in the dictionary on a specific players key, it adds the data to all of the other keys. Ive tried printing it out, making sure the update data function doesnt run for all the players, it doesnt.
Here is the update data function:
local function GiveItem(Player, Class, SubjectName)
if PlayersData[Player.UserId] then
print("Ran")
print(PlayersData) -- {[129409203] = { ["Wins"] = 1}; [5802880] = { ["Wins"] = 1}}
-- Update data
PlayersData[Player.UserId][Class].Owns[SubjectName] = {["Wins"] = 2}
print("Updated")
print(PlayersData) -- {[129409203] = { ["Wins"] = 2}; [5802880] = { ["Wins"] = 2}}
end
end
I dont know what to do at this point, i have never encountered this issue. Any help is appreciated!
The data return seems inconsistent and doesn’t match your table, where the .Owns comes from.
Based on what you send, PlayersData[Player.UserId] = {["Wins"] = 2} is enough.
This probably doesn’t answer your question but without the correct data we can’t help you.
The GiveItem function takes 3 params, Player, Class(The class the item is in, EG: Hammer) and Name(Name of the item)
local function GiveItem(Player, Class, SubjectName)
if PlayersData[Player.UserId] then
print("E")
print(PlayersData)
-- Update data
PlayersData[Player.UserId][Class].Owns[SubjectName] = {["TimeBought"] = 5}
print("A")
print(PlayersData)
end
end
The pattern im noticing is when 1 player buys an item, it saves it to everyones “Owns” dictionary, with the class bought from.
This is the code being ran from the client when the player clicks the buy button.
Shop.BuyTextButton.MouseButton1Click:Connect(function()
if SelectedShopItem then
BuyItem:FireServer(SelectedShopItem.Class, SelectedShopItem.Name)
end
end)
Oh wait I see your problem entirely now, what has likely happened is when you’ve made the template for the data you haven’t made a deep copy of it.
As such your data marker is the same for each instance as they are sharing the same memory pointer.
You can see this behaviour here:
When creating and loading the data, make a deep copy.
Yeah that does make sense, currently the code that adds the player table is this.
local function AddData(Player)
local PlayerData
local s, e = pcall(function()
PlayerData = Store:GetAsync("Player_"..Player.UserId)
end)
if s then
if PlayerData == nil then PlayerData = DataTemplate end
PlayersData[Player.UserId] = PlayerData
else
warn(e)
end
end
When you make the new data they all share the same DataTemplate (as this is a memory pointer).
As such to fix this:
local function deepCopy(original)
local copy = {}
for k, v in pairs(original) do
if type(v) == "table" then
v = deepCopy(v)
end
copy[k] = v
end
return copy
end
local function AddData(Player)
local PlayerData
local s, e = pcall(function()
PlayerData = Store:GetAsync("Player_"..Player.UserId)
end)
if s then
if PlayerData == nil then PlayerData = deepCopy(DataTemplate) end
PlayersData[Player.UserId] = PlayerData
else
warn(e)
end
end