Help with a player point system

Hello!

How can I create a currency system (points) that gives the player 1 point every second they play the game (that saves over time)?

Once I figure this first part out: ^^^

I’d like to make it so that when a gamepass called 2X POINTS is bought, the player then gets 2 points every second they play (that also saves in-game).

I’m going to have the players use these points to buy in-game cosmetics and such, but for now I just need this base point system down.

You can use MarketplaceService | Roblox Creator Documentation and DataStoreService | Roblox Creator Documentation

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")
local MarketplaceService = game:GetService("MarketplaceService")
local PlayerData = DataStoreService:GetDataStore("PlayerData")
local GamepassID = 0

Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	
	local Points = Instance.new("IntValue", leaderstats)
	Points.Name = "Points"
	
	local success, data = pcall(function()
		return PlayerData:GetAsync(player.UserId)
	end)
	if success and data then
		Points.Value = data.Points
	elseif not success then
		warn("There was an error loading the player data")
	end
end)

spawn(function()
	while wait(1) do
		for _, player in pairs(Players:GetPlayers()) do
			local success, result = pcall(MarketplaceService.UserOwnsGamePassAsync, MarketplaceService, player.UserId, GamepassID)
			if success and result then
				player.leaderstats.Points.Value += 2
			elseif success and not result then
				player.leaderstats.Points.Value += 1
			elseif not success then
				warn("An error occurred when checking if the player owns the gamepass")
			end
		end
	end
end)

Players.PlayerRemoving:Connect(function(player)
	local data = {
		Points = player.leaderstats.Points.Value
	}
	local success, err = pcall(function()
		PlayerData:UpdateAsync(player.UserId, function(oldData)
			return data
		end)
	end)
	if not success then
		warn(err)
	end
end)

game:BindToClose(function()
	if RunService:IsStudio() then
		return
	end
	for _, player in pairs(Players:GetPlayers()) do
		local data = {
			Points = player.leaderstats.Points.Value
		}
		local success, err = pcall(function()
			PlayerData:UpdateAsync(player.UserId, function(oldData)
				return data
			end)
		end)
		if not success then
			warn(err)
		end
	end
end)

Instead of using spawn(function() you shoud use corountine.wrap()

Essentially using it like:

coroutine.wrap(function()
print("test")
end)()

where would I insert this script?

Put the script in ServerScriptService.

will spawn(function() still work? What’s the difference?

Yes, spawn(function() will still work. There is not a big difference. Spawn runs the specified callback function in a separate thread, without yielding the current thread. And coroutines do the same, but it can be a bit faster than spawn. Because spawn has a wait() before the function is executed.