New help making a system that tells the player when they got a badge

Hello, I’m making a badge collecting game and I want to tell the player when they got a badge, and the total victor count.

Example:
Player 1 has gotten the badge 4th
Player 2 has gotten the badge 1st
Player 3 has gotten the badge 12th
You were 13th to get the badge

Here’s my code so far:

MAIN SERVER SCRIPT

local dss = game:GetService("DataStoreService")
local players = game:GetService("Players")

local data_store = dss:GetDataStore("test")

local save_module = require(script.Save)

-- adds data when player joins
function player_added(player)
	save_module.add_instances(player, data_store)
end

-- saves data when player leaves
function player_left(player)
	save_module.save_badges(player, data_store)
end

-- saves data for all players when the server shuts down
function save_all_players()
	for _, player in pairs(players:GetPlayers()) do
		pcall(function()
			save_module.save_badges(player, data_store)
		end)
	end
end

players.PlayerAdded:Connect(player_added)
players.PlayerRemoving:Connect(player_left)
game:BindToClose(save_all_players)

SAVE MODULE

local module = {}

module.add_instances = function(player, data_store)
	local data = Instance.new("Folder")
	data.Parent = player
	data.Name = "BadgeData"

	local success, loadedBadges = pcall(function()
		return data_store:GetAsync(player.UserId)
	end)
	
	if not success then
		player:Kick("Data error! Please try again in a bit.")
	end

	if success and loadedBadges then
		for badgeId, count in pairs(loadedBadges) do
			local badge = Instance.new("IntValue")
			badge.Name = badgeId
			badge.Value = count
			badge.Parent = data
		end
	end
end

module.save_badges = function(player, data_store)
	local data = player:WaitForChild("BadgeData")
	local badges = {}

	for i, badge in pairs(data:GetChildren()) do
		badges[badge.Name] = badge.Value
	end

	local success, err = pcall(function()
		return data_store:SetAsync(player.UserId, badges)
	end)

	if not success then
		print(err)
	end
end

module.add_badge = function(player, ID)
	
end

return module
1 Like

Can you not just use badge service?

1 Like

nope, it doesn’t tell you when you get the badge, or the victor count I believe

1 Like

It tells you when you get it, there’s a pop up and there is an amount that displays how many people got it total but that’s not visible when in game. If you have the scope to do so try using the api to grab that number. Don’t know how exactly to do that but it’s been done before

1 Like

My apologies, I’m new to helping others, so please let me know if this works or if there’s anything I can improve.

Here’s a possible solution for your badge system. It tracks global badge counts, notifies the player of their rank, and saves their badge data:

-- Main Server Script
local dss = game:GetService("DataStoreService")
local players = game:GetService("Players")

local badgeDataStore = dss:GetDataStore("BadgeGlobalCount") -- New DataStore for global badge counts
local playerDataStore = dss:GetDataStore("test")

local save_module = require(script.Save)

function player_added(player)
	save_module.add_instances(player, playerDataStore)
end

function player_left(player)
	save_module.save_badges(player, playerDataStore)
end

function save_all_players()
	for _, player in pairs(players:GetPlayers()) do
		pcall(function()
			save_module.save_badges(player, playerDataStore)
		end)
	end
end

players.PlayerAdded:Connect(player_added)
players.PlayerRemoving:Connect(player_left)
game:BindToClose(save_all_players)

-- Award a badge to a player
function award_badge(player, badgeId)
	save_module.add_badge(player, badgeId, badgeDataStore)
end

-- Save Module
local module = {}

module.add_instances = function(player, data_store)
	local data = Instance.new("Folder")
	data.Parent = player
	data.Name = "BadgeData"

	local success, loadedBadges = pcall(function()
		return data_store:GetAsync(player.UserId)
	end)

	if not success then
		player:Kick("Data error! Please try again in a bit.")
	end

	if success and loadedBadges then
		for badgeId, count in pairs(loadedBadges) do
			local badge = Instance.new("IntValue")
			badge.Name = badgeId
			badge.Value = count
			badge.Parent = data
		end
	end
end

module.save_badges = function(player, data_store)
	local data = player:WaitForChild("BadgeData")
	local badges = {}

	for _, badge in pairs(data:GetChildren()) do
		badges[badge.Name] = badge.Value
	end

	local success, err = pcall(function()
		return data_store:SetAsync(player.UserId, badges)
	end)

	if not success then
		print(err)
	end
end

module.add_badge = function(player, badgeId, globalDataStore)
	-- Track global badge count
	local rank = 1 -- Default to the first
	local success, count = pcall(function()
		return globalDataStore:IncrementAsync(badgeId, 1) -- Increment the count for the badge
	end)

	if success then
		rank = count
	else
		warn("Failed to update global badge count for badge ID: " .. badgeId)
		rank = "unknown" -- Fallback if IncrementAsync fails
	end

	-- Update player's badge data
	local badgeData = player:FindFirstChild("BadgeData")
	if badgeData and not badgeData:FindFirstChild(badgeId) then
		local badge = Instance.new("IntValue")
		badge.Name = badgeId
		badge.Value = 1
		badge.Parent = badgeData

		-- Notify the player
		local message = "Congratulations! You were the " .. rank .. "th player to get the badge!"
		game.ReplicatedStorage:WaitForChild("BadgeNotificationEvent"):FireClient(player, message)
	end
end

return module

Please let me know if this helps

2 Likes

Thanks, but if someone already has the badge, it just sets it to 0 for the other people.

After a bit of tweaking, it works. Thank you

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.