[SOLVED] SurfaceGui that Shows Random Sentences, Certain Sentence Awards Badge

It now works with showing the sentences, but when the sentence “Badge For You” it shows ups, it doesn’t award the badge.

Thanks, changed it to that too

try setting it to 0. that may help.

I don’t usually award badges, but I’m rather certain you can’t do so in a local script. You’ll have to use remote events on the server. But you would also want to move the random string there as well so they can’t make it up.

Lua lists start at 1. 0 would cause an out of bounds error.

View this article.

math.random(a, b)

returns a value between a and b-1.

local GuiButton = script.Parent 
local b = game:GetService('BadgeService')

local sentences = {
	"Badger Badger Mushroom",
	"Ahah! You'll be here forever.",
	"No badge here.",
	"Unlucky, no badge for you.",
	"Badge For You",
	"How long have you been here?",
	"This is what true pain is."
}

GuiButton.MouseButton1Down:Connect(function()
	local text = sentences[math.random(1, #sentences)])
    GuiButton.Text = text

		if text == "Badge For You" then
		    local id = 2125641650
			    print("Awarding BadgeID: " .. id .. " to UserID: " .. game.Players.LocalPlayer.userId)
			    local b = game:GetService("BadgeService")
			b:AwardBadge(game.Players.LocalPlayer.userId, id)
		end	
	end)
1 Like

This is most likely the reason why. Roblox would be a very insecure site if you could award badges on the client. Exploiters and hacked clients could easily hack your game.

Do everything securely on the server.

I know how math.random works. It is inclusive which means if you say math.random(0,#list) it could return 0.

If you try list[0] it would error since the first index is 1. So you need to start with 1.

Other languages start at 0, but lua is weird.

Yes, lua is weird, but when using math.random() lua will NEVER return the first argument.

It only returns a number BETWEEN the first argument, and on the second. so if you said:

print(math.random(0, 1))

It would always return 1.

Creating a RemoteEvent is even more dangerous. The hacker could connect the event to a script of their own, and harm the game more. Awarding a badge on the client is the least of our worries, who cares if someone hacks a badge? It’s not worth monetary value.

All that aside, that was a problem on their end. It does need to be called on a server-script, so there will need to be some way of getting it to that.

What I mean is that it doesn’t matter WHAT you’re trying to do on the client, make sure that it’s inaccessible from any exploiters.

You don’t want your game to get hacked in the first place. Do you?

The official documentation disagrees. math the square brackets mean it includes that number. I can’t test right now but I’ve never encountered that in practice.

You will need to change this to a server script, so just a little change. If you need help, let me know!

https://developer.roblox.com/en-us/api-reference/function/BadgeService/AwardBadge

The badge still doesn’t award, thanks for helping though

I need a lot of help… as I said I barely just started scripting lol. How would I get it to work?

The way this should be done is there should be a button.

That button should fire a remote event to let the server know it’s been pressed. The server will then pick the string award the badge and send the string back through the remote event to let the client know what the button should now say.

Sure they could fire the remote event whenever they want, but the server the one who verifies its validity. If the button can’t always be pressed the server should have sanity checks that ensure the button could have been pressed before it does anything.

As long as you always work under the assumption that you will from time to time be sent false data from cheaters you can use remote events and still have a secure game. The problems arise when you just make a remote event directly do something without any verification.

Server script:

local Players = game:GetService('Players')
local b = game:GetService('BadgeService')

local sentences = {
	"Badger Badger Mushroom",
	"Ahah! You'll be here forever.",
	"No badge here.",
	"Unlucky, no badge for you.",
	"Badge For You",
	"How long have you been here?",
	"This is what true pain is."
}

Players.PlayerAdded:Connect(function(Player)
    local PlayerGui = Player:WaitForChild('PlayerGui')
    local Button = PlayerGui.ScreenGui.Button -- Change ScreenGui.Button to all the UI info.
    local TextBox = Button.Parent.TextBox -- Again, change all that to the correct UI info.

    Button.MouseButton1Down:Connect(function()
        local text = sentences[math.random(1, #sentences)]
        TextBox.Text = text

        if text == "Badge For You" then
            b:AwardBadge(Player.UserId, 2125641650)
        end
    end)
end)

That should work, but it’s untested! :smile:

1 Like

It didn’t work, but I think I did something wrong! Let me keep trying and I’ll tell you if it works or not.

Firstly, you should create a remote event with name “AwardBadge” in the ReplicatedStorage.

LocalScript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AwardBadge = ReplicatedStorage:WaitForChild("AwardBadge")

local GuiButton = script.Parent 

local sentences = {
	"Badger Badger Mushroom",
	"Ahah! You'll be here forever.",
	"No badge here.",
	"Unlucky, no badge for you.",
	"Badge For You",
	"How long have you been here?",
	"This is what true pain is.",
}

GuiButton.MouseButton1Click:Connect(function()
   local sentence = sentences[math.random(#sentences)]
   GuiButton.Text = sentence

   if sentence == "Badge For You" then
	   AwardBadge:FireServer()
   end	
end)

Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BadgeService = game:GetService("BadgeService")

local AwardBadge = ReplicatedStorage.AwardBadge
local BadgeId = 2125641650

Awardbadge.OnServerEvent:Connect(function(player)
   local success, badgeInfo = pcall(function()
	  return BadgeService:GetBadgeInfoAsync(BadgeId)
   end)

   if success and badgeInfo.IsEnabled then
      local success, result = pcall(function()
	     return BadgeService:AwardBadge(player.UserId, BadgeId)
	  end)
   end
end)

With pcall you can handle errors like

if not success then
   --Handle error
end

But thats not necessary

2 Likes