Data Store not very good

Someone told me that my data store script was very bad, I dont really understand what they are trying to tell me because I am very new to scripting. Is there anyone that can explain it to me in idiot language?


local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local Module = require(script.ModuleScript)
local dataStore = DataStoreService:GetDataStore("MyDataStore")

local function saveData(player)
	local tableToSave = {
		Coins = player.leaderstats.Coins.Value,
		OwnedGH = player.GoldenHook.Owned.Value,
		EquippedGH = player.GoldenHook.Equipped.Value,

		OwnedTP = player.TPose.Owned.Value,
		EquippedTP = player.TPose.Equipped.Value,
		OwnedUS = player.UpsideDown.Owned.Value,
		EquippedUS = player.UpsideDown.Equipped.Value,
		OwnedWH = player.WoodenHook.Owned.Value,
		EquippedWH = player.WoodenHook.Equipped.Value,
		EquippedIH = player.InvisibleHook.Equipped.Value,
		OwnedIH = player.InvisibleHook.Owned.Value

	local success, errorMessage = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave)

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")

	local leaderstats ="Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Coins ="IntValue")
	Coins.Name = "Coins"
	Coins.Parent = leaderstats
	local InvisibleHook ="Folder")
	InvisibleHook.Name = "InvisibleHook"
	InvisibleHook.Parent = player
	local OwnedIH ="BoolValue")
	OwnedIH.Name = "Owned"
	OwnedIH.Parent = InvisibleHook
	local EquippedIH ="BoolValue")
	EquippedIH.Name = "Equipped"
	EquippedIH.Parent = InvisibleHook
	local WoodenHook ="Folder")
	WoodenHook.Name = "WoodenHook"
	WoodenHook.Parent = player
	local OwnedWH ="BoolValue")
	OwnedWH.Name = "Owned"
	OwnedWH.Parent = WoodenHook
	local EquippedWH ="BoolValue")
	EquippedWH.Name = "Equipped"
	EquippedWH.Parent = WoodenHook
	local UpsideDown ="Folder")
	UpsideDown.Name = "UpsideDown"
	UpsideDown.Parent = player
	local OwnedUS ="BoolValue")
	OwnedUS.Name = "Owned"
	OwnedUS.Parent = UpsideDown
	local EquippedUS ="BoolValue")
	EquippedUS.Name = "Equipped"
	EquippedUS.Parent = UpsideDown
	--//Golden Hook//--
	local GoldenHook ="Folder")
	GoldenHook.Name = "GoldenHook"
	GoldenHook.Parent = player

	local OwnedGH ="BoolValue")
	OwnedGH.Name = "Owned"
	OwnedGH.Parent = GoldenHook
	local EquippedGH ="BoolValue")
	EquippedGH.Name = "Equipped"
	EquippedGH.Parent = GoldenHook

	local TPose ="Folder")
	TPose.Name = "TPose"
	TPose.Parent = player

	local OwnedTP ="BoolValue")
	OwnedTP.Name = "Owned"
	OwnedTP.Parent = TPose
	local EquippedTP ="BoolValue")
	EquippedTP.Name = "Equipped"
	EquippedTP.Parent = TPose
	local Folder4 ="Folder")
	Folder4.Name = "NumberOfHooks"
	Folder4.Parent = player

	local IntValue2 ="IntValue")
	IntValue2.Name = "Amount"
	IntValue2.Parent = Folder4

	local data = nil

	local success, errorMessage = pcall(function()
		data = dataStore:GetAsync(player.UserId) 

	if success and data then 
		Coins.Value = data.Coins
		OwnedGH.Value = data.OwnedGH
		OwnedTP.Value = data.OwnedTP
		EquippedTP.Value = data.EquippedTP
		EquippedGH.Value = data.EquippedGH
		EquippedUS.Value = data.EquippedUS
		OwnedUS.Value = data.OwnedUS
		EquippedIH.Value = data.EquippedIH
		OwnedIH.Value = data.OwnedIH
		EquippedWH.Value = data.EquippedWH
		OwnedWH.Value = data.OwnedWH
		print("The player has no data!") -- The default will be set to 0


game:BindToClose(function() -- When the server shuts down
	for _, player in Players:GetPlayers() do -- Loop through all the players

Module script inside other script (I was told to make this)

local module = {}

module.PlayerData = {


return module

There is nothing wrong with using vanilla datastore, but I would strongly advise taking a look at tools built on top of DataStoreService for handling data safely and more robustly:
Please see: DataStore2 or ProfileService

Other tips here would be to use UpdateAsync vs SetAsync, as SetAsync can overwrite the previously cached data and cause data loss.

I also think you could be more descriptive with your variable naming conventions, I am unclear what you are trying to abbreviate within tableToSave.

If you have any questions please let me know.


Do not use datastore2, use profile service, or your own profile based datastore.

1 Like

I would personally use ProfileService because of session locking and data loss prevention. Session locking is very important for your game especially if you have a trading system.

ProfileService is the standard.

1 Like

I concur. Please see: How would I start a table trading system? - #2 by Blankscarface23