Hello.I've spent at least a few hours now trying to debug/find the error of what is causing the issue to occur,but to no avail.Here is my issue:
When a Player joins the game,their data is loaded from the datastore and put into their data folder in ServerStorage.
When a Player leaves the game,their data is put into a metatable and saved to the datastore.
Pretty straightforward,until the bug comes in.
For some odd reason,the weapons and pets that the player owns are cloned repeatedly inside the datastore.Also,data between two players gets mixed together for some odd reason..
For example:
Player A owns the weapon "LinkedSword".It is saved in the 'Weapons' metatable,and inside the 'Weapons' folder when loaded into his/her datafolder.Player A owns the pet "Doge",which is saved inside the 'Pets' metatable,and inside the 'Pets' folder when loaded into the datafolder.
With Player B,the same scenario is in place with how the data is stored.
Player B owns the weapon "GolfClub",and owns the pet "Kitty".
All runs well,when the player joins their data is loaded into the server,when they leave the data is put inside a metatable and saved to the datastore.But here's the problem:
Next time Player A's data is loaded,he/she now owns the pets "Doge" and "Kitty" and "Kitty" and "Kitty" (Yes,the cloning is what happens).Same with the saved weapons.The data seems to "Cross" between the two players,even though they have their own seperate datafolders.
I am completely stumped.If someone can point out the logic error,please do. Thanks!
Here is the code:
DataService script:
009 | _G.DataServiceReady = false |
010 | while _G.ServerReady = = nil or _G.ServerReady = = false do |
014 | local DataStore = game:GetService( "DataStoreService" ):GetDataStore(_G.Config.DataStoreName) |
032 | _G.GetUserData = function (Player) |
033 | if DataStore:GetAsync( "User_" ..Player.userId) = = nil then |
035 | dat.ChosenWeapon = "LinkedSword" |
036 | table.insert(dat.Weapons, "LinkedSword" ) |
039 | return DataStore:GetAsync( "User_" ..Player.userId) |
046 | _G.SaveUserData = function (Player,NewValue) |
047 | DataStore:SetAsync( "User_" ..Player.userId,NewValue) |
053 | _G.UnpackUserData = function (Data,Player) |
054 | local f = Instance.new( 'Folder' ,game.ServerStorage.UserData) |
056 | local v = Instance.new( 'StringValue' ,f) |
058 | v.Value = Data.ChosenWeapon |
059 | local v = Instance.new( 'IntValue' ,f) |
062 | local v = Instance.new( 'IntValue' ,f) |
065 | local v = Instance.new( 'IntValue' ,f) |
068 | local v = Instance.new( 'StringValue' ,f) |
070 | v.Value = Data.ChosenPet |
071 | local v = Instance.new( 'IntValue' ,f) |
073 | v.Value = Data.NoobChance |
075 | local v = Instance.new( 'Folder' ,f) |
077 | for i,v in pairs (Data.Pets) do |
078 | local va = Instance.new( 'StringValue' ,f.Pets) |
082 | local v = Instance.new( 'Folder' ,f) |
084 | for i,v in pairs (Data.Weapons) do |
085 | local va = Instance.new( 'StringValue' ,f.Weapons) |
094 | _G.PackUserData = function (DataFolder) |
095 | local data = _G.BaseData |
096 | data.ChosenWeapon = DataFolder.ChosenWeapon.Value |
097 | data.Money = DataFolder.Money.Value |
098 | data.Level = DataFolder.Level.Value |
099 | data.ChosenPet = DataFolder.ChosenPet.Value |
101 | for i,v in pairs (DataFolder.Pets:GetChildren()) do |
102 | table.insert(data.Pets,v.Value) |
104 | for i,v in pairs (DataFolder.Weapons:GetChildren()) do |
105 | table.insert(data.Weapons,v.Value) |
112 | _G.DataServiceReady = true |
PlayerEvents script:
09 | local PlayerService = game:GetService( "Players" ) |
12 | PlayerService.CharacterAutoLoads = false |
15 | PlayerService.PlayerAdded:connect( function (Player) |
16 | print ( "[Player Service] " ..Player.Name.. " has joined the game." ) |
19 | while _G.ServerReady = = nil or _G.ServerReady = = false do |
25 | if _G.Config.Maintence = = false then |
26 | _G.UnpackUserData(_G.GetUserData(Player),Player) |
27 | _G.LoadPet(Player, true ) |
33 | PlayerService.PlayerRemoving:connect( function (Player) |
34 | print ( "[Player Service] " .. Player.Name.. " has left the game." ) |
35 | _G.LoadPet(Player, false ) |
36 | _G.SaveUserData(Player,_G.PackUserData(game.ServerStorage.UserData [ Player.Name ] )) |