I recently released a game with skin packs for the weapons. However, there appear to be some players losing their items once they buy them, and I’m wondering if anyone is able to look over my DataStore2 script to try and figure out why this may be? Here is the script - I warn you it’s a bit long! I would be grateful for any assistance as I am new to DataStore2 (hoping I didn’t make the wrong decision choosing it over regular DataStores lol)
-------------------------------------------------------------------------------------
local MainKey = "PlayerData1"
DataStore2.Combine(MainKey, "Inventory")
local function CreateDataTable() -- function to get the table
local PlayerData = {
KOWeaponPacks = {
["StarterPack"] = true;
["BronzePack"] = false;
["SilverPack"] = false;
["GoldPack"] = false;
["PlatinumPack"] = false;
["TitaniumPack"] = false;
["NaturePack"] = false;
["LavaPack"] = false;
["EnergyPack"] = false;
};
PremiumWeaponPacks = {
["GhostlyPack"] = false;
["AncientPack"] = false;
["DirtPack"] = false;
["MysticPack"] = false;
["PolishedPack"] = false;
["NeonPack"] = false;
["HotCoalPack"] = false;
["ForcefieldPack"] = false;
["TwistedWoodPack"] = false;
["IciclePack"] = false;
["MythrilPack"] = false;
["CyberPack"] = false;
["PurityPack"] = false;
["AquaPack"] = false;
["BrickPack"] = false;
["OverseerPack"] = false;
["ShadowPack"] = false;
["RainbowPack"] = false;
};
EquippedItems = {
["Weapon1"] = "StarterPack";
["Weapon2"] = "StarterPack";
["Weapon3"] = "StarterPack";
["Weapon4"] = "StarterPack";
["Weapon5"] = "StarterPack";
["Weapon6"] = "StarterPack";
};
}
return PlayerData -- Returns the table when function is called
end
-------------------------------------------------------------------------------------
Players.PlayerAdded:Connect(function(plr)
DataStore2("PlayerData", plr):SetBackup(3, DefaultKOValue)
local PlayerData1 = DataStore2("PlayerData", plr):Get(CreateDataTable())
if DataStore2("PlayerData", plr):IsBackup() then
plr:Kick("Error loading save data, please rejoin.")
end
repeat wait() until ServerStorage:FindFirstChild(plr.Name) -- Wait until player data directory created by PlayerData script
local PlayerDataDIR = ServerStorage:WaitForChild(plr.Name)
local KOWeaponPackDIR = Instance.new("Folder", PlayerDataDIR) -- Create a new folder in the player's ServerStorage folder that stores KO weapon pack data
KOWeaponPackDIR.Name = "KOWeaponPacks"
local EquippedFolder = PlayerDataDIR:WaitForChild("EquippedData")
local CoinWeaponPackDIR = Instance.new("Folder", PlayerDataDIR) -- Create a new folder in the player's ServerStorage folder that stores premium weapon pack data
CoinWeaponPackDIR.Name = "CoinWeaponPacks"
for i, v in pairs (PlayerData1["KOWeaponPacks"]) do -- Index retrieved player data KO packs and add a BoolValue to the player's ServerStorage directory
print(tostring(i), v)
local NewStat = Instance.new("BoolValue")
NewStat.Parent = KOWeaponPackDIR
NewStat.Name = tostring(i)
NewStat.Value = tostring(v)
end
for i, v in pairs (PlayerData1["PremiumWeaponPacks"]) do -- Index retrieved player data premium weapon packs and add a BoolValue to the player's ServerStorage directory
print(tostring(i), v)
local NewStat = Instance.new("BoolValue")
NewStat.Parent = CoinWeaponPackDIR
NewStat.Name = tostring(i)
NewStat.Value = tostring(v)
end
for i, v in pairs (PlayerData1["EquippedItems"]) do -- Index retrieved equipped weapon packs and add a BoolValue to the player's ServerStorage directory
print(tostring(i), v)
local NewStat = Instance.new("StringValue")
NewStat.Parent = EquippedFolder
NewStat.Name = tostring(i)
NewStat.Value = tostring(v)
end
for i, v in pairs (PlayerData1["KOWeaponPacks"]) do -- Set the boolvalue's value according to whether the PlayerData dictionary is true/false
if tostring(i) ~= "StarterPack" then
if KOWeaponPackDIR:FindFirstChild(tostring(i)) then
print("GOTCHA")
local Value = KOWeaponPackDIR:WaitForChild(tostring(i))
print("GOTCHA2")
Value.Value = DataStore2("PlayerData", plr):Get(CreateDataTable())["KOWeaponPacks"][tostring(i)] -- Sets boolvalue
print("GOTCHA3")
Button:FireClient(plr, tostring(i), v) -- Fires purchase button in the shop (if the value is true the button will be disabled client side)
print("GOTCHA4")
end
end
end
print("Fired ButtonStatus for "..plr.Name)
for i, v in pairs (PlayerData1["PremiumWeaponPacks"]) do -- Set the boolvalue's value according to whether the PlayerData dictionary is true/false
if CoinWeaponPackDIR:FindFirstChild(tostring(i)) then
print("GOTCHA")
local Value = CoinWeaponPackDIR:WaitForChild(tostring(i))
print("GOTCHA2")
Value.Value = DataStore2("PlayerData", plr):Get(CreateDataTable())["PremiumWeaponPacks"][tostring(i)]
print("GOTCHA3")
Button2:FireClient(plr, tostring(i), v)
print("GOTCHA4")
end
end
print("Fired ButtonStatus for "..plr.Name)
for i, v in pairs(EquippedFolder:GetChildren()) do -- Checks for when the equipped values change in ServerStorage, and sets them on the DataStore.
v.Changed:Connect(function()
PlayerData1["EquippedItems"][v.Name] = v.Value
DataStore2("PlayerData", plr):Set(PlayerData1)
end)
local function UpdateAllStats(UpdatedStats)
for i, v in pairs (PlayerData1["KOWeaponPacks"]) do
if PlayerDataDIR:FindFirstChild(tostring(i)) then
print("GOTCHA")
local Value = PlayerDataDIR:WaitForChild(tostring(i))
print("GOTCHA2")
Value.Value = DataStore2("PlayerData", plr):Get(UpdatedStats)["KOWeaponPacks"][tostring(i)]
print("GOTCHA3")
end
end
for i, v in pairs (PlayerData1["PremiumWeaponPacks"]) do
if PlayerDataDIR:FindFirstChild(tostring(i)) then
print("GOTCHA")
local Value = PlayerDataDIR:WaitForChild(tostring(i))
print("GOTCHA2")
Value.Value = DataStore2("PlayerData", plr):Get(UpdatedStats)["PremiumWeaponPacks"][tostring(i)]
print("GOTCHA3")
end
end
end
DataStore2("PlayerData", plr):OnUpdate(UpdateAllStats)
end
end)
KOPurchase.OnServerEvent:Connect(function(player, ProductName)
repeat wait() until player ~= nil and ProductName ~= nil
if db == false then
db = true
else
repeat wait() until db == false
end
local PlayerData1 = DataStore2("PlayerData", player):Get(CreateDataTable())
local PlayerDataDIR = ServerStorage:WaitForChild(player.Name)
local KOWeaponPackDIR = PlayerDataDIR:WaitForChild("KOWeaponPacks")
print("Started purchase")
if not ProductDatabase[ProductName] then return end
local KODataStore = DataStore2("KOs", player)
local ProductPrice = ProductDatabase[ProductName]
if CreateDataTable()["KOWeaponPacks"] ~= nil and PlayerData1["KOWeaponPacks"] == nil then
PlayerData1["KOWeaponPacks"] = CreateDataTable()["KOWeaponPacks"]
elseif CreateDataTable()["KOWeaponPacks"][ProductName] ~= nil and PlayerData1["KOWeaponPacks"][ProductName] == nil then
PlayerData1["KOWeaponPacks"][ProductName] = CreateDataTable()["KOWeaponPacks"][ProductName]
end
if KODataStore:Get(DefaultKOValue) >= ProductPrice and PlayerData1["KOWeaponPacks"][ProductName] == false then
print("Redeeming product")
local Button = ProductPrice
local Result = 'Successful purchase'
PurchaseResult:FireClient(player, Result, Button)
PlayerData1["KOWeaponPacks"][ProductName] = true
KOWeaponPackDIR:FindFirstChild(ProductName).Value = true
elseif KODataStore:Get(DefaultKOValue) < ProductPrice and PlayerData1["KOWeaponPacks"][ProductName] == false then
print("Redemption failure")
local Button = ProductPrice
local Result = 'Not enough coins'
PurchaseResult:FireClient(player, Result, Button)
elseif PlayerData1["KOWeaponPacks"][ProductName] == nil then
print("Redemption failure (nil product)")
local Button = ProductPrice
local Result = 'Not enough coins'
PurchaseResult:FireClient(player, Result, Button)
elseif PlayerData1["KOWeaponPacks"][ProductName] == true then
print("Data mismatch correction attempt")
local Button = ProductPrice
local Result = 'Successful purchase'
PurchaseResult:FireClient(player, Result, Button)
PlayerData1["KOWeaponPacks"][ProductName] = true
KOWeaponPackDIR:FindFirstChild(ProductName).Value = true
end
DataStore2("PlayerData", player):Set(PlayerData1)
db = false
end)```