Gamasutra: The Art & Business of Making Gamesspacer
Chance, Probability, Luck, Percentage calculation for games.
Printer-Friendly VersionPrinter-Friendly Version
View All     RSS
April 24, 2014
arrowPress Releases
April 24, 2014
PR Newswire
View All
View All     Submit Event





If you enjoy reading this site, you might also want to check out these UBM TechWeb sites:


 
Chance, Probability, Luck, Percentage calculation for games.
by Roger Haagensen on 11/23/10 02:23:00 pm   Featured Blogs

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

When making games (and sometimes other software) where you need a chance of something either happening or not, it can get somewhat complicated to make it all work correctly.

Roger Hågensen considers himself an Absurdist and a Mentat, hence believing in Absurdism and Logic. Has done volunteer support in Anarchy Online for Funcom. Voicework for Caravel Games. Been a Internet Radio DJ with GridStream. Currently works as a Freelancer, Windows applications programmer, web site development, making music, writing, and just about anything computer related really. Runs the website EmSai where he writes a Journal and publishes his music, ideas, concepts, source code and various other projects. Has currently released 3 music albums.

When do you need chance/probability in a game?

You may want a pure lucky chance, like say the player either hitting or not hitting something. A pure random pick of 0 or 1 (random number range pick of 0-1) will give around 50% chance and would work well in that case, and easy to implement.

But what about 90% chance of hitting, or 5% chance of hitting?
What if your game has modifiers like a bonus, or skill increase or items that increase the player chance of hitting, or maybe sometimes they may be hurt, thus reducing their chance of hitting, or a enemy cast negative buffs on the player.

Trying to create a random number range to handle all this is impossible (or is it?), and many end up making huge mistakes. Wrong calculations can lead to frustrated players when they "know" they should have hit based on the character attributes and skill,
yet they seem not to hit based on the percentage the game tells them they should have.

For example a hit chance of 99% should hit 99 out of 100 shots, but how many games can you remember where this has been true? And how many games have you noticed where 100% really doesn't match 100%?

The code!

The following code is in PureBasic a brilliant procedural basic based syntax, cheap license, and you can code for Windows, Mac and Linux. performance is similar to C and you can make tight standalone executables. For those with no familiarity with PureBasic I'm hoping that the syntax easy enough and suitable as pseudocode that you can port to your own preferred programming language.

The Chance_Luck() routine takes a percentage as chance/probability value.

Set it to 0 or lower and you will always get False back, set it to 100 or higher and you will always get True back.

Set it to 1-99 and you will get true returned based on the probability, so setting the value to 99 and then calling Chance_Luck() 100 times you should on average get true 99 times and false 1 time.

This is perfect for lucky chance checks where you might want to let the player either hit or miss, or get hit or missed but with a specific probability.

The Chance_Amount() routine takes a amount value and a percentage of chance/probability value.

Set the percentage to 0 or lower and you will always get amount of 0 back, set it to 100 or higher and you will always get the full amount back.

Set the percentage to 1-99 and you will get the amount back modified by the percentage probability, so setting the percentage to 99 and amount to 1000 then calling Chance_Amount() will return 901 to 1000 as the amount.

This is perfect for damage dealt or damage received checks where you might want the player to always deal at least 90%-100% damage for example.

;© Roger "Rescator" Hågensen, EmSai 2010. http://www.EmSai.net/
;Creative Commons Attribution License,
;http://creativecommons.org/licenses/by/3.0/

;Chance of success or failure given the percentage of probability.
;If 0% chance or lower (negative modifer overload, penality), failure always.
;If 100% chance or higher (positive modifer overload, bonus), success always.
;Otherwise 1% to 99% chance (+/- modifiers etc.).
Procedure.i Chance_Luck(percentage.i)
    Protected result.i,chance.i=#False,range.i
    If percentage>99
        result=#True
    ElseIf percentage>0 ;1% to 99% chance
        range=100-percentage
        chance=Random(99)+1 ;Kinda clunky but needed since the number range starts at 0 rather than 1.
        If    range
            result=#True ;lucky chance
        EndIf
    EndIf
    ProcedureReturn result
EndProcedure

;Chance of full amount given the percentage of probability.
;If 0% chance or lower (negative modifer overload, penality), amount is 0 always.
;If 100% chance or higher (positive modifer overload, bonus), amount is full always.
;Otherwise amount is 1% to 99% (+/- modifiers etc.).
Procedure.i Chance_Amount(amount.i,percentage.i)
    Protected chance.f,result.i=#False,range.i
    If percentage>99
        result=amount
    ElseIf percentage>0
        range=100-percentage ;Get range based on percentage
        chance=Random(range-1)+1 ;Kinda clunky but needed since the number range starts at 0 rather than 1.
        chance=(chance+percentage)/100.0 ;Create the modifier based on percentage
        result=amount*chance ;Apply modifer
    EndIf
    ProcedureReturn result
EndProcedure

Define.i i,n,s,percentage

;Lucky chance test
n=100000
percentage=50
DisableDebugger
For i=1 To n
    s+Chance_Luck(percentage)
Next
EnableDebugger
Debug StrD(((s/n)*100.0))+"% lucky chance average with "+Str(percentage)+"% probability."

;Amount probability test
n=1000
percentage=90
Debug Str(Chance_Amount(n,percentage))+" of max amount "+Str(n)+" with "+Str(percentage)+"% probability."

Chance vs Probability!

The routines are very simple, so what is the point of this being a Tips really?

The reason is that many confuses the idea of Chance and Probability, as chance always have a 50/50 chance of happening or not happening. While probability is the likelihood of it happening or not. In other words probability is chance+bias.

So think about impossible as a synonym for improbable, and possible as a synonym for probable. You may think it is impossible for humans to fly on their own, but its' not, it's simply highly improbable we'll be able to ever. You may think eating will always be possible, but you could be wrong, we could evolve to not need to eat, eating is simply highly probably to remain a human necessity.

The illusionist Derren Brown once tossed ten coins all heads in a row, the probability of that is very low, how did he do it?

He and the TV crew spent over 9 hours, where he again and again started counting from 1, until 9 hours later he finally managed ten heads in a row.

Conclusion!

So the next time you think that there is a probability of something happening 90% of the time, does not mean it actually will. There is a likelihood it will, but no guarantee.

But with the two routines above, you will be guaranteed to have the bias needed to make the chance match the expected perceived probability.

Those playing your game will have no idea how, but they will feel that the game is fair.
As it is the perceived probability that people expect, rather than what chance actually is, pure luck.


Related Jobs

Crytek
Crytek — Shanghai, China
[04.24.14]

Mobile Programmer
2K
2K — Novato, California, United States
[04.24.14]

Senior Tools Programmer
Turbine Inc.
Turbine Inc. — Needham, Massachusetts, United States
[04.23.14]

Director, Analytics Platform Development
Gameloft Toronto
Gameloft Toronto — Toronto, Ontario, Canada
[04.23.14]

Technical Artist






Comments


Tim Carter
profile image
Once, when I was playing D&D as a teenager, I rolled 6 20's in a row. One in 65 million odds. My old D&D friends still talk about that.

Tyler Glaiel
profile image
technically any individual sequence is one in 65 million odds.

Mathieu MarquisBolduc
profile image
But only one gives you the right to wear an "I roll 20's" t-shirt.

Tyler Glaiel
profile image
Yes, I suppose the "I rolled 8, 12, 1, 2, 1, 18, 20, 4, 13, 13, 7, 19, 17, 20, 6, 9, 8, 14, 17, 2" doesn't have the same impact

Mathieu MarquisBolduc
profile image
I wanna make a few serious comments, tho, following my past experience with using random checks/probabilities in games. You have to be really careful when using probabilities in games, for several reasons.



1- Most random numbers generators SUCKS. Google it.



2- In most games, the number of samples of any given random event are not high enough for "probabilities" to be used. If you "roll the dice" less than about 30 times for a certain event in a play session, you shouldn't use a straight-up randomness.



3- If you allow randomness to create just any pattern in your game, without filtering it, players who witness unlikely pattern will assume your game is broken or badly designed. Filtered randomness is your friend. (google it).



4- There are a lot of different probability distributions. For example, if you want something to happen every 4 days on average in your game, you should use something like a Poisson distribution (google it).



To sum up, doing a straight "Random() < chance of happening" check it almost always a bad idea.

Tim Carter
profile image
When you say "in most games" are you talking about tabletop games?



In my experience, if the players are told the odds, they won't think the game is broken at all. If you tell that such-and-such happens on a 1 on a percentile roll, they will know they have a 1% chance of success. There's no way they'll think the game itself is off then, even if that roll happens once in the game session.



True, the odds are unlikely they'll roll it - but then again, it is rolls like that that, when passed, lead to legendary moments in players' memories.

Mathieu MarquisBolduc
profile image
I was talking specifically about video games.



Lets say the player have a big attack in a jrpg it uses only 3-4 time per play session. lets say this attack has a 80% chance of success. You should never, never leave it to a random check. Because *some* players will fail all of them, even if its unlikely, and they will be pissed and they will think the game is broken.



I should have added another point:



5- Most people dont get independant random event. Intuitively, most people will think that if you flip "head" 4 times in a row, the probability of getting a fifth is low, even tho its 50-50. Its better not to try fighting this impression, however wrong it is.

Bevan Bennett
profile image
If you want to temper the possibility of (un)lucky streaks, it can be beneficial to model your PRNG as a pool of numbered tokens rather than a die (or dice).



Consider the difference between a deck of 36 cards numbered 2,3,3,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,11,11,12 and 2d6. In the latter case it's perfectly feasible (if somewhat unlikely) to get a result of 2 (or 12) several times in a row, but such a result is impossible using the cards/tokens. It can get tricky in deciding how to replenish the pool (or when to reshuffle the cards), but this approach can really help even out when streakiness can kill or frustrate a player. I remember some friends used to -only- play Settlers of Cataan with such a "dice deck" and never with actual dice for this reason.



A decent general algorithm for a token pool is to return a token to the pool after pool size/2 additional tokens have been removed.

Tim Carter
profile image
The problem is that the players will start to "count cards".



Besides, what is true about life is that non-average events occur. They must occur for averages to even exist. The bell curve is a curve, not a spike in the middle, with nearly flat regions on the sides.

Roger Haagensen
profile image
Some more examples just to show how flexible the Chance_Amount() routine is (which really is the star in the article above).



Magic damage of your attack could be 90-135 for example.

damagedealt=Chance_Amount(damage+damagebonus,hitpercentage+hitpercentagebonus)



Crafted armor strength.

armorstrength=Chance_Amount(armorpotential+materialpotential,smithingpercentage+smithingb onus)



Now as you get access to better spells, or you increase attributes or skills, or get buffs or items or other bonuses

the closer to 100% (aka maxed out) you get, this is a huge incentive to max out your character,

another thing is that with a maxed out character you are less likely to suffer penalties by negative buffs from attackers

as hopefully your high skills and bonuses ensures that you are still close to or at 100%.



A routine like Chance_Amount() could "power" the bulk of the stats in a game.



You could for example specify bullet impact as the amount value, and the wind as the percentage.

Where 100% would indicate no wind (perfect conditions) and 0% would indicate impossible weather.

Depending on the context this could be used to give a drift or crosswind affected result, or instead of damage the amount value could mean distance.



Chance_Amount() would also be useful in car games.

If the car is undamaged it is 100%, but if you get it beaten up pretty badly, maybe it drops to 50% or worse.

And depending on what the amount value represent this could mean steering drift, or max speed loss, or break efficiency issues.



I did ponder mentioning such examples in the article but it was long enough for such a simple routine.

Besides, this article is under the "Programming" category so I was kinda hoping people would immediately see all the possible uses for this. *laughs*

Nick Green
profile image
"For example a hit chance of 99% should hit 99 out of 100 shots, but how many games can you remember where this has been true?"



I don't think this is "wrong calculations" - it's potentially a lack of transparency, or a more sophisticated system than might be apparent to some players.



Eg. a 99% hit chance might mean that against a same level mob with no dodge modifier, each hit by the player has a 99% chance of hitting.



But mobs might have dodge modifiers that - true to their name - modify the 99% hit chance so that a same level player doesn't actually have a 99% chance of hitting them. Relative level is also often used to modify this chance up or down so that eg. a level 1 player trying to hit a level 40 mob might - despite their 99% hit chance - miss a lot.



That's not wrong :)


none
 
Comment: