How can i optimize and clean up my DataStore?

Hey, as you read from the title my data store script is kind of messy, I was thinking of switching to profileservices but I am looking for an alternative as I don’t know how to use profileservices.

local DataStore = game:GetService("DataStoreService")

local CashData = 
	DataStore:GetDataStore("CashStats") --Cash Data
local GemData =
	DataStore:GetDataStore("GemStats") -- Gems Data
local LogData = 
	DataStore:GetDataStore("LogData4")


local Value = 0
game.Players.PlayerAdded:Connect(function(player)
	local leaderstats
		= Instance.new("Folder")
	leaderstats.Name= ("PLAYER_STATS")
	leaderstats.Parent= player
	local WORKAROUND= Instance.new("Folder")
	WORKAROUND.Name= ("leaderstats")
	WORKAROUND.Parent= player
	-----------------------------------------------------------
	local cash
		= Instance.new("IntValue")
	cash.Name= ("Tokens") --Cash Value
	cash.Parent = leaderstats
	cash.Value = 0 -- Starter Value
	cash.Value = CashData:GetAsync(player.UserId) or Value
	CashData:SetAsync(player.UserId, cash.Value)
	-----------------------------------------------------------
	local gems
		= Instance.new("IntValue")
	gems.Name= ("Wins") --Gems Value
	gems.Parent = leaderstats
	gems.Value = 0 -- Starter Value
	gems.Value = GemData:GetAsync(player.UserId) or Value
	GemData:SetAsync(player.UserId, gems.Value)
	------------------------------------------------------------
	local log
		= Instance.new("IntValue")
	log.Name= ("SawLog") --Gems Value
	log.Parent = player
	log.Value = 0 -- Starter Value
	log.Value = LogData:GetAsync(player.UserId) or Value
	LogData:SetAsync(player.UserId, log.Value)
	------------------------------------------------------------
	local WORK
		= Instance.new("IntValue")
	WORK.Name= ("Wins") --Gems Value
	WORK.Parent = WORKAROUND
	WORK.Value = GemData:GetAsync(player.UserId) or Value
	game.Players.PlayerRemoving:Connect(function(player)
		
		CashData:SetAsync(player.UserId, player.PLAYER_STATS.Tokens.Value)
		
		GemData:SetAsync(player.UserId, player.PLAYER_STATS.Wins.Value)
		
		LogData:SetAsync(player.UserId, player.SawLog.Value)
	end)
	
	gems.Changed:Connect(function()
		WORK.Value = gems.Value
	end)
	
end) 


game:GetService("ReplicatedStorage").RemoteEvents.UpdateLog.OnServerEvent:Connect(function(player)
	player:FindFirstChild("SawLog").Value = 1
	print("received")
	print(player.Name)
	print(player:FindFirstChild("SawLog").Value)
end)

Why don’t you store stuff like cash, gems and so on in a table?

Thank you for responding, unfortunately i’m not the best scripter so I it’s kind of difficult for me to understand, do you mean like in a module script? Because if so i did think about it but i don’t really know how to start.
As i mentioned in my post: Should i switch to profileservice or should i clean up this script?

(ABOUT THE STRINGS LIKE “cash” AND “gems” I CHANGED THEM BUT THEY REMAINED THE SAME IN THE SCRIPT BECAUSE I FORGOT TO CHANGE THEM)

This script has a lot of vulnerabilities and leaves a lot of opportunities for things like data loss.

  1. You created a PlayerRemoving connection inside of your PlayerAdded connection. This means that whenever one player joins, that function will be run one more time when a player leaves.
  2. You aren’t using any kind of error handling logic for the data store asynchronous network requests (e.g. SetAsync). You can also add retry logic so if it fails the first time, it tries again.
  3. You are overwriting data way too often. You overwrite it as soon as they join and then 3 times when they leave, for example. These Get and Set requests will massively eat into the server’s data request budget.
  4. You have no security measures like session locking or data versioning to prevent outdated data from being saved. Adding these can help prevent data loss.
  5. Don’t use a separate data store for each data item. Store it in a table like @SimTim38 said.
  6. Utilise UpdateAsync and it’s features for stronger, more secure data saving.
  7. You have no kind of BindToClose saving or yielding for when the server closes. This means data requests for player getting kicked may not go through, hence their data will not be saved.

Sorry if it sounds like I’m just having a rant, I’m just pointing out the issues I found with the script. If you implement the changes it would make your data system a lot more secure.

If you feel comfortable putting in these features yourself, then go right ahead. If you have absolutely no idea and don’t really want to do it yourself, use ProfileService because it handles that stuff for you.

Thank you so much for responding!
As i mentioned before i’m nto the best with scripting so I may stick with profileServices.
I have a question, can profileservice save folders with values inside? Anyways than kyou so much for responding!

I’ve never used ProfileService, but I would assume so if you serialised all the data into a table first.

Thank you so much! I have no other thing to say thank you again to the both of you for responding!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.