Alright, I am trying to make a player data system but I ran into a problem trying to edit the values in the table. If there are 2 or more players in the game it will create two tables within TempData all fine but when I run the ChangeData function to change the current checkpoint value to 4 both players checkpoint values get updated to the same thing. I’m really not sure why this is happening.
Also just to note the is an example script to show what I’m having a problem with and ill be testing with the local server in studio.
Code
local TempData = {} --The Table with all players and data with it.
local TempDataDefualt = {["Ragdoll"] = false, ["CheckPoint"] = 1, } -- default data
local function ChangeData(Player, DataName, Value) --Change Data function thats breaking
TempData[Player.Name][DataName] = Value
end
game.Players.PlayerAdded:Connect(function(Player) --Adds Player to the Temp Data Table
TempData[Player.Name] = TempDataDefualt
print(TempData) -- Print all data when a player joins
end)
wait(15) --- just making sure both players have loaded for the example
print("After Change")
ChangeData(game.Players.Player1, "CheckPoint", 4) --- change data of "CheckPoint" to 4
print(TempData) -- print data after the changes have been made
Yeah, this is a problem I have ran into in the first game I created. Turns out it’s actually pretty simple. A table is different from numbers, strings, or other variables. When you assign a table to a variable, and assign the same table to another variable, then you change a value in the first variable, the value for the second variable would also change. Look at the example below:
local randomTable = {
a = "hello",
b = "world"
}
local x = randomTable
local y = randomTable
print(x.a) --> "hello"
print(y.a) --> "hello"
x.a = "changed"
print(x.a) --> "changed"
print(y.a) --> "changed"
By creating a variable whose value is equal to the table, you’re just adding another reference (shallow copy) to that table, instead of making a copy of it (deep copy). To make a deep copy of the table, insert a function like this:
local function DeepCopy(baseTable)
local newTable = {}
for key, value in pairs(baseTable) do
if type(value) == "table" then
value = DeepCopy(value)
end
newTable[key] = value
end
end
This code is pretty self explanatory, and you could probably understand this yourself. So I would just change the code to something like this:
local TempData = {} --The Table with all players and data with it.
local TempDataDefualt = {["Ragdoll"] = false, ["CheckPoint"] = 1, } -- default data
local function ChangeData(Player, DataName, Value) --Change Data function thats breaking
TempData[Player.Name][DataName] = Value
end
local function DeepCopy(baseTable)
local newTable = {}
for key, value in pairs(baseTable) do
if type(value) == "table" then
value = DeepCopy(value)
end
newTable[key] = value
end
end
game.Players.PlayerAdded:Connect(function(Player) --Adds Player to the Temp Data Table
TempData[Player.Name] = DeepCopy(TempDataDefualt)
print(TempData) -- Print all data when a player joins
end)
wait(15) --- just making sure both players have loaded for the example
print("After Change")
ChangeData(game.Players.Player1, "CheckPoint", 4) --- change data of "CheckPoint" to 4
print(TempData) -- print data after the changes have been made
For those looking for a quick rundown when you assign the same table (array or dictionary) to two or more variables those variables all become references to the same table value.
local table1 = {}
local table2 = table1
--both of these variables now point towards the same empty table value
local table3 = {}
local table4 = {}
--both of these variables point to separate empty table values