How do i design a role-chance system, similar to Murder Mystery 2?

Hello!

First of all i’d like to say, that only thing in common with my game and Murder Mystery 2 is this murderer chance system - i’m not recreating it.

So basically, i would have 2 ranks, innocents or whatever, and murderer. The end goal for this was to have a table of players, with a displayed chance of them becoming a murder, either by repeating the players name a % amount of times and doing Random:NextInteger or by having a weight for each player and getting weigted random results (still debating)

And i was just gonna do it like - have the chance value in the player for storage and set it’s value to 100/player count for equal chances, but then it tripped me up, because i wanted the chances to rise after a match where player wasn’t a murderer, and drop again, when player WAS the murderer.

Could the solution simply be that, when i drop down the chance of the player to become a murderer, i split that extra chance between the remaining players? But then the challenge is what to do with the new players… it wouldn’t exactly be fair if you come in the server and your chance is as high as the people who have played it for like an hour.

So, in summary, i can’t figure out how to distribute and manage the chance of the players to become a murderer after the match is over or when a new player joins.
Then there’s the fact that player can leave in the middle of assigning the rank or the match, but that’s another can of worms…

3 Likes

Back when Roblox University was a thing, they created an entire YouTube series dedicated to creating Murder Mystery games (the running trend at the time). That game was called The Mad Bloxxer. Search it up on their channel if you can.

It covers everything that you probably want in a murder game, enough to match the MM2 base gameplay flow. There is also an open source copy of the finished game on I believe UristMcSparks’ profile.

Roblox U playlist is here:

2 Likes

I would start by giving each player e.g. 10%, I would treat it more like points not percentage and then if player was a murderer so I would reset his ‘points’ to 10% again and if not then I would increase it. Also new players start from 10%.
And the choosing system would look like that:

local playerChances = {}; -- players and 'points' assigned to them, so for example:
--[[
local playerChances = {{Player = game.Players.Kacper, Chance = 11}};
]]--

function getNextMurderer()
    local sum = 0;
    for _,v in pairs(playerChances) do
        sum = sum + v.Chance;
    end

    local rand = math.random(0, sum);

    sum = 0;
    for _,v in pairs(playerChances) do
        sum = sum + v.Chance;
        if rand <= sum then
            return v.Player;
        end
    end
end

I guess that most players won’t notice that these aren’t real %.

8 Likes

Yeah, i watched those episodes! Nothing that helped my particular case, but i may have missed something. As far as i remember, he just assigned the murderer role by doing math.random on all players and yes that works, but i would want to award players for playing, even if it’s just a little extra chance of getting to be the murderer.

Adding on to @Kacper’s answer, see: https://medium.com/@peterkellyonline/weighted-random-selection-3ff222917eb6 to visualize how this works. You could do something along the lines of the snippet below to implement an “increase” in weights based on various factors (i.e gamepass ownership, play time);

local MarketplaceService = game:GetService("MarketplaceService");
local MultProduct = 12345;

local Participants -- define

local function getNextMurderer()
	local selected = nil;
	
	local TotalWeight = 0;
	local Weights = {};
	
	--Participants: game.Players:GetPlayers or players joining next round
	for index, player in pairs(Participants) do
		-- Give every participant a starter weight of 10 pts
		Weights[index] = 10;
		
		if MarketplaceService:UserOwnsGamePassAsync(player.UserId, MultProduct) then
			--multiplier of 10 for every player that owns the relevant gamepass
			Weights[index] = Weights[index] * 10
		end
	
		TotalWeight = TotalWeight + Weights[index]
	end
	
	--select a random ticket from the pool (random number ranging from 1 to sum of weights)
	local ticket = Random.new():NextInteger(1, TotalWeight);
	
	for index = 1, TotalWeight do
		-- subtract from the sum of weights until we reach 0
		-- the higher the weight the higher the chances of reaching 0 
		ticket = ticket - Weights[index]
		if ticket <= 0 then
			--select the winner
			selected = Participants[index]
			break
		end
	end
	return selected;
end

print(getNextMurderer())
7 Likes

The Roblox U tutorials do include percentage chances. There may not be a specific video for it however, though I do believe those videos cover the creation of the game as much as possible. If you’re interested in taking a look through the source code, that’s available here:

Sorry it took a bit of time to get it to you. Phone data is down.

2 Likes

@ImageLabel @Kacper That’s true… and even if i use points, i could still turn them into percentages for the UI…
i would have min and max points, and then use basic proportions to get the percentage that i would display
Thank you! I’ll try it out.

1 Like

You wouldn’t even need a min-max;

local baseChance = 10; --starterweight
local MultChance = (baseChance * (baseChance*(baseChance*0.1))); --10% increase
1 Like