local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")

local function playerAdded(player)
	local progress = Instance.new("Folder", player)
	progress.Name = "Progress"

	local playerUserId = '-progress'..player.UserId
	local data = playerData:GetAsync(playerUserId)
	if data then
		for i, v in pairs(progress:GetChildren()) do
			v.Value = data["Trees"]  	--Trees as example
		end
	else
			print("New Game")
	end
end

local function create_table(player)
	local playerProgress = {}
	for i, progress in pairs(player.Progress:GetChildren()) do
		playerProgress[progress.Name] = progress.Value
	end
	return playerProgress
end

local function onPlayerExit(player)
	local playerProgress = create_table(player)
	local success, err = pcall(function()
		local playerUserID = '-progress'..player.UserId
		playerData:SetAsync(playerUserID, playerProgress)
	end)

	if not success then
		warn("Could not save tycoon")
	end
end

game.Players.PlayerAdded:Connect(playerAdded)
game.Players.PlayerRemoving:Connect(onPlayerExit)

hi, im trying to make an autosave for my tycoon game and this is my script so far what im trying to achieve is that when a player purchase something, an ObjectValue will be created into the Progress Folder... When the player leaves the game, the Progress Folder and its object value will be saved. Meanwhile, when the player enter the game and touched the claim button, i want it to check the player's Progress Folder and load what he/she bought. The claim button script is below. But i dont know if my idea is efficient or not. I tried to play the game, but the tycoon doesn't save. If you guys think i should change how the autosave works, feel free to comment.. Im still new to scripting thank you

local button = script.Parent
local tycoon = script.Parent.Parent
local buttonBase = script.Parent.Parent.ClaimBase
local manage = tycoon.Management

local function getPlayerFromPart(part)
	local character = part.Parent

	if character then
		local player = game.Players:GetPlayerFromCharacter(character)
		return player
	end
end

local function assignTycoon(player)
	local playerValue = Instance.new("ObjectValue")

	playerValue.Name = "TycoonOwned"
	playerValue.Value = tycoon
	playerValue.Parent = player

	tycoon.TycoonOwner.Value = player
end

local function tycoonSave(player)
	local progress = player:WaitForChild("Progress")
	
	for i, v in pairs(progress:GetChildren()) do
		if v.Value then
			v.Value.BuyButon:Destroy()
			
			for j, k in pairs(v.Value.PurchasedItem:GetChildren()) do
				k.Transparency = 0
				k.CanCollide = true
			end
			
		end
	end
	
end

local function onTouched(otherPart)
	local player = getPlayerFromPart(otherPart)

	if player then
		local tycoonOwned = player:FindFirstChild("TycoonOwned")

		if not tycoonOwned then
			assignTycoon(player)
			tycoonSave(player)
			button:Destroy()
			buttonBase:Destroy()
		end
	end
end

button.Touched:Connect(onTouched)