Choose a Door - Chance System

copy-paste

Hey, members. I’m trying to create a chance system based on a game called ‘Lose speed per second!’ (https://www.roblox.com/games/12292508604)

I’ve tried modifying my system multiple times to get accurate chances but it’s mostly just random (or even the same amount, sometimes also stat). What I’m trying to do is generate random rewards to be assigned to doors: the stat, amount (negative or positive).

After playing the game for a while I’ve got an idea of how the stat amount is randomized but I still can’t figure out what stat is more common to get, and if the chances are different for each map. I think there is also a min/max value for each stat for each map.

For the amounts I think it’s the highest chance to get the middle number, a lower chance to get a lower number, but the lowest chance to get a high number. I’m probably completely wrong about the system, but you can play the game to see for yourself.

I’m completely stuck modifying the chance system for this occasion, so I’m hoping someone could help me out here.

So you tried to create a probability function, but it does not act probable?

local function chance(percentage, decimals)
    local d = 10 ^ decimals

    return math.random(0, 100 * d) / d <= percentage
end

In order to get closer to a middle number, and get less lower and less higher numbers you can use standard deviation:

function Deviate(mean, SD) -- middle number, standard deviation
	local r1,r2 = math.random(),math.random()
	local ZScore = math.sqrt(-2 * math.log(r1)) * math.cos(2 * math.pi * r2)
	return ZScore * SD + mean
end

print(Deviate(5,2)) -- will return a new number basically every time, google standard deviation to understand more

For getting more additions than multiplying, etc. you can use a simple weight system:

function getOperator(info)
	local totalWeight = 0
	for i,v in pairs(info) do
		totalWeight += v
	end

	local choice = Random.new():NextNumber(0, totalWeight)
	local result
	for i,v in pairs(info) do
		choice -= v
		if choice <= 0 then
			result = i
			break
		end
	end
	return result
end

local operators = { -- since we are using a weight system these do not need to add up to 100
	["Add"] = 50,
	["Multiply"] = 30,
	["Percent"] = 30, 
}
print(getOperator(operators))

Combine these two, change the chances, and you have a pretty good good system.
You can use a very simple chance system to determine for a negative or positive:

local positiveChance = 70 -- more chance to be positive so users can have more fun winning

local randomNumber = Random.new():NextInteger(0,100)

local isPositive = randomNumber <= positiveChance

Hope this helps :slightly_smiling_face: