In my game I had an issue with one player having their coins reset to the default value, and in another post I have been suggested to table data, but I would like to double check that something different isn’t going on to cause probable data loss (As i believe tabling would mean Id have to reset all data)
Below I will depict everything that goes on with datastore, and If anyone could point out any flaws to which data could be lost I would be very greatful.
Main script storing data:
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("MyDataStore3") -- DO NOT CHANGE THE TERM IN ""
game.Players.PlayerAdded:Connect(function(player)
local goldPieces = Instance.new("IntValue")
goldPieces.Name = "GoldPieces"
goldPieces.Value = 500
goldPieces.Parent = player
local kingSkinInventory = Instance.new("Folder")
kingSkinInventory.Name = "KingSkinInventory"
kingSkinInventory.Parent = player
local assassinSkinInventory = Instance.new("Folder")
assassinSkinInventory.Name = "AssassinSkinInventory"
assassinSkinInventory.Parent = player
local bodyguardSkinInventory = Instance.new("Folder")
bodyguardSkinInventory.Name = "BodyguardSkinInventory"
bodyguardSkinInventory.Parent = player
local assassinHatInventory = Instance.new("Folder")
assassinHatInventory.Name = "AssassinHatInventory"
assassinHatInventory.Parent = player
local bodyguardHatInventory = Instance.new("Folder")
bodyguardHatInventory.Name = "BodyguardHatInventory"
bodyguardHatInventory.Parent = player
local kingHatInventory = Instance.new("Folder")
kingHatInventory.Name = "KingHatInventory"
kingHatInventory.Parent = player
local hairstyleInventory = Instance.new("Folder")
hairstyleInventory.Name = "HairstyleInventory"
hairstyleInventory.Parent = player
local equippedAssassinHat = Instance.new("StringValue")
equippedAssassinHat.Name = "EquippedAssassinHat"
equippedAssassinHat.Parent = player
local equippedBodyguardHat = Instance.new("StringValue")
equippedBodyguardHat.Name = "EquippedBodyguardHat"
equippedBodyguardHat.Parent = player
local equippedKingHat = Instance.new("StringValue")
equippedKingHat.Name = "EquippedKingHat"
equippedKingHat.Parent = player
local equippedKingSkin = Instance.new("StringValue")
equippedKingSkin.Name = "EquippedKingSkin"
equippedKingSkin.Parent = player
local equippedAssassinSkin = Instance.new("StringValue")
equippedAssassinSkin.Name = "EquippedAssassinSkin"
equippedAssassinSkin.Parent = player
local equippedBodyguardSkin = Instance.new("StringValue")
equippedBodyguardSkin.Name = "EquippedBodyguardSkin"
equippedBodyguardSkin.Parent = player
local equippedHairstyle = Instance.new("StringValue")
equippedHairstyle.Name = "EquippedHairstyle"
equippedHairstyle.Parent = player
--[[]
local weaponSkinInventory = Instance.new("Folder")
weaponSkinInventory.Name = "WeaponSkinInventory"
weaponSkinInventory.Parent = player
local equippedWeapon = Instance.new("StringValue")
equippedWeapon.Name = "EquippedWeapon"
equippedWeapon.Parent = player
--]]
local data
local success, errorMsg = pcall(function()
data = DataStore:GetAsync(player.UserId)
end)
if data ~= nil then
--Load equipped skin, weapon skin, goldpieces, skin inventory, weaponskininventory
--[[ if data.EquippedWeapon then
equippedWeapon.Value = data.EquippedWeapon
end
--]]
if data.EquippedKingSkin then
equippedKingSkin.Value = data.EquippedKingSkin
end
if data.EquippedAssassinSkin then
equippedAssassinSkin.Value = data.EquippedAssassinSkin
end
if data.EquippedBodyguardSkin then
equippedBodyguardSkin.Value = data.EquippedBodyguardSkin
end
if data.EquippedAssassinHat then
equippedAssassinHat.Value = data.EquippedAssassinHat
end
if data.EquippedBodyguardHat then
equippedBodyguardHat.Value = data.EquippedBodyguardHat
end
if data.EquippedKingHat then
equippedKingHat.Value = data.EquippedKingHat
end
if data.EquippedHairstyle then
equippedHairstyle.Value = data.EquippedHairstyle
end
if data.GoldPieces then
goldPieces.Value = data.GoldPieces
end
--[[
if data.Skins then
for i, v in pairs(data.Skins) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = skinInventory
end
end
--]]
if data.KingSkins then
for i, v in pairs(data.KingSkins) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = kingSkinInventory
end
end
if data.AssassinSkins then
for i, v in pairs(data.AssassinSkins) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = assassinSkinInventory
end
end
if data.BodyguardSkins then
for i, v in pairs(data.BodyguardSkins) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = bodyguardSkinInventory
end
end
if data.AssassinHats then
for i, v in pairs(data.AssassinHats) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = assassinHatInventory
end
end
if data.BodyguardHats then
for i, v in pairs(data.BodyguardHats) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = bodyguardHatInventory
end
end
if data.KingHats then
for i, v in pairs(data.KingHats) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = kingHatInventory
end
end
if data.Hairstyles then
for i, v in pairs(data.Hairstyles) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = hairstyleInventory
end
end
--[[
if data.WeaponSkins then
for i, v in pairs(data.WeaponSkins) do
local val = Instance.new("StringValue")
val.Name = v
val.Parent = weaponSkinInventory
end
end
--]]
end
–Some code included in a function that checks for players death (irrelevant)
game.Players.PlayerRemoving:Connect(function(player) -- Run the code inside when a player leaves the game
local data = {} -- GoldPieces, skin/wep skin
data.GoldPieces = player.GoldPieces.Value
--data.EquippedWeapon = player.EquippedWeapon.Value
data.EquippedKingSkin = player.EquippedKingSkin.Value
data.EquippedAssassinSkin = player.EquippedAssassinSkin.Value
data.EquippedBodyguardSkin = player.EquippedBodyguardSkin.Value
data.EquippedAssassinHat = player.EquippedAssassinHat.Value
data.EquippedBodyguardHat = player.EquippedBodyguardHat.value
data.EquippedKingHat = player.EquippedKingHat.Value
data.EquippedHairstyle = player.EquippedHairstyle.Value
data.KingSkins = {}
data.AssassinSkins = {}
data.BodyguardSkins = {}
--data.WeaponSkins = {}
data.AssassinHats = {}
data.BodyguardHats = {}
data.KingHats = {}
data.Hairstyles = {}
for i, v in pairs(player.KingSkinInventory:GetChildren()) do
table.insert(data.KingSkins, v.Name)
print(v.Name)
end
for i, v in pairs(player.AssassinSkinInventory:GetChildren()) do
table.insert(data.AssassinSkins, v.Name)
print(v.Name)
end
for i, v in pairs(player.BodyguardSkinInventory:GetChildren()) do
table.insert(data.BodyguardSkins, v.Name)
print(v.Name)
end
for i, v in pairs(player.AssassinHatInventory:GetChildren()) do
table.insert(data.AssassinHats, v.Name)
print(v.Name)
end
for i, v in pairs(player.BodyguardHatInventory:GetChildren()) do
table.insert(data.BodyguardHats, v.Name)
print(v.Name)
end
for i, v in pairs(player.KingHatInventory:GetChildren()) do
table.insert(data.KingHats, v.Name)
print(v.Name)
end
for i, v in pairs(player.HairstyleInventory:GetChildren()) do
table.insert(data.Hairstyles, v.Name)
print(v.Name)
end
--[[
for i, v in pairs(player.WeaponSkinInventory:GetChildren()) do
table.insert(data.WeaponSkins, v.Name)
print(v.Name)
end
--]]
local success,errorMsg = pcall(function()
DataStore:SetAsync(player.UserId,data)
end)
if success then
print("Save Successful!")
end
end)
game:BindToClose(function()
--Will run when server about to shutdown
for i, player in pairs(game.Players:GetPlayers()) do
local data = {} -- GoldPieces, skin/wep skin
data.GoldPieces = player.GoldPieces.Value
--data.EquippedWeapon = player.EquippedWeapon.Value
data.EquippedKingSkin = player.EquippedKingSkin.Value
data.EquippedAssassinSkin = player.EquippedAssassinSkin.Value
data.EquippedBodyguardSkin = player.EquippedBodyguardSkin.Value
data.EquippedAssassinHat = player.EquippedAssassinHat.Value
data.EquippedBodyguardHat = player.EquippedBodyguardHat.value
data.EquippedKingHat = player.EquippedKingHat.Value
data.EquippedHairstyle = player.EquippedHairstyle.Value
data.KingSkins = {}
data.AssassinSkins = {}
data.BodyguardSkins = {}
--data.WeaponSkins = {}
data.AssassinHats = {}
data.BodyguardHats = {}
data.KingHats = {}
data.Hairstyles = {}
for i, v in pairs(player.KingSkinInventory:GetChildren()) do
table.insert(data.KingSkins, v.Name)
print(v.Name)
end
for i, v in pairs(player.AssassinSkinInventory:GetChildren()) do
table.insert(data.AssassinSkins, v.Name)
print(v.Name)
end
for i, v in pairs(player.BodyguardSkinInventory:GetChildren()) do
table.insert(data.BodyguardSkins, v.Name)
print(v.Name)
end
for i, v in pairs(player.AssassinHatInventory:GetChildren()) do
table.insert(data.AssassinHats, v.Name)
print(v.Name)
end
for i, v in pairs(player.BodyguardHatInventory:GetChildren()) do
table.insert(data.BodyguardHats, v.Name)
print(v.Name)
end
for i, v in pairs(player.KingHatInventory:GetChildren()) do
table.insert(data.KingHats, v.Name)
print(v.Name)
end
for i, v in pairs(player.HairstyleInventory:GetChildren()) do
table.insert(data.Hairstyles, v.Name)
print(v.Name)
end
--[[
for i, v in pairs(player.WeaponSkinInventory:GetChildren()) do
table.insert(data.WeaponSkins, v.Name)
print(v.Name)
end
--]]
local success,errorMsg = pcall(function()
DataStore:SetAsync(player.UserId,data)
end)
if success then
print("Save Successful!")
end
end
end)
game.ReplicatedStorage.MenuPlay.OnServerEvent:Connect(function(player)
if player:FindFirstChild("InMenu") then
player.InMenu:Destroy()
end
end)
game.ReplicatedStorage.BuyItem.OnServerInvoke = function(player,itemName,itemType)
local item
local inInventory
if itemType == "kingSkin" then
--skin
item = game.ReplicatedStorage.KingSkins:FindFirstChild(itemName)
if player.KingSkinInventory:FindFirstChild(itemName) then
inInventory = true
end
elseif itemType == "assassinSkin" then
--skin
item = game.ReplicatedStorage.AssassinSkins:FindFirstChild(itemName)
if player.AssassinSkinInventory:FindFirstChild(itemName) then
inInventory = true
end
elseif itemType == "bodyguardSkin" then
--skin
item = game.ReplicatedStorage.BodyguardSkins:FindFirstChild(itemName)
if player.BodyguardSkinInventory:FindFirstChild(itemName) then
inInventory = true
end
elseif itemType == "assassinHat" then
--skin
item = game.ReplicatedStorage.AssassinHats:FindFirstChild(itemName)
if player.AssassinHatInventory:FindFirstChild(itemName) then
inInventory = true
end
elseif itemType == "bodyguardHat" then
--skin
item = game.ReplicatedStorage.BodyguardHats:FindFirstChild(itemName)
if player.BodyguardHatInventory:FindFirstChild(itemName) then
inInventory = true
end
elseif itemType == "kingHat" then
--skin
item = game.ReplicatedStorage.KingHats:FindFirstChild(itemName)
if player.KingHatInventory:FindFirstChild(itemName) then
inInventory = true
end
elseif itemType == "hairstyle" then
--skin
item = game.ReplicatedStorage.Hairstyles:FindFirstChild(itemName)
if player.HairstyleInventory:FindFirstChild(itemName) then
inInventory = true
end
--[[
elseif itemType == "weaponSkin" then
--WeaponSkin
item = game.ReplicatedStorage.WeaponSkins:FindFirstChild(itemName)
if player.WeaponSkinInventory:FindFirstChild(itemName) then
inInventory = true
end
-]]
end
if item then
if item:FindFirstChild("Cost") then
if not inInventory then
-- Check to see if we can buy it
if item.Cost.Value <= player.GoldPieces.Value then
print("You can purchase this")
player.GoldPieces.Value = player.GoldPieces.Value - item.Cost.Value
local stringValue = Instance.new("StringValue")
stringValue.Name = item.Name
if itemType == "kingSkin" then
stringValue.Parent = player.KingSkinInventory
elseif itemType == "assassinSkin" then
stringValue.Parent = player.AssassinSkinInventory
elseif itemType == "bodyguardSkin" then
stringValue.Parent = player.BodyguardSkinInventory
elseif itemType == "assassinHat" then
stringValue.Parent = player.AssassinHatInventory
elseif itemType == "bodyguardHat" then
stringValue.Parent = player.BodyguardHatInventory
elseif itemType == "kingHat" then
stringValue.Parent = player.KingHatInventory
elseif itemType == "hairstyle" then
stringValue.Parent = player.HairstyleInventory
--elseif itemType == "weaponSkin" then
--stringValue.Parent = player.WeaponSkinInventory
end
return "bought"
else
return "failed"
end
else
--You already own (equip it instead)
print("You already own this item.")
if itemType == "kingSkin" then
player.EquippedKingSkin.Value = itemName
elseif itemType == "assassinSkin" then
player.EquippedAssassinSkin.Value = itemName
elseif itemType == "bodyguardSkin" then
player.EquippedBodyguardSkin.Value = itemName
elseif itemType == "assassinHat" then
player.EquippedAssassinHat.Value = itemName
elseif itemType == "bodyguardHat" then
player.EquippedBodyguardHat.Value = itemName
elseif itemType == "kingHat" then
player.EquippedKingHat.Value = itemName
elseif itemType == "hairstyle" then
player.EquippedHairstyle.Value = itemName
--elseif itemType == "weaponSkin" then
--player.EquippedWeapon.Value = itemName
end
return "equipped"
end
end
else
print("No such skin/weapon skin found")
return "failed"
end
end
I then have a script for the shop calling the Replicated storage folders, and setting up data sending.
I have various other things involving the gold value, such as awarding gold at the end of a round and on coin pickup (done by a one line code) and some scripts for checking for game passes etc
I also have one other data store here:
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local currencyName = "GoldPieces"
local PreviousPurchases = DataStoreService:GetDataStore("PreviousPurchases")
local ONEHUNDRED_GP = 1178943319
local TWOHUNDRED_GP = 1178933654
local FIVEHUNDRED_GP = 1178933718
local TWELVEHUNDREDANDFIFTY_GP = 1178933942
local TWOTHOUSAND_GP = 1178934107
local FOURTHOUSAND_GP = 1178934474
local TENTHOUSAND_GP = 1178934774
MarketplaceService.ProcessReceipt = function(receipt)
--Receipt has PurchaseId, PlayerId, ProductId, CurrencySpentValue, CurrencyType, PlaceIDWherePurchased
local ID = receipt.PlayerId.."-"..receipt.PurchaseId
local success = nil
pcall(function()
success = PreviousPurchases:GetAsync(ID)
end)
if success then -- Has it already been bought
--Purchase has already been done
return Enum.ProductPurchaseDecision.PurchaseGranted
end
local player = game.Players:GetPlayerByUserId(receipt.PlayerId)
if not player then
-- Left, or disconnected
return Enum.ProductPurchaseDecision.NotProcessedYet --Give when they next join
else
if receipt.ProductId == ONEHUNDRED_GP then
--Theyve bought 100gp
player.GoldPieces.Value = player.GoldPieces.Value + 100
end
if receipt.ProductId == TWOHUNDRED_GP then
--Theyve bought 200gp
player.GoldPieces.Value = player.GoldPieces.Value + 200
end
if receipt.ProductId == FIVEHUNDRED_GP then
--Theyve bought 500gp
player.GoldPieces.Value = player.GoldPieces.Value + 500
end
if receipt.ProductId == TWELVEHUNDREDANDFIFTY_GP then
--Theyve bought 1250gp
player.GoldPieces.Value = player.GoldPieces.Value + 1250
end
if receipt.ProductId == TWOTHOUSAND_GP then
--Theyve bought 2000gp
player.GoldPieces.Value = player.GoldPieces.Value + 2000
end
if receipt.ProductId == FOURTHOUSAND_GP then
--Theyve bought 4000gp
player.GoldPieces.Value = player.GoldPieces.Value + 4000
end
if receipt.ProductId == TENTHOUSAND_GP then
--Theyve bought 10000gp
player.GoldPieces.Value = player.GoldPieces.Value + 10000
end
pcall(function()
PreviousPurchases:SetAsync(ID, true)
end)
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
Sorry for the long post, any help is appreciated. Cheers