Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Randomly Select Player?

I have been trying to think of a way to randomly select a player, which I can do, but I can't figure out a way to give people a better chance of being picked if they have a specific gamepass. I'm not quite sure how I would be able to do this, does anybody know a way how to do this? Any help would be appreciated. I have provided the code I use to randomly select one player, all I need to do is find a way to increase the odds for somebody that has the gamepass without making them selected too often or not as often.

players = {}

function start()
	wait(1)
	players = game.Players:GetPlayers()
	local selected = players[math.random(1, #players)].Name
	print(selected)
end

3 answers

✓ Accepted answer

This problem is to find a random choice, given different weights to each choice.

Think of the weight as the number of raffle tickets each player has. Let's say normal users have 1, but players with a game pass have 10 (though this is easy to configure).

This model works like this:

  • Only one player can win
  • Everyone, even with poor odds, has a small chance to win
  • If many people have low odds, together they can have higher odds than someone else (e.g., doesn't guarantee something like 50% of raffles go to owners of the gamepass if the non-owners significantly outnumber)

To figure out who wins, we pick a random number from the total number of raffle tickets, rather than the total number of players.

To figure out which player has that ticket, we just assign the tickets sequentially to each player. That is, the first one (or ten) is the first player, the next one (or ten) is the next player's, and so on.


An implementation looks like this:

local weights = {};
local totalWeight = 0;
-- 1) Count number of raffle tickets
-- (can actually be non-integer, too)
for i,v in pairs(players) do
	weights[i] = 1;
	if if game:GetService("GamePassService"):PlayerHasPass(v,ID) then
		weights[i] = 10;
		-- 10 times more likely than non-owners to win
	end
	-- Weight can include anything else that would influence
	-- odds, including other upgrades.
	totalWeight = totalWeight + weights[i];
end

-- 2) Pick winning raffle ticket (can also be non-integer)
local winner = math.random() * totalWeight;


-- 3) Figure out which person owns that ticket
for i = 1, #weights do
	winner = winner - weights[i];
	if winner <= 0 then
		choice = players[i];
		break;
	end
end

-- choice is a player from `players` who won the raffle
-- according to the weight at the corresponding entry in
-- `weights`

I would suggest using a for loop, checking through all the players for a gamepass. If they have it, they can have a (Percent) greater chance to be selected.

for i,v in pairs(game.Players:GetPlayers()) do
	if game:GetService("GamePassService"):PlayerHasPass(v,ID) then
		percentage = Instance.new("NumberValue",v)
		percentage.Value = #game.Players:GetPlayers() / 100 + Percent -- Based on how many players are in-game and how much you want the percent to increase, you can pull off a fraction of other players' perentages in upcoming code to make it equal to 100%.
	end
end

To add on to what red said, you could also create a table and if the player has the pass, insert their name twice.

local players = {}

for i,v in pairs(game.Players:GetPlayers()) do
	if game:GetService("GamePassService"):PlayerHasPass(v,ID) then
		players:insert(v.Name)
	end
	players:insert(v.Name)
end

This discussion is preserved as it was. New answers, comments, and votes are closed.