"Fair" random number generator

General discussion about LÖVE, Lua, game development, puns, and unicorns.
JaseMourne
Prole
Posts: 13
Joined: Sat Aug 11, 2012 7:37 pm

"Fair" random number generator

Post by JaseMourne » Sat Aug 31, 2013 3:34 pm

In a turn based strategy game where when two opposing units clash, one scores a hit and the other does not, and this is determined by a single attribute (Combat) and a bit of randomness, that randomness has to be as "fair" as possible. An idea crossed my mind when thinking about how to balance the random factor - and this is applicable in any almost game genre, I guess.

When player 1's (P1) unit attacks player 2's (P2) unit, there are two separate dice rolls to add a bit of randomness to the combat, which is otherwise primarily based on their Combat attribute (well, it's not really a dice roll, it's rather a random number from 0 to 1, but let's just use the word for simplicity). Now when P1's roll is greater than P2's roll, we will make P1's next roll weaker, and P2's roll stronger. This repeats forever, so if P1's rolls are still somehow greater three times in a row, the 4th roll will be much weaker, and so on. If then P1's rolls are weaker 3 times in a row, the roll modifiers of both players will even out. Of course, these roll modifiers are set to 1 by default for all players. Based on how strong the roll bonus/penalty is, we can control how much lucky/unlucky a player can get. Good/bad streaks of luck are still possible, but extremely rare.

This roll modifier is always bound to a single player, and each player has their own. So, from a single player's perspective, they should only very very rarely experience a big good/bad luck streak. And the common problem in TBS games where luck plays a factor is that players perceive bad streaks as a very negative thing, and these bad streaks tend to happen. This system should solve it.

What do you think, guys?

User avatar
raidho36
Party member
Posts: 1944
Joined: Mon Jun 17, 2013 12:00 pm

Re: "Fair" random number generator

Post by raidho36 » Sat Aug 31, 2013 3:42 pm

No. There should be no such bias in random function. Even if sounds sweet in theory, in practice it will always backfire by effectively making this random utterly useless. Besides, it's a dice, they're supposed to produce random results, without any bit of fairness to it.

User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: "Fair" random number generator

Post by vrld » Sat Aug 31, 2013 4:13 pm

I disagree with raidho: Since humans in general (me included) are not very good at perceiving and understanding random events, an unbiased random draw might be perceived as unfair, for example when the opponent lands 3 critical strikes in a row, while your unit misses every turn. Many (board) games include rules to balance for this. In Monopoly, for example, you go to jail for rolling doubles three times in a row.

Your method seems to be a good compromise between fairness and scalability, but you should play test it to see if it really works. You could also tweak it to just consider the last instead of all rounds.

Another possibility might be what I like to call a random bag: For each unit, you fill a bag (table) with all possible outcomes, maybe with a bias. On each turn, you pick one of the outcomes at random and remove it from the bag. Once the bag is empty, you refill it and repeat the process. You can also refill the bag once it has less than x items in it, to keep things interesting.

Example: The possible outcomes are 'miss', 'hit', 'critical hit'. You have one veteran unit pitted against a novice. The veteran unit's bag is v = {'miss', 'miss', 'hit', 'hit', 'critical hit'} and the novice's bag is n = {'miss', 'miss', 'hit', 'critical hit'}. You refill the bag when it contains less than two items.

Round one: veteran draws 'miss', novice draws 'hit'. the bags now contain: v = {'miss', 'hit', 'hit', 'critical hit'}, n = {'miss', 'miss', 'critical hit'}
Round two: veteran draws 'hit', novice draws 'miss'. the bags now contain: v = {'miss', 'hit', 'critical hit'}, n = {'miss', 'critical hit'}
Round three: veteran draws 'critical hit', novice draws 'miss', and the bag is refilled. the bags now contain: v = {'miss', 'hit'}, n = {'miss', 'miss', 'hit', 'critical hit'}.
Round four: veteran draws 'hit', novice draws 'critical hit'. Novice is dead, so no bags are refilled.
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine

User avatar
substitute541
Party member
Posts: 484
Joined: Fri Aug 24, 2012 9:04 am
Location: Southern Leyte, Visayas, Philippines
Contact:

Re: "Fair" random number generator

Post by substitute541 » Mon Sep 02, 2013 11:29 am

vrld wrote:I

Another possibility might be what I like to call a random bag: For each unit, you fill a bag (table) with all possible outcomes, maybe with a bias. On each turn, you pick one of the outcomes at random and remove it from the bag. Once the bag is empty, you refill it and repeat the process. You can also refill the bag once it has less than x items in it, to keep things interesting.
Reminds me of the "selecting things at random with* replacement from a sample of size n" thingy that I learned from a certain online course.

Edit: it is without, as micha said down below.
Last edited by substitute541 on Mon Sep 02, 2013 12:18 pm, edited 1 time in total.
Currently designing themes for WordPress.

Sometimes lurks around the forum.

User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: "Fair" random number generator

Post by micha » Mon Sep 02, 2013 11:47 am

It is without replacement. This is the whole point. By not replacing objects, the number of occurances is distributed more evenly (and also less randomly).

JaseMourne
Prole
Posts: 13
Joined: Sat Aug 11, 2012 7:37 pm

Re: "Fair" random number generator

Post by JaseMourne » Tue Sep 03, 2013 11:49 am

raidho36 wrote:No. There should be no such bias in random function. Even if sounds sweet in theory, in practice it will always backfire by effectively making this random utterly useless. Besides, it's a dice, they're supposed to produce random results, without any bit of fairness to it.
To me, that is a question of design, as to how much random combat should get. In my design, I only want a bit of randomness added, so when a unit with a strength of 2 fights a unit with a strength of 1, the latter should never win 0:7, or the like. With an unbiased random function, this does happen (playtested, of course).
vrld wrote:I disagree with raidho: Since humans in general (me included) are not very good at perceiving and understanding random events, an unbiased random draw might be perceived as unfair, for example when the opponent lands 3 critical strikes in a row, while your unit misses every turn. Many (board) games include rules to balance for this. In Monopoly, for example, you go to jail for rolling doubles three times in a row.
Exactly.
Your method seems to be a good compromise between fairness and scalability, but you should play test it to see if it really works. You could also tweak it to just consider the last instead of all rounds.
Yes, it does work, I tested it. It gives results that are more or less expected, with a few peaks here and there. The reason I've posted is because I wanted to know if there are better and/or already known methods of achieving this.
Another possibility might be what I like to call a random bag: For each unit, you fill a bag (table) with all possible outcomes, maybe with a bias. On each turn, you pick one of the outcomes at random and remove it from the bag. Once the bag is empty, you refill it and repeat the process. You can also refill the bag once it has less than x items in it, to keep things interesting.

Example: The possible outcomes are 'miss', 'hit', 'critical hit'. You have one veteran unit pitted against a novice. The veteran unit's bag is v = {'miss', 'miss', 'hit', 'hit', 'critical hit'} and the novice's bag is n = {'miss', 'miss', 'hit', 'critical hit'}. You refill the bag when it contains less than two items.

Round one: veteran draws 'miss', novice draws 'hit'. the bags now contain: v = {'miss', 'hit', 'hit', 'critical hit'}, n = {'miss', 'miss', 'critical hit'}
Round two: veteran draws 'hit', novice draws 'miss'. the bags now contain: v = {'miss', 'hit', 'critical hit'}, n = {'miss', 'critical hit'}
Round three: veteran draws 'critical hit', novice draws 'miss', and the bag is refilled. the bags now contain: v = {'miss', 'hit'}, n = {'miss', 'miss', 'hit', 'critical hit'}.
Round four: veteran draws 'hit', novice draws 'critical hit'. Novice is dead, so no bags are refilled.
Now this is very interesting. Catches my curiosity. Let's see if it's applicable in my design. Gonna churn some numbers now... Thank you. :)

User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: "Fair" random number generator

Post by vrld » Tue Sep 03, 2013 12:52 pm

You might also be interested in this article: Probability and Games: Damage Rolls. The article provides a nice (and interactive!) introduction to designing random distributions in games.
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine

JaseMourne
Prole
Posts: 13
Joined: Sat Aug 11, 2012 7:37 pm

Re: "Fair" random number generator

Post by JaseMourne » Tue Sep 03, 2013 1:02 pm

Okay, so the "random bag" implementation does not work too well for me. I probably could make it work with some serious effort, though. Nonetheless, I'm glad I've learned about this method. Might come handy in some other situations.
vrld wrote:You might also be interested in this article: Probability and Games: Damage Rolls. The article provides a nice (and interactive!) introduction to designing random distributions in games.
I'm right on it, sir. Thank you. :)

User avatar
timmeh42
Citizen
Posts: 90
Joined: Wed Mar 07, 2012 7:32 pm
Location: Cape Town, South Africa

Re: "Fair" random number generator

Post by timmeh42 » Wed Sep 04, 2013 3:26 pm

It might be interesting to read how Dota 2 implements Pseudo-Random Distribution - as a game with a massive playerbase, it has to strive to make random events as "fair" as possible or suffer the consequences of a large amount of moaning and whining (and less fun-having).

JaseMourne
Prole
Posts: 13
Joined: Sat Aug 11, 2012 7:37 pm

Re: "Fair" random number generator

Post by JaseMourne » Wed Sep 11, 2013 1:17 am

timmeh42 wrote:It might be interesting to read how Dota 2 implements Pseudo-Random Distribution - as a game with a massive playerbase, it has to strive to make random events as "fair" as possible or suffer the consequences of a large amount of moaning and whining (and less fun-having).
Thank you for another good link. I'm well aware of that (it's been used in Warcraft 3, too), but that only works for singular effects that either do or do not trigger - these effects are not evaluated against anything else but the chance. So, each effect remembers its own chance of triggering, which goes up every time it does not trigger, and goes down every time it does trigger. As an exercise, some time ago, I've devised a method based on this principle, but much simpler, with very solid results.

Problem is, in my case, you are evaluating two such effects standing against each other. And because unit A and unit B may, but also may not ever clash again after the first clash, you cannot store the effect's chance as a standalone thing. You need to try to assure the "overall fairness", which can only be, in my opinion, be done on a player-to-player basis. That's why I'm shooting for the approach described in OP.

Post Reply

Who is online

Users browsing this forum: pixelfixation and 6 guests