wait(.2)
local Players = game:GetService("Players")
local BadgeService = game:GetService("BadgeService")
local badges = {
{id = 825470753469894, name = "Nuala", texture = "rbxassetid://18940489185"},
{id = 3993436032447000, name = "Sunflower Nuala", texture = "rbxassetid://18944802036"},
{id = 2794494538841400, name = "Beach Ball Nuala", texture = "rbxassetid://80222689551657"},
{id = 2143889494944777, name = "Nualawood", texture = "rbxassetid://18946833131"},
{id = 4176424032128923, name = "Giant Nuala", texture = "rbxassetid://103876632520199"},
{id = 3182012389732672, name = "Hydrant Nuala", texture = "rbxassetid://100487757734727"},
{id = 1101050386441915, name = "Sailor Nuala", texture = "rbxassetid://91109574359405"},
{id = 661002574639906, name = "Sand Castle Nuala", texture = "rbxassetid://124947880599175"},
{id = 473377285836462, name = "Nuala Miner", texture = "rbxassetid://128743420133652"},
{id = 3762525486484396, name = "Nuala in a Car", texture = "rbxassetid://95427629249900"},
{id = 340050098656158, name = "Golden Nuala", texture = "rbxassetid://126138662021056"},
{id = 2160660132301528, name = "Nualafruit", texture = "rbxassetid://77055838031866"},
{id = 1063303013099351, name = "Fossilized Nuala", texture = "rbxassetid://79465460318986"},
{id = 270485295814570, name = "Orange Cat Nuala", texture = "rbxassetid://73816275866374"},
{id = 755827457568771, name = "One with the Trees Nuala", texture = "rbxassetid://71257673798622"},
--medium
{id = 1420164253190837, name = "Squirrel Nuala", texture = "rbxassetid://113482393948846"},
{id = 4358658733723848, name = "Sunala", texture = "rbxassetid://93600606095858"},
{id = 3402913698605796, name = "Darkness Nuala", texture = "rbxassetid://112489906966646"},
{id = 1738741922042695, name = "Soaked Nuala", texture = "rbxassetid://114570479911453"},
{id = 3008797889549368, name = "Pet Nuala", texture = "rbxassetid://112869458098664"},
{id = 1832432256834839, name = "Stuckala", texture = "rbxassetid://84250092672774"},
{id = 2970196169244497, name = "Spider Nuala", texture = "rbxassetid://80339252884121"},
{id = 4072019634641547, name = "Rooted Nuala", texture = "rbxassetid://96008593268327"},
{id = 192741430310577, name = "Blurry Nuala", texture = "rbxassetid://113493534989565"},
--hard
{id = 204729745518514, name = "Sorta Secret Nuala", texture = "rbxassetid://70639536016768"},
{id = 2203150997366991, name = "CEO Nuala", texture = "rbxassetid://79820069482902"},
{id = 727546042646471, name = "Sparkling Water Nuala", texture = "rbxassetid://108536789846216"},
{id = 3962196304428070, name = "Blue Cheese Nuala", texture = "rbxassetid://73818890487547"},
{id = 2434531127950952, name = "Shiny Holo Nuala Card", texture = "rbxassetid://110793207823615"},
{id = 175513168695701, name = "Inverted Nuala", texture = "rbxassetid://132450627819203"},
{id = 1713165856656032, name = "Nuala Popsicle", texture = "rbxassetid://77270470518850"},
{id = 533709723862086, name = "Geode Nuala", texture = "rbxassetid://126554522594528"},
--intense
{id = 454847409910032, name = "Secret Nuala", texture = "rbxassetid://96152411579165"},
{id = 996134040535768, name = "Clockwork Nuala", texture = "rbxassetid://113871798097662"},
{id = 454847409910032, name = "Glitchala", texture = "rbxassetid://118536585617465"},
{id = 1731114169300166, name = "All Seeing Nuala", texture = "rbxassetid://137052549280413"},
{id = 2036934203903108, name = "Shattered Nuala", texture = "rbxassetid://95519084437532"},
{id = 4476419490344865, name = "Getting Over Nuala", texture = "rbxassetid://73186683114218"},
{id = 1148612316112491, name = "Perspective Nuala", texture = "rbxassetid://110993534956541"},
{id = 4417167326052753, name = "Evil Sunflower Nuala", texture = "rbxassetid://84628998129290"},
{id = 2043023404572736, name = "Enchanted Nuala", texture = "rbxassetid://93246288392901"},
{id = 3987020990443036, name = "MyDala", texture = "rbxassetid://82763103723814"},
{id = 2953722112281299, name = "Nualoss", texture = "rbxassetid://72832102492468"},
--insane
{id = 40126125060604, name = "Painting Nuala", texture = "rbxassetid://82542755960424"},
{id = 2322113928663430, name = "Nuala Tome", texture = "rbxassetid://105171665819956"},
{id = 862720075315443, name = "There is no Nuala", texture = "rbxassetid://103116132463469"},
{id = 2444506894085935, name = "Transparency Grid Nuala", texture = "rbxassetid://126548735691996"},
{id = 3360273555884087, name = "Nuala of the Highest Lair", texture = "rbxassetid://18983536706"},
{id = 3400104666010003, name = "WeirdCala", texture = "rbxassetid://127502625460014"},
{id = 4187874656078620, name = "Very Secret Nuala", texture = "rbxassetid://99422042744585"},
{id = 4351712341478131, name = "Nuala Sundae", texture = "rbxassetid://120606036215366"},
{id = 149872491772465, name = "Missing Nuala", texture = "rbxassetid://130712649243760"},
{id = 2989237371775314, name = "Error Nuala", texture = "rbxassetid://77765934507270"},
{id = 4298685936848608, name = "NoClipala", texture = "rbxassetid://83885949305070"},
{id = 1480730204551845, name = "Amazeing Nuala", texture = "rbxassetid://116736515402482"},
--extreme
{id = 3820190767963370, name = "Trolla", texture = "rbxassetid://118260270782448"},
{id = 248692490906882, name = "Skinwalker Nuala", texture = "rbxassetid://77030405433033"},
{id = 4065174263016170, name = "Recollectionala", texture = "rbxassetid://102689282022489"},
{id = 1375269726864897, name = "Corrupted Nuala", texture = "rbxassetid://107120486096645"},
{id = 3221419613951887, name = "Distorted Nuala", texture = "rbxassetid://104523945828252"},
{id = 2381729989399521, name = "Anualag Horror", texture = "rbxassetid://76334306387556"},
{id = 2407518871994148, name = "Nuala Constellation", texture = "rbxassetid://120362717482625"},
{id = 4488432287139738, name = "Super Secret Nuala", texture = "rbxassetid://70980098280356"},
--scardeycat
{id = 2953722112281299, name = "Nuala Over Zero", texture = "rbxassetid://80461440223428"},
{id = 4241551891661502, name = "Internet Nuala", texture = "rbxassetid://"},
{id = 2629260279024232, name = "The Nuala is Lava", texture = "rbxassetid://135228501157252"},
{id = 2488018575890184, name = "Nuala of the Upside Down", texture = "rbxassetid://112448225990430"},
{id = 947573328526532, name = "Insanely Secret Nuala", texture = "rbxassetid://76411513054539"},
{id = 2293209590453508, name = "Nualas in Time", texture = "http://www.roblox.com/asset/?id=139010281450474"},
--catastrophic
{id = 1491544040784761, name = "Nuala RNG", texture = "rbxassetid://120562327467124"},
{id = 1199522669258002, name = "Black Hole Nuala", texture = "rbxassetid://77810750404723"},
{id = 2909418844436231, name = "Badger Nuala", texture = "rbxassetid://18983578620"},
{id = 3431167427759979, name = "Truly Trolling Nuala", texture = "rbxassetid://133523563740746"},
--hairrowing
{id = 1805495013054783, name = "Difficulty Chart Nuala", texture = "rbxassetid://111085992573816"},
{id = 1314449722405156, name = "Badger Nuala 2: The Badgering", texture = "rbxassetid://92588827580523"},
--meowciless
-- More badges as needed,
-- ...
}
local totalBadges = #badges
-- Function to retry badge checks
local function safeUserHasBadgeAsync(userId, badgeId, retryCount)
retryCount = retryCount or 0
print("Checking if user " .. userId .. " has badge " .. badgeId)
local success, result = pcall(function()
return BadgeService:UserHasBadgeAsync(userId, badgeId)
end)
if success then
print("Badge check succeeded for user " .. userId .. " and badge " .. badgeId)
return result
else
if retryCount < 3 then
wait(1) -- Wait a bit before retrying
print("Badge check failed for user " .. userId .. " and badge " .. badgeId .. ". Retrying...")
return safeUserHasBadgeAsync(userId, badgeId, retryCount + 1)
else
print("Failed to check badge " .. badgeId .. " for user " .. userId)
return false
end
end
end
-- Function to update badge position inside the ScrollFrame
local function updateBadgePositionAndSize(dexImage, positionIndex)
local badgesPerRow = 5
local badgeSize = UDim2.new(0.1, 0, 0.1, 0)
local spacing = UDim2.new(0.05, 0, 0.05, 0)
local baseOffsetX = UDim2.new(.1, 0, 0, 0)
local baseOffsetY = UDim2.new(0, 0, 0.1, 0)
local row = math.floor((positionIndex - 1) / badgesPerRow)
local column = (positionIndex - 1) % badgesPerRow
if dexImage then
dexImage.Position = UDim2.new(column * (badgeSize.X.Scale + spacing.X.Scale), 0, row * (badgeSize.Y.Scale + spacing.Y.Scale), 0) + baseOffsetX + baseOffsetY
else
warn("dexImage is nil for badge at index: " .. tostring(positionIndex))
end
end
-- Function to check badges and update ScrollFrame
local function checkBadges(player, scrollFrame, badgeCounterLabel, retries)
wait(.2)
retries = retries or 0
print("Checking badges...")
local badgeCount = 0 -- Track the number of badges found
for index, badge in ipairs(badges) do
print("Checking badge:", badge.name)
local hasBadge = safeUserHasBadgeAsync(player.UserId, badge.id, retries)
local dexImage = scrollFrame:FindFirstChild(badge.name)
if dexImage then
print("Found badge image:", badge.name)
dexImage.Image = badge.texture
updateBadgePositionAndSize(dexImage, index)
if hasBadge then
print("Badge is owned:", badge.name)
dexImage.ImageTransparency = 0
local textLabel = dexImage:FindFirstChildOfClass("TextLabel")
if textLabel then
textLabel.TextColor3 = Color3.new(0, 1, 0) -- Green for owned badges
end
badgeCount = badgeCount + 1 -- Increment the badge count
else
print("Badge is not owned:", badge.name)
dexImage.ImageTransparency = 0.5
local textLabel = dexImage:FindFirstChildOfClass("TextLabel")
if textLabel then
textLabel.TextColor3 = Color3.new(1, 1, 1) -- White for unowned badges
end
end
else
print("Badge image not found:", badge.name)
end
end
print("Badge count:", badgeCount)
-- Update the badge counter (X / Y format)
if badgeCounterLabel then
badgeCounterLabel.Text = "" .. badgeCount .. " / " .. totalBadges .. " Nualas"
end
if badgeCount >= 20 then
print("20 badges have been found!")
-- Add any action you want to perform here when 20 badges are found
game.ReplicatedStorage:WaitForChild("taxi"):FireServer(player)
end
end
-- Function called when player's character is added
local function onCharacterAdded(character)
wait(2) -- Slight delay to ensure character is loaded
print("Character added")
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local screenGui = playerGui:FindFirstChild("ScreenGui")
if not screenGui then
warn("ScreenGui not found!")
return
end
local dexFrame = screenGui:FindFirstChild("dexPage1")
if not dexFrame then
warn("dexPage1 frame not found!")
return
end
local scrollFrame = dexFrame:FindFirstChild("ScrollFrame")
if not scrollFrame then
warn("ScrollFrame not found inside dexPage1!")
return
end
-- Create a badge counter label if not already present
local badgeCounterLabel = dexFrame.ScrollFrame:FindFirstChild("BadgeCounter")
if not badgeCounterLabel then
badgeCounterLabel = Instance.new("TextLabel")
badgeCounterLabel.Name = "BadgeCounter"
badgeCounterLabel.Size = UDim2.new(0.4, 0, 0.1, 0) -- Width is 40% of the parent frame, height is 10%
badgeCounterLabel.Position = UDim2.new(0.25, 0, 0, 0) -- Center horizontally and place it at the top
badgeCounterLabel.BackgroundTransparency = 1
badgeCounterLabel.TextScaled = true
badgeCounterLabel.TextColor3 = Color3.new(1, 1, 1) -- White text
badgeCounterLabel.TextStrokeTransparency = 0.5 -- Optional: Adds a stroke to make text stand out
badgeCounterLabel.Parent = dexFrame.ScrollFrame
end
-- Check badges and update ScrollFrame
wait(.1)
checkBadges(player, scrollFrame, badgeCounterLabel, 0)
end
-- Connect the Player.CharacterAdded event
local player = Players.LocalPlayer
player.CharacterAdded:Connect(onCharacterAdded)
-- Handle case where the player's character is already loaded
if player.Character then
onCharacterAdded(player.Character)
end
I want to improve this save system. I’m 99% sure the issue is less to do with the code and more to do with BadgeService and BadgeDetection being overloaded. So, I can think of two possible routes to go with this…
1.Ssomehow make it so the badges aren’t overloaded, wether that be by scripting or some other magical method I don’t know about, without slowing it down too much. in other words, optimizing.
And 2… ugh… remake the entire badge system to use datastores instead of badge detection… fun.
So, if option 1 works, amazing. If option 2 is needed… Im willing to put in the work. But, for both, I’d like a little nudging in the right direction lol.