DataStore System Review and what to change

I’m Quintin and i’ve been scripting since 6 years and i’m 14 years of age and i’ve done various of stuff in scripting exept data i was never really bothered to cause i just used a friend’s data, but i decided to change that now so i tried making my Own Data System and it works all good. But i want some reviews on how i can improve this data and make it as efficent as possible

Here’s the Module Script :

--//Types
type Player = {
	Data : Folder;
	UserId : number;
	Name : string;
};

--//Services
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

--//Modules
local StatsModule = require(script.Data)
local Settings = require(script.Settings)

--//Variables
 local DataStore = DataStoreService:GetDataStore(Settings.DataKey)
 
--//RunTime
local DataModule = {}

DataModule.CreateFolders = function(Player : Player)
	for i,v in StatsModule.Folders do
		local NewFolder = Instance.new("Folder")
		NewFolder.Parent = Player.Data
		NewFolder.Name = i
	end
	print("Created Folders For ".. Player.Name)
end

DataModule.FoldersToTable = function(DataFolder : Folder)
	local DataTable = {}
	
	for i,v in DataFolder:GetDescendants() do
		if v:IsA("NumberValue") or v:IsA("BoolValue") or v:IsA("StringValue") then
			DataTable[v.Name] = v.Value
		end
	end
	
	return DataTable
end

DataModule.FindValue = function(name : string, DataFolder : Folder)
	for i,v in DataFolder:GetDescendants() do
		if v.Name == name then
			return v
		end
	end
	print("Couldn't find Value ".. name.." for ".. DataFolder.Parent.Name)
	return nil
end

DataModule.LoadInValue = function(Table : SharedTable, DataFolder : Folder)
	for i,v in Table do
		local Value = DataModule.FindValue(i, DataFolder)
		if Value then
			Value.Value = v
		end
	end
	print("Loaded in Values for ".. DataFolder.Parent.Name)
end

DataModule.CreateValues = function(Player : Player)
	for i,v in StatsModule.Stats do
		local NewValue = Instance.new(v[2])
		NewValue.Value = v[1]
		NewValue.Parent = Player.Data[v[3]]
		NewValue.Name = i
	end
	print("Created Values For ".. Player.Name)
end

DataModule.SetUpPlayer = function(Player : Player)
	DataModule.CreateFolders(Player)
	DataModule.CreateValues(Player)
end

DataModule.LoadData = function(Player : Player)
	local NewDataFolder = Instance.new("Folder")
	NewDataFolder.Name = "Data"
	NewDataFolder.Parent = Player
	
	local Loaded = Instance.new("BoolValue")
	Loaded.Name = "Loaded"
	Loaded.Parent = Player
	
	local PlayerData

	local succes, errorMessage = pcall(function()
		PlayerData = DataStore:GetAsync(Player.UserId)
	end)
	
	DataModule.SetUpPlayer(Player)
	
	if PlayerData == nil and succes then
		print("New Data for ".. Player.Name)
		Loaded.Value = true
	else
		DataModule.LoadInValue(PlayerData, NewDataFolder)
		Loaded.Value = true
		print("Loaded Data for ".. Player.Name)
	end
	
	if not succes  then
		print(errorMessage)
	else
		while wait(Settings.AutoTime) do
			DataModule.SaveData(Player)
		end
	end
end

DataModule.SaveData = function(Player : Player)
	if Settings.SaveInStudio == false then return end
	
	local DataFolder = Player.Data
	if not DataFolder then return end

	if Player:FindFirstChild("Loaded") == nil or not Player.Loaded.Value then
		print("Data not loaded yet didn't save for ".. Player.Name)
		return
	end
	
	local DataTable = DataModule.FoldersToTable(DataFolder)
	
	print(DataTable)
	
	local success, errorMessage = pcall(function()
		DataStore:SetAsync(Player.UserId, DataTable)
	end)
	if not success then
		print(errorMessage)
	else
		print("Succesfully Saved Data for ".. Player.Name)
	end
end

DataModule.Start = function()
	Players.PlayerAdded:Connect(DataModule.LoadData)
	Players.PlayerRemoving:Connect(DataModule.SaveData)
	game:BindToClose(function()
		for i,v in game.Players do
			DataModule.SaveData(v)
		end
	end)
end

return DataModule

So incase u got any Tips/reviews please go ahead

But i’ve tried using UpdateAsync but it said unable to cast value to functions which i don’t get why it says that

2 Likes

To overwrite a player’s data using UpdateAsync, you need to return a value rather than directly plugging in a value.

dataStore:UpdateAsync(key, function(oldValue)
    return newValue
end)
2 Likes

In the CreateFolders and CreateValues function set the parent as the last property of the newly made instance.

1 Like

i don’t think this will do much. It’s basically the same doesn’t have a impact on performace

1 Like

Thank’s it’s working now i appreciate ur help.

It’s 1.25 times faster and a good practice in general.

1 Like

Ah, i didn’t know that. Alright.

1 Like

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