Datastore Crashes Studio

Hi there,

My Datastore keep causing my game to crash when I stop test playing in studio
Is there any way to prevent this? This is mostly caused by me saving the player inventory,

Thanks a lot

Please provide the part of your script that manages storing data for when player leaves or/and when server shuts down. It seems you’re saving data too many times, so it’s most likely a logical error in the script.

serverscript:

game.Players.PlayerAdded:Connect(function()
	--.. Random Code
	local InvItemsData = InventoryItemsData:GetAsync(player.UserId)
	print(InvItemsData)
	if InventoryItemsData then
		print("Past Inventory Data Retrieved")
		LoadInv:FireClient(player, InvItemsData)
	else
		print("No Existing For Inventory, Data will be created when Aura is equipped")
	end
end)

LocalScript when they recieve the

LoadInv:FireClient(player, InvItemsData)

LoadInvEvent.OnClientEvent:Connect(function(InventoryTable)
	print(InventoryTable)
	for _, item in InventoryTable do
		AddToInventory(item)
	end
end)

This looks like the part that retrieves data, but I think the problem lies in the part that saves it so could you provide that part? The part that does print(“InvItem Saved into Folder”)

This is the Inventory
image

What happens is that the serverscript puts these all into a table and then saves it as a datastore

And what it prints is just a table

Could you show the part of code that does that? Judging by the warning your script does too many saving requests.

most of it’s just random code

local function SerilizeObj(Table)
	local InvList = {}
	for _, v in Table do
		table.insert(InvList, v.Name)
	end
	return InvList
end
SaveInventoryEvent.OnServerEvent:Connect(function(player: Player, InvItem: string, DeletingItem: BoolValue)
	if not DeletingItem then 
		--// Addition Of An Aura to the Inventory
		local NewInvItem = Instance.new("StringValue")
		NewInvItem.Name = InvItem
		if game.ServerScriptService["All_Player's_Inv"]:FindFirstChild(player.UserId) == nil then
			print("New Folder Created")
			local PlayerFolder = Instance.new("Folder")
			PlayerFolder.Name = player.UserId
			PlayerFolder.Parent = game.ServerScriptService["All_Player's_Inv"]
		end
		print("InvItem Saved into Folder")
		NewInvItem.Parent = game.ServerScriptService["All_Player's_Inv"][player.UserId]
		
		local PlayerAuraTable = game.ServerScriptService["All_Player's_Inv"][player.UserId]:GetChildren()
		InventoryItemsData:SetAsync(player.UserId, SerilizeObj(PlayerAuraTable))
	else 
		--// Deletion of a InvItem
		if game.ServerScriptService["All_Player's_Inv"]:FindFirstChild(player.UserId) == nil then
			warn("Player Folder is nil While Trying To Request an InvItem Deletion")
			return
		else
			local ItemDeletion = game.ServerScriptService["All_Player's_Inv"]:FindFirstChild(player.UserId)[InvItem]
			ItemDeletion:Destroy()
		end
	end
end)

this runs every time the player gets a new item, which can range from 0.8 seconds to 0.1 seconds,

yeah uh i think i foudn the problem

Yeah that seems to be the problem. First of all, this runs when a remote event is fired? This is not secure at all, try doing stuff like that only on the server, and never trust the client.

The problem is that you’re using SetAsync way too much, whilst it’s generally supposed to be used only when the player leaves the game, maybe also happen ever X minutes to prevent total data loss if server crashes.

Instead you need to store player data in a table, and whenever you need to amend a player’s data you change those values in that table. Then you use SetAsync if the player wants to leave, in which case you simply tell DataStore to store that table where you’ve been keeping track of player data.

what should I use instead of SetAsync then

SetAsync is fine you’re just using it too frequently, you don’t need to save a player’s inventory every time they receive a new item, just save it periodically (every 5-10 minutes or so) and when they leave the game.

do something like

local playersData = {}
game.Players.PlayerAdded:Connect(function(Player)
	
	local InvItemsData = InventoryItemsData:GetAsync(player.UserId)
        playersData[Player.UserId] = InvItemsData
	print(InvItemsData)
	if InventoryItemsData then
		print("Past Inventory Data Retrieved")
		LoadInv:FireClient(player, InvItemsData)
	else
		print("No Existing For Inventory, Data will be created when Aura is equipped")
	end
end)

then you can change playersData[Player.UserId] to reflect changes to player data and once player leaves

game.Players.PlayerRemoving:Connect(function(Player)
        InventoryItemsData:SetAsync(player.UserId,  playersData[Player.UserId])
end

this is greatly simplified but I hope you get the general idea

2 Likes