How to make role percentage?

hi, in my game one person among the player is randomly chosen to be the killer, like mm2 or piggy, to be clear. the only problem is that it often choses the same person to be the killer, which is bad, and i want people to be chosen to be the killer based on their percentage

  1. What do you want to achieve? i want to create a killer role percentage, kinda like murder mystery, but only the killer role, possibly with a gui that tells a player the value of their percentage, and when someone is chosen to be the killer, their percentage resets (i would start with 10% or something like that)

  2. What is the issue? i donā€™t know how to do it

  3. What solutions have you tried so far? i looked around in the dev forum but all the solutions i found seem not to work for me

this is my script for now, itā€™s a module script inside a server script

function module.ChooseKiller(players)

	local RandomObj = Random.new()

	local chosenKiller = players[RandomObj:NextInteger(1, #players)]
	
	local add = game.ReplicatedStorage.Add
	local fire = add.Fire:Clone()
	local sparkles = add.Sparkles:Clone()
	
	fire.Parent = chosenKiller.Character.Head
	sparkles.Parent = chosenKiller.Character.Head
	
	wait(3)
	
	return chosenKiller
end

i hope somebody can help :))

Right now you have a system in place where one player gets picked to be the murderer, which is how it should work. You canā€™t really pick a specific percentage since the player amount varies. For example: if thereā€™s 2 people, you can only pick between those two people and the chance will always be 50%, but when thereā€™s say 17 people, the probability will be 6%. (100/17 ā‰ˆ 6)

So you already have the correct system in place. What I can tell you though is how to display the probability of a player getting picked:

local probability = math.round(100/#players)

Wait, I think I get what you mean now.
So you want to make a system where somebody who was just picked has a lower chance to be picked, and someone who hasnā€™t been chosen for a long time will have a higher chance. Did I understand correctly?

yes, sorry for not being clear, what should i do?

Put all the players into a table, then remove the recently chosen player from the list, and pick your random number from the ones left.

may you write the script please? iā€™ve never been good at scripting tables

You canā€™t just tell people to write a script.

image

1 Like

Sorry for the long wait, I made sure this worked and had a proper explanation.
If you have any questions concerning my code or my explanation, please donā€™t hesitate to ask me. I will gladly explain.

Feel free to suggest another system if you think itā€™s better or more efficient than this. Also donā€™t forget to point out if I made any mistakes in my code or explanation!

So, how would we make such a system?
First, we make a table with all the players and their points. It would look something like this:

local chances = {
["Bob"] = 0, -- Bob was the killer last time so his points are 0; this means he won't be picked this round
["Joe"] = 1,
["Matt"] = 3,
["Mary"] = 4
}

These points represent the probability (chance) that the player gets picked.

For every point that they have, weā€™ll add their name to another list once, that means if you have 3 points, your name will be in the list 3 times. So now the list would be something like:

local list = {
[1] = "Joe",
[2] = "Matt",
[3] = "Matt",
[4] = "Matt",
[5] = "Mary",
[6] = "Mary",
[7] = "Mary",
[8] = "Mary"
}

Does this remind you of something? Because it does remind me! This is the same system as, when you put papers with peopleā€™s names in a bowl and then grab one random paper, you get a random name. This means the more papers with a personā€™s name, the higher the chance that they will get picked.

Finally, we generate a random number, in this case from 1 to 8. Letā€™s say the random number is 4: index 4 of the list above has the corresponding name ā€œMattā€. That means Matt has been chosen as the killer.

I strongly suggest you to first take my explanation and try to make the system on your own, and then compare it with my version, because Iā€™m actually not supposed to give you a whole script on here. You would learn much more out of actually trying it out yourself!

Thatā€™s enough ado, letā€™s finally do the same but with code!

Here's the code WITH explanation
local chances = {} -- list of players and their chance to become the killer

local function chooseKiller(plrs)

	-- first we're removing the players that have left from the chances list
	-- we're doing this so the chances list won't have useless values in it and won't become laggy and cluttered
	for plr, points in pairs(chances) do
		if table.find(plrs, plr) == nil then -- if we can't find the player in the players list
			table.remove(chances, table.find(chances, plr)) -- remove the player from the chances list (we're doing table.find because we need the index to remove it from the table)
		end
	end

	-- add players that aren't in the chances list yet
	for _, plr in pairs(plrs) do
		if table.find(chances, plr.Name) == nil then -- if the player isn't in the list already
			chances[plr.Name] = 1 -- add the player to the list and give them 1 point
		end
	end
	
	-- now we're creating a table containing a list of players
	-- for every point that they have, we will add their name to the list once
	-- this means that the more points they have, the more times their name is in the list and the higher the likelihood for them to be picked
	local names = {}
	for plr, points in pairs(chances) do
		if points >= 1 then -- check if chance isn't 0
			for i = 1, chances[plr], 1 do -- repeat as many times as the player has points
				table.insert(names, plr) -- add player's name to the names list
			end
		end
	end
	print(names)

	local chosenName = names[math.random(1, table.getn(names))] -- pick a player from the names list
	-- it's currently a name so we need to find the player corresponding to that name
	local chosenKiller = game:GetService("Players"):FindFirstChild(chosenName)

	-- here we give a point to each player that hasn't been picked this round so they have a higher chance to be picked next round
	for plr, points in pairs(chances) do
		chances[plr] += 1
	end

	-- now we will set the chance of the killer to 0 so they can't be picked next round
	chances[chosenName] = 0

	return chosenKiller
end

print(chooseKiller(game:GetService("Players"):GetPlayers())) -- finally we can run the function. this will print the killer
Here's the code WITHOUT the explanation
local chances = {}

local function chooseKiller(plrs)

	for plr, points in pairs(chances) do
		if table.find(plrs, plr) == nil then
			table.remove(chances, table.find(chances, plr))
		end
	end

	for _, plr in pairs(plrs) do
		if table.find(chances, plr.Name) == nil then
			chances[plr.Name] = 1
		end
	end
	local names = {}
	for plr, points in pairs(chances) do
		if points >= 1 then
			for i = 1, chances[plr], 1 do
				table.insert(names, plr)
			end
		end
	end

	local chosenName = names[math.random(1, table.getn(names))]
	local chosenKiller = game:GetService("Players"):FindFirstChild(chosenName)

	for plr, points in pairs(chances) do
		chances[plr] += 1
	end

	chances[chosenName] = 0

	return chosenKiller
end

print(chooseKiller(game:GetService("Players"):GetPlayers()))

I strongly suggest you read the code with the explanation first so you actually understand whatā€™s going on and learn from it, and then take/modify the code without the explanation.

Here you go! Iā€™m actually not supposed to write whole scripts for you on here, but I felt generous, so here you go. You can figure the probability percentage gui out on your own (:

Have fun coding!

3 Likes

@Lushisnothere Make sure to mark the solution when youā€™re done.

thank you, it works and iā€™m extremely grateful you helped! only 1 question: what if I wanted each player to already have his percentage at the beginning of each game, and the killer to be chosen only at a certain point in the game and therefore in the script? youā€™ve already been really helpful and kind, so you donā€™t have to answer. only do if you want :))

Edit: Also, Iā€™m sorry if I couldnā€™t reply right away

does it work in a module script?

why would you need a modulescript?