Chance / Percentage Script

The script looks good but you should move the post #help-and-feedback:code-review.

1 Like

What part are you confused about?

“Make sure you sort each chance by how OP it is”

As an example, for a game like Speed-Run 4, the SpeedBoost would be very “OP” as the game is based off of “Speed”, so it should be the rarest. With other games like obbies, the JumpBoost would be very “OP” as it helps your character navigate and complete the obby easier, so it should be the rarest.

so what should i do? can u show me a code example?

As long as your Chances list is ordered from Highest to Lowest this should work just as well.

local Chances = {
	SpeedBoost = 60,
	JumpBoost = 32,
	Regen = 7,
	LowGravity = 1
}

script.Parent.MouseButton1Up:Connect(function()

	local chance = math.random(0,100)

	for ability,percent in pairs(Chances) do
		if (chance >= percent) then
			print("Ability:",ability,"rolled:",chance)
			break
		end
	end

end)

Speed Run

local Chances = {
SpeedBoost = 10
JumpBoost = 20
Regen = 40
LowGravity = 30

Obbies

local Chances = {
SpeedBoost = 30
JumpBoost = 10
Regen = 55
LowGravity = 5

also how can i make it so one of the chances are like 0.1 or 0.001

If a random number between 0 and 100 isn’t granular enough you could do between a great figure, and then divide to a 100 max figure.

e.g.

local rand100 = math.random(0,100) -- 0 to 100
local rand1000 = math.random(0,1000)/10  --0, 0.1 to 100.0
local rand10000 = math.random(0,10000)/100 -- 0, 0.01 to 100.00

Also a note on my previous code - the for loop I used doesn’t work as I expected and requires a table sort to ensure the list is ordered as you like, you can learn about table.sort here:
table (roblox.com)

By the way - the logic I implemented was set up to mimic and reduce your code, however, if you want the ability to not get any power up until you hit a certain chance - you could just do this;


local Chances = {
	"SpeedBoost",
	"JumpBoost",
	"Regen",
	"LowGravity"
}

local MissChance = 5 -- reduce this to 0 and it will always hit an ability - really this is probably a  better solution to my original suggestion.. ^_^"

local chance = math.random(1,#Chances + MissChance)

local ability = Chances[chance]
print("Miss Chance Ability:",ability,"Chance:",chance)
2 Likes

so if i have things that are 0.1 or 0.001 or etc

instead of doing math.random(1,100) i do math.random(1/10000) / 100? or math.random(1/1000) / 100 or math.random(1/100) / 100

also when it picks a num like 53.1 or 53.24 and will my script with the signs < > = work?

will it compare?

<> is SQL for Not Equal to, right?

The equivalent in Lua is ~=

This wouldn’t work as expected, and neither of the solutions proposed in this post would.

Since I suppose that you want it to always end up choosing one, I would do something like @WingItMan did, but more like this:

local Chances = {
	SpeedBoost = 60,
	JumpBoost = 32,
	Regen = 7,
	LowGravity = 1
}

script.Parent.MouseButton1Up:Connect(function()

    local chance = math.random(0,100)
    local accum = 0
    
    for ability, percent in pairs(Chances) do
        if chance <= percent + accum then
            print(ability)
            break
        end
        accum += percent
    end

end)

Instead of checking if chance >= percent, do the opposite, and sum the chances.

You can also do it with if statements this way:

local choosenchance = math.random(1, 100)
if choosenchance <= Chances.SpeedBoost then
    print("SpeedBoost")
elseif choosenchance <= Chances.SpeedBoost + Chances.JumpBoost then
    print("JumpBoost")
elseif choosenchance <= Chances.SpeedBoost + Chances.JumpBoost + Chances.Regen then
    print("Regen")
else
    print("LowGravity")
end
1 Like

so ur saying my script wont work?

Your script would work, but it won’t be accurate.

The method proposed by @WingItMan won’t work, or it would be very innacurate.

1 Like

wdym by not accurate? also which one will work

You should seed math.random() before using to allow more randomness in the generation of the numbers, i.e. math.randomseed(os.clock()). If you are using it for player chance percentage then a better method is to use:

local rand = Random.new(os.clock());
local new_number = Random:NextNumber();

Since this has a single pool to draw numbers from and no other scripts can pull the next value from it (unless you allow it to). Whereas math.random() will be shared by any player that pulls from it so could skew players actual chances. I use the pseudo-random (between 0 and 1) number returned from Random.NextNumber() as a decimal percentage and multiply this by the required range. We have to use math.round() + 0.5 to remove the 0 from the range since 0-100 contains an extra interval between 0 and 1 so there are actually 101 intervals.

The code below is a method for getting a fair(ish) chance of getting 1-in-million chance. Increase the luck_bonus to change the chances to (1*luck_bonus) in-million, so to get 8 in a million set it to 8. By the law of averages most players should win the odds but it doesn’t always happen. iteration represents each player and i the number of times they had to try. You can adapt this code to include a table of ranges for different odds.

local iteration = 0;
local chance = 1000000;
local luck_bonus = 1;
local rand = Random.new(os.clock());

while true do
	
	iteration += 1;
	local success = false;
	for i=1, chance do
		local new_number = math.round((rand:NextNumber() * chance) + 0.5);
		if new_number <= (1 * luck_bonus) then
			warn("Player",iteration,"success after",i,"attempts with",new_number);
			success = true;
			break;
		end
	end
	
	if success == false then
		print("Player",iteration,"failed",chance,"attempts");
	end
	
	wait(1);
	
end
1 Like

While I acknowledge that my first solution may provide unexpected results due to tables being read as un-ordered, I’m not sure what you mean by saying my script won’t work or would be inaccurate?

Can you clarrify your reasoning for the benefit of this topic and myself in case I’ve missed something?

what about this?

It’s a good example with the table provided. It does choose things with a good spread of randomness (again Random:NextInteger() would provide a single pool which wont skew the players chances). I wouldn’t recommend using this method for any percentages that go beyond values between 1 and 100 or 1 and 1000. Any chance table that is 1/10000 or 1/1000000 will generate a huge table during initialisation.