Data Store

data-storeluascriptfree

Thursday, April 18, 2024

LOCALS

local players = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("test-0")
local SaveCooldown = 10
local playerData = script.PlayerData

CODE

local function SaveData(player)
	local PData = {}
	for _, folder in pairs(player:GetChildren()) do
		if playerData:FindFirstChild(folder.Name) then
			if playerData[folder.Name]:GetAttribute("SaveChildren") == true then
				PData[folder.Name] = {}
				if playerData[folder.Name]:GetAttribute("SaveChildrenValues") == true then
					for _, child in pairs(folder:GetChildren()) do
						if not child:GetAttribute("DoNotSaveValue") then
							table.insert(PData[folder.Name], {child.Name, child.Value, child.ClassName})
						end
					end
				else
					for _, child in pairs(folder:GetChildren()) do
						if not child:GetAttribute("DoNotSaveValue") then
							table.insert(PData[folder.Name], {child.Name, child.ClassName})
						end
					end
				end
			end
		end
	end

	local success, errorMsg = pcall(function()
		dataStore:SetAsync(player.UserId.."_Key", {["PlayerData"] = PData})
	end)

	if success then
		print("Saved Data")
	else
		warn(errorMsg)
	end
end

local function LoadData(player)
	for _, v in pairs(playerData:GetChildren()) do
		v:Clone().Parent = player
	end

	local data
	local success, errorMsg = pcall(function()
		data = dataStore:GetAsync(player.UserId.."_Key")
	end)
	if errorMsg then
		wait(errorMsg)
		player:Kick("Could not save data")
	end
	if data then
		local PData = data.PlayerData
		for i, v in pairs(PData) do
			if #v > 0 then
				for x, c in pairs(v) do
					local value
					if playerData:FindFirstChild(tostring(i)):FindFirstChild(c[1]) then
						value = player:FindFirstChild(tostring(i)):FindFirstChild(c[1])
					else
						if c[3] == nil then
							value = Instance.new(tostring(c[2]))
						else
							value = Instance.new(tostring(c[3]))
						end
					end
					value.Name = c[1]
					value.Value = c[2]
					value.Parent = player[tostring(i)]
				end
			end
		end
	end
end

local function PlayerRemoving(player)
	SaveData(player)
end

local function PlayerAdded(player)
	LoadData(player)
	
	while wait(SaveCooldown) do
		SaveData(player)
	end
end

players.PlayerAdded:Connect(PlayerAdded)
players.PlayerRemoving:Connect(PlayerRemoving)

game:BindToClose(function()
	for _, player in pairs(players:GetPlayers()) do
		coroutine.wrap(SaveData)(player)
	end
end)

SET-UP

1) Create a SERVER SCRIPT into the SERVER SCRIPT SERVICES and add this code in it.
2) Create a FOLDER into the SCRIPT that you have made and name it "PlayerData"
3) Create another FOLDER into the "PlayerData" FOLDER and name it to what you want


NOTES
- You can use these ATTRIBUTES to give a roles to your FOLDERS-VALUES:
1) SaveChildren --Will save your folder childrens (FOLDER ATTRIBUTE)
2) SaveChildrenValues --Will save your folder childrens values (FOLDER ATTRIBUTE)
3) DoNotSaveValue --Will not save your folder childrens values (VALUE ATTRIBUTE)