Stamp system for timed obby wins

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I’d like to make some sort of “stamp” system, where beating something under a period of time awards a stamp with a grade rating.

  2. What is the issue? Include screenshots / videos if possible!
    The issue is I have no idea on how would I save several data into datastores.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve looked for related stuff in the forum, and I couldn’t find relevant content. I also asked some of my friends for help, but none seem to know either.

Explaining everything with more detail: The system I want to create is similar to “Sonic & All-Stars Racing Transformed”, where beating a race awards a star. Picture below:
ex

I can provide more information such as the win script I’m using, etc. But for now I need help on the data saving part.

You could have a timer that starts when you start the obby, and based on the time it could give you a certain medal.

Thank you for the response. I already have the timer stuff, i just need to find out how to make the saving part.

You could store the data using DataStoreService, and then award the stamp if it’s better than a certain time. I’m not too experienced with DataStoreService, but I think that would be a good start for what you’re trying to do.

datastore service, create a datastore and store the wins in there if they’re good enough, if not, don’t store it

Thanks for the response. While I know how to store a single value, I don’t know how to store multiple of them. I as well have several courses, about 15 per area and I don’t know if making several values is the best approach for now.

If needed, here’s the win script I’m using:

function PlayerWin(Player:Player,BadgeID:number,TowerName:string, color:Color3, difficulty:string, nicelevel:string, winroom:string, isSC:boolean, Acronym) -- win function
	local Time:string,Boosts:table<string>?,AccurateTime:number = GetTimerRemote:InvokeClient(Player)
	if #Boosts > 0 and isSC then
		Player:Kick("You have bypassed the barrier and used a boost item.")
	else
		local CONFETTI:RemoteEvent = ReplicatedStorage:WaitForChild("WinRemote")
		CONFETTI:FireClient(Player, difficulty)
		local hits = 0
		if Player.Character then
			local Humanoid = Player.Character:FindFirstChild("Humanoid")
			if Humanoid then
				hits = Humanoid:WaitForChild("KillbrickHits").Value
				Humanoid.Health = Humanoid.MaxHealth
			end
			for k, v in pairs(workspace.Markers:GetChildren()) do
				difficultycolor = color
				if workspace.Markers:FindFirstChild(winroom) then
					Player.Team = WinnerTeam
					Teleport(Player.Character, workspace.Markers:FindFirstChild(winroom))
				else
					Player.Team = WinnerTeam
					Teleport(Player.Character, workspace.Markers.WinroomSpawn)
				end
			end
		end

		Acronym = Acronym or "???"

		if BadgeID > 0 then
			local module = require(game:GetService("ServerScriptService"):WaitForChild("BadgeCounter").BadgeGiver)
			task.spawn(function()
				module:AwardBadge(Player, BadgeID)
			end)
		end
		local SummaryRemote:RemoteEvent = ReplicatedStorage:WaitForChild("Summary", 10)
		local AmountGiven:number
		local DifficultyBonus:number
		local NoBoostsBonus:number
		local Time:string,Boosts:table<string>?,AccurateTime:number = GetTimerRemote:InvokeClient(Player)
		local Difficulty = difficulty
		local Items = Boosts


		if #Items > 0 then
			if isSC == true then
				--dont give np if player used boosts
			elseif isSC == false then
				if Difficulty == "Remorseless" then
					AmountGiven = 10
					DifficultyBonus = 10
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 20
				elseif Difficulty == "Intense" then
					AmountGiven = 10
					DifficultyBonus = 5
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 15
				elseif Difficulty == "Challenging" then
					AmountGiven = 10
					DifficultyBonus = -5
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 5
				elseif Difficulty == "Difficult" then
					AmountGiven = 10
					DifficultyBonus = -10
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
				elseif Difficulty == "Hard" then
					AmountGiven = 10
					DifficultyBonus = -10
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
				elseif Difficulty == "Medium" then
					AmountGiven = 10
					DifficultyBonus = -10
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
				elseif Difficulty == "Easy" then
					AmountGiven = 10
					DifficultyBonus = -10
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
				end
			end
		else
			if isSC == true then
				AmountGiven = 10
				DifficultyBonus = 80
				NoBoostsBonus = DifficultyBonus / AmountGiven * 1 + AmountGiven
				SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
				Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 90
				Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + NoBoostsBonus
				if Difficulty == "Terrifying" or "Catastrophic" then
					AmountGiven = 10
					DifficultyBonus = 155
					NoBoostsBonus = DifficultyBonus / AmountGiven * 1 + AmountGiven
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 165
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + NoBoostsBonus
				end
			elseif isSC == false then
				if Difficulty == "Remorseless" then
					AmountGiven = 10
					DifficultyBonus = 60
					NoBoostsBonus = DifficultyBonus / AmountGiven * 1 + AmountGiven
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 70
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + NoBoostsBonus
				elseif Difficulty == "Intense" then
					AmountGiven = 10
					DifficultyBonus = 15
					NoBoostsBonus = DifficultyBonus / AmountGiven * 1 + AmountGiven
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 25
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + NoBoostsBonus
				elseif Difficulty == "Challenging" then
					AmountGiven = 10
					DifficultyBonus = 5
					NoBoostsBonus = DifficultyBonus / AmountGiven * 1 + AmountGiven
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 15
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + NoBoostsBonus
				elseif Difficulty == "Difficult" then
					AmountGiven = 10
					DifficultyBonus = 0
					NoBoostsBonus = DifficultyBonus / AmountGiven * 1 + AmountGiven
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 10
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + NoBoostsBonus
				elseif Difficulty == "Hard" then
					AmountGiven = 10
					DifficultyBonus = -5
					NoBoostsBonus = DifficultyBonus / AmountGiven * 1 + AmountGiven
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + 5
					Player:WaitForChild("NEAT Points").Value = Player:WaitForChild("NEAT Points").Value + NoBoostsBonus
				elseif Difficulty == "Medium" then
					AmountGiven = 10
					DifficultyBonus = -10
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
				elseif Difficulty == "Easy" then
					AmountGiven = 10
					DifficultyBonus = -10
					NoBoostsBonus = 0
					SummaryRemote:FireClient(Player, AmountGiven, Difficulty, DifficultyBonus, NoBoostsBonus)
				end
			end
		end
		if Time == nil then Time = "an unknown amount of time" end
		local WinText:string = string.gsub(WinMessage,"{Player}",Player.Name)
		WinText = string.gsub(WinText,"{Time}",Time)
		if #Boosts > 0 then
			WinText = WinText .. " Boosts used: "
			for k,v in pairs(Boosts) do
				if k > 1 then WinText = WinText .. ", " end
				WinText = WinText .. v
			end
		end

		CheckChallenge(Player, Time, Boosts, AccurateTime, Acronym, difficulty, hits)

		if script.Switches.GlobalWinsEnabled.Value == true then
			if isSC == true then
				WinText = string.gsub(WinText,"{TowerName}",TowerName.." ["..difficulty.."]")
				GlobalWin(WinText)
				if script.Switches.WebhooksEnabled.Value == true then
					WebhookMsg(Player.Name, Time, TowerName, difficulty, nicelevel, Boosts, isSC, winroom)
				end
			else
				WinText = string.gsub(WinText,"{TowerName}",TowerName)
				GameAnnouncement(WinText,color, false)
				if script.Switches.WebhooksEnabled.Value == true then
					WebhookMsg(Player.Name, Time, TowerName, difficulty, nicelevel, Boosts, isSC, winroom)
				end
			end
		else
			WinText = string.gsub(WinText,"{TowerName}",TowerName)
			GameAnnouncement(WinText,color, false)
			if script.Switches.WebhooksEnabled.Value == true then
				WebhookMsg(Player.Name, Time, TowerName, difficulty, nicelevel, Boosts, isSC, winroom)
			end
		end
	end
end