Also, the icon is gold/yellow not blue (for the badge received icon)
Yeah, that’s actually intentional, I didn’t want it to stay the same so that people could notice it wasn’t quite roblox badges.
Maybe make it like customizable like u could change it to goal reached or achievement achieved ya know?
also make it look less like roblox badge some people might have thought that image was actual real getting a badge.
Thanks for the idea. I might add some function to change this setting globally. Expect that soon (maybe) when I get time.
I know DS2 has something like .PatchGlobalSettings() or something, I guess that’s achievable here.
In the v1 you were able to use the badge’s “picture” as the notification image, that might become a thing here as well.
If anyone runs into issues, try submitting a issue on GitHub. I kind of just want it like that because I wanna use GitHub more lol.
Love this. Have a quick question though, how would I make a gui that displays how many badges a player owns out of the total amount of badges like “2/12 badges owned”? Like get the two number values. I have put these print statements but both output wrong.
if profile then
local badgeProfile = badgeService3:LoadProfile(plr, profile.Data.Badges)
delay(5, function()
if badgeProfile.Data then
local owned = badgeProfile.Data
local badgers = BadgeService3:GetBadges()
print(#owned)
print(#badgers)
badgeProfile:AwardBadge("Welcome")
end
end)
both print 0 though…
Here are the two badges right now.
Does the print statements not return because they are dictionaries and the #(table) only works on arrays? Would I have to loop through the tables and count the items in them instead?
Actually # should works on any table. This is pretty odd, can you try printing what these are before printing how many values are inside them? Btw, :GetOwnedBadges() actually returns an array! So it would work, you’re using :onUpdate() to update the profile store profile right?
I just noticed you’re using profile.Data to count the badges, it’s fine, but try using :GetOwnedBadges() for testing. It will transform it into an array, so it should work.
If it ends up not really working, i guess you can illerate through the table if it ends up not working.
#
only works on arrays and partially on mixed tables.
Ordered indexes (numerical keys) are always counted, but keys are not counted by #
and are instead skipped.
Oh ok, then yes @motlopoway, you would have to use a for loop or keep that number somewhere for the :GetBadges(), since :GetOwnedBadges() returns an array, you can use # on it.
Your request was added to the milestones of this module.
@motlopoway also added that to milestones, some function could be useful.
(pool removed, just went with per-profile onBadgeAwarded event)
I actually forgot to talk about this, but I still recommend using :Delete() if you’re working with your own solution. In this case basic datastores, BadgeService3 currently yields for 5 seconds before garbage collecting the profile automatically. I still highly recommend that you do a DeepCopy of the profile.Data table before trying to save if you’re messing around with basic datastore use. This is not needed if you’re using a solution like ProfileService/DS2 which changes data as it changes.
Shouldn’t it just be called BadgeService4?
That’s a bit much lol! I just call it a v2, BadgeService4 would sound weird. BadgeService3 already does, It should have been called BadgeService2 from the start to be honest.
Update released, 1.5.0
Changes:
-
:onBadgeAwarded(function(badgeId)
RBXScriptSignal
added. Will fire only when a badge is awarded. -
New customizable settings! Look at these!
["usesBadgeImageForNotifications"] = false;
["isNotificationsDisabled"] = false;
["usesGoldBadgeNotification"] = false;
["defaultBadgeNotificationImage"] = "rbxassetid://6170641771";
["notificationDuration"] = 5;
["autoGarbageCollectProfileTime"] = 5;
["NotificationDescription"] = 'You have been awarded "%s"!';
["NotificationTitle"] = "Badge Awarded!"
-
New function added to BadgeService3,
:SetGlobalSettings(SettingsTable)
, this function will change the settings you ask for! -
New usable “variable” into badges,
Image
which can be set to a image id, not a decal id, and with the settingusesBadgeImageForNotifications
enabled, it will use that as the notification image for that badge. -
New function added
:GetBadgeAmount()
will return you the number of all badges. -
:GetBadges()
will now return the badges, and also the result from:GetBadgeAmount()
Customization highlights:
- Disable notifications!
isNotificationsDisabled
- Add your own notification system if you want! using
:onBadgeAwarded()
- Use the default, gold color for the badge notification!
usesGoldBadgeNotification
- Change the default notification image to whatever you want!
defaultBadgeNotificationImage
- Use specific badge images!
usesBadgeImageForNotifications
- Change the notification’s text, and description!
NotificationDescription
andNotificationTitle
- more…
If you use BadgeService3, please follow the update topic.
That’s where updates will be kept now.
Here’s an tutorial for anyone using DataStore2. I will also be making a dedicated tutorial on how to use it with Profile Service. There are some extra tips inside this video as well.
Not gonna switch from old version because profile service/DS2 is too confusing to me. Old badgeService3 has force save which I can use for my autosave script and it is more friendly to me.
Idk, if this would work but would it be possible to use them across places, if you got a badge in one place? Could you script it to give you a tool in another?
Here’s an example of how this module can be used with the Nevermore Engine:
local Nevermore = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local PlayerDataStoreManager = Nevermore("PlayerDataStoreManager")
local badgeService3 = Nevermore(game.ReplicatedStorage.BadgeService3)
local dataStoreManager = PlayerDataStoreManager.new(DataStoreService:GetDataStore("PlayerData"), function(player) return tostring(player.UserId) end)
function loadBadges(player, store)
return store:Load("Badges", {}):Then(function(data)
return badgeService3:LoadProfile(player, data)
end):Catch(function(...)
warn("Failed to load", ...)
end)
end
function handlePlayerAdded(player)
local dataStore = dataStoreManager:GetDataStore(player)
local badgeStore = dataStore:GetSubStore("BadgeStore")
loadBadges(player, badgeStore):Then(function(profile)
delay(5, function()
if profile.Data then
profile:AwardBadge("Welcome")
end
end)
profile:onUpdate(function()
badgeStore:Store(profile.Data)
end)
end):Catch(function()
player:Kick()
end)
end
Players.PlayerAdded:Connect(handlePlayerAdded)
for _, player in pairs(Players:GetPlayers()) do
handlePlayerAdded(player)
end
You don’t actually need to use any of these two services, you can make your own data saving solution, in this case even integrate it into your old BadgeService3 solution, how ever it is a big more tricky to do so with BadgeService3 v1, it isn’t that hard but it is a bit harder. I can make a v1 handler for you if you like, it shouldn’t be that hard to convert your scripts into.
Also thanks for letting me know you used BadgeService3 v1.
Also I don’t know what you mean by force save?
The old version has :SavePlayerData(plr) function or something like that, not sure but theres a function to save player data manually
Speaking of which I think that you should keep the old version as well (and the old documentation) because its more easier and simple to use. The old one is just better for me because it does the saving and loading automatically. Or make the v2 more simple to use
The biggest problem for me is that it’s too complex to use for “crappy” develolers like me.
You’re not crappy… You’re a beginner, when I made that I was probably about your skill.
I moved away from BadgeService3 v1 because of a bunch of problems and this, eventually does the same except it doesn’t save, to learn it is easier, it’s just harder to set up. Anyways you can message me if you want a handler for it. I can make it act just like BadgeService3.