[{"data":1,"prerenderedAt":1708},["ShallowReactive",2],{"guide-random-number-generation-games":3},{"id":4,"title":5,"body":6,"date":1697,"description":1698,"extension":1699,"meta":1700,"navigation":454,"path":1704,"readingTime":254,"seo":1705,"stem":1706,"__hash__":1707},"guides\u002Fguides\u002Frandom-number-generation-games.md","Random Number Generation in Games: Fairness, Fun, and Mechanics",{"type":7,"value":8,"toc":1676},"minimark",[9,14,18,34,38,138,142,145,150,153,353,357,360,364,367,371,374,396,681,685,689,692,946,950,953,1106,1110,1113,1174,1178,1181,1281,1285,1288,1615,1619,1639,1643,1652,1656,1672],[10,11,13],"h2",{"id":12},"randomness-is-the-heart-of-games","Randomness Is the Heart of Games",[15,16,17],"p",{},"Without randomness, every game session would play identically. Cards would always draw in the same order, enemies would follow the same patrol routes, and loot would always drop the same items. Randomness is what makes games replayable, surprising, and emotionally engaging.",[15,19,20,21,25,26,29,30,33],{},"But randomness in games is not the same as randomness in cryptography. Game RNG prioritizes ",[22,23,24],"strong",{},"speed",", ",[22,27,28],{},"reproducibility",", and ",[22,31,32],{},"designer control"," — not unpredictability against attackers.",[10,35,37],{"id":36},"where-games-use-randomness","Where Games Use Randomness",[39,40,41,57],"table",{},[42,43,44],"thead",{},[45,46,47,51,54],"tr",{},[48,49,50],"th",{},"System",[48,52,53],{},"What It Randomizes",[48,55,56],{},"Design Goal",[58,59,60,72,83,94,105,116,127],"tbody",{},[45,61,62,66,69],{},[63,64,65],"td",{},"Loot drops",[63,67,68],{},"Item type, rarity, stats",[63,70,71],{},"Reward anticipation, progression",[45,73,74,77,80],{},[63,75,76],{},"Card shuffling",[63,78,79],{},"Deck order",[63,81,82],{},"Fairness, replayability",[45,84,85,88,91],{},[63,86,87],{},"Dice mechanics",[63,89,90],{},"Combat outcomes, skill checks",[63,92,93],{},"Uncertainty, drama",[45,95,96,99,102],{},[63,97,98],{},"Procedural generation",[63,100,101],{},"Terrain, rooms, levels",[63,103,104],{},"Unique experiences",[45,106,107,110,113],{},[63,108,109],{},"AI behavior",[63,111,112],{},"Patrol paths, attack choices",[63,114,115],{},"Unpredictability",[45,117,118,121,124],{},[63,119,120],{},"Critical hits",[63,122,123],{},"Extra damage chance",[63,125,126],{},"Excitement, risk\u002Freward",[45,128,129,132,135],{},[63,130,131],{},"Spawn locations",[63,133,134],{},"Enemy\u002Fitem placement",[63,136,137],{},"Exploration variety",[10,139,141],{"id":140},"prngs-suitable-for-games","PRNGs Suitable for Games",[15,143,144],{},"Games need fast, deterministic PRNGs that produce good statistical distributions. Cryptographic generators are overkill and too slow for the volume of random calls games make per frame.",[146,147,149],"h3",{"id":148},"xorshift128","Xorshift128+",[15,151,152],{},"The default in V8 (Chrome\u002FNode.js). Fast, good distribution, 128-bit state.",[154,155,160],"pre",{"className":156,"code":157,"language":158,"meta":159,"style":159},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F Simplified xorshift128+ (educational)\nlet state0 = 1, state1 = 2;\nfunction xorshift128plus() {\n  let s1 = state0;\n  let s0 = state1;\n  state0 = s0;\n  s1 ^= s1 \u003C\u003C 23;\n  s1 ^= s1 >> 17;\n  s1 ^= s0;\n  s1 ^= s0 >> 26;\n  state1 = s1;\n  return (s0 + s1) >>> 0;\n}\n","javascript","",[161,162,163,172,201,214,228,241,252,271,288,297,313,324,347],"code",{"__ignoreMap":159},[164,165,168],"span",{"class":166,"line":167},"line",1,[164,169,171],{"class":170},"sJ8bj","\u002F\u002F Simplified xorshift128+ (educational)\n",[164,173,175,179,183,186,190,193,195,198],{"class":166,"line":174},2,[164,176,178],{"class":177},"szBVR","let",[164,180,182],{"class":181},"sVt8B"," state0 ",[164,184,185],{"class":177},"=",[164,187,189],{"class":188},"sj4cs"," 1",[164,191,192],{"class":181},", state1 ",[164,194,185],{"class":177},[164,196,197],{"class":188}," 2",[164,199,200],{"class":181},";\n",[164,202,204,207,211],{"class":166,"line":203},3,[164,205,206],{"class":177},"function",[164,208,210],{"class":209},"sScJk"," xorshift128plus",[164,212,213],{"class":181},"() {\n",[164,215,217,220,223,225],{"class":166,"line":216},4,[164,218,219],{"class":177},"  let",[164,221,222],{"class":181}," s1 ",[164,224,185],{"class":177},[164,226,227],{"class":181}," state0;\n",[164,229,231,233,236,238],{"class":166,"line":230},5,[164,232,219],{"class":177},[164,234,235],{"class":181}," s0 ",[164,237,185],{"class":177},[164,239,240],{"class":181}," state1;\n",[164,242,244,247,249],{"class":166,"line":243},6,[164,245,246],{"class":181},"  state0 ",[164,248,185],{"class":177},[164,250,251],{"class":181}," s0;\n",[164,253,255,258,261,263,266,269],{"class":166,"line":254},7,[164,256,257],{"class":181},"  s1 ",[164,259,260],{"class":177},"^=",[164,262,222],{"class":181},[164,264,265],{"class":177},"\u003C\u003C",[164,267,268],{"class":188}," 23",[164,270,200],{"class":181},[164,272,274,276,278,280,283,286],{"class":166,"line":273},8,[164,275,257],{"class":181},[164,277,260],{"class":177},[164,279,222],{"class":181},[164,281,282],{"class":177},">>",[164,284,285],{"class":188}," 17",[164,287,200],{"class":181},[164,289,291,293,295],{"class":166,"line":290},9,[164,292,257],{"class":181},[164,294,260],{"class":177},[164,296,251],{"class":181},[164,298,300,302,304,306,308,311],{"class":166,"line":299},10,[164,301,257],{"class":181},[164,303,260],{"class":177},[164,305,235],{"class":181},[164,307,282],{"class":177},[164,309,310],{"class":188}," 26",[164,312,200],{"class":181},[164,314,316,319,321],{"class":166,"line":315},11,[164,317,318],{"class":181},"  state1 ",[164,320,185],{"class":177},[164,322,323],{"class":181}," s1;\n",[164,325,327,330,333,336,339,342,345],{"class":166,"line":326},12,[164,328,329],{"class":177},"  return",[164,331,332],{"class":181}," (s0 ",[164,334,335],{"class":177},"+",[164,337,338],{"class":181}," s1) ",[164,340,341],{"class":177},">>>",[164,343,344],{"class":188}," 0",[164,346,200],{"class":181},[164,348,350],{"class":166,"line":349},13,[164,351,352],{"class":181},"}\n",[146,354,356],{"id":355},"pcg-permuted-congruential-generator","PCG (Permuted Congruential Generator)",[15,358,359],{},"A newer family combining LCG speed with better statistical quality. Gaining adoption in game engines.",[146,361,363],{"id":362},"mersenne-twister-mt19937","Mersenne Twister (MT19937)",[15,365,366],{},"The default in Python and many game engines. Extremely long period (2^19937 - 1), but large state (2.5 KB). Overkill for most games but widely available.",[10,368,370],{"id":369},"seeded-rng-for-reproducibility","Seeded RNG for Reproducibility",[15,372,373],{},"Games often need reproducible randomness — the same seed should produce the same world. This is essential for:",[375,376,377,384,390],"ul",{},[378,379,380,383],"li",{},[22,381,382],{},"Deterministic replays",": Record seed + player inputs, not full game state",[378,385,386,389],{},[22,387,388],{},"Shared worlds",": Multiplayer games synchronize seeds so all clients generate the same terrain",[378,391,392,395],{},[22,393,394],{},"Debugging",": Reproduce bugs by replaying with the same seed",[154,397,399],{"className":156,"code":398,"language":158,"meta":159,"style":159},"\u002F\u002F Seeded PRNG for game worlds\nclass SeededRNG {\n  constructor(seed) {\n    this.seed = seed;\n  }\n\n  next() {\n    this.seed = (this.seed * 16807 + 0) % 2147483647;\n    return this.seed \u002F 2147483647;\n  }\n\n  \u002F\u002F Random integer in range [min, max)\n  nextInt(min, max) {\n    return Math.floor(this.next() * (max - min)) + min;\n  }\n}\n\nconst world = new SeededRNG(42);\nconst treeX = world.nextInt(0, 800);\nconst treeY = world.nextInt(0, 600);\n",[161,400,401,406,417,432,445,450,456,463,501,518,522,526,531,548,588,593,598,603,628,656],{"__ignoreMap":159},[164,402,403],{"class":166,"line":167},[164,404,405],{"class":170},"\u002F\u002F Seeded PRNG for game worlds\n",[164,407,408,411,414],{"class":166,"line":174},[164,409,410],{"class":177},"class",[164,412,413],{"class":209}," SeededRNG",[164,415,416],{"class":181}," {\n",[164,418,419,422,425,429],{"class":166,"line":203},[164,420,421],{"class":177},"  constructor",[164,423,424],{"class":181},"(",[164,426,428],{"class":427},"s4XuR","seed",[164,430,431],{"class":181},") {\n",[164,433,434,437,440,442],{"class":166,"line":216},[164,435,436],{"class":188},"    this",[164,438,439],{"class":181},".seed ",[164,441,185],{"class":177},[164,443,444],{"class":181}," seed;\n",[164,446,447],{"class":166,"line":230},[164,448,449],{"class":181},"  }\n",[164,451,452],{"class":166,"line":243},[164,453,455],{"emptyLinePlaceholder":454},true,"\n",[164,457,458,461],{"class":166,"line":254},[164,459,460],{"class":209},"  next",[164,462,213],{"class":181},[164,464,465,467,469,471,474,477,479,482,485,488,490,493,496,499],{"class":166,"line":273},[164,466,436],{"class":188},[164,468,439],{"class":181},[164,470,185],{"class":177},[164,472,473],{"class":181}," (",[164,475,476],{"class":188},"this",[164,478,439],{"class":181},[164,480,481],{"class":177},"*",[164,483,484],{"class":188}," 16807",[164,486,487],{"class":177}," +",[164,489,344],{"class":188},[164,491,492],{"class":181},") ",[164,494,495],{"class":177},"%",[164,497,498],{"class":188}," 2147483647",[164,500,200],{"class":181},[164,502,503,506,509,511,514,516],{"class":166,"line":290},[164,504,505],{"class":177},"    return",[164,507,508],{"class":188}," this",[164,510,439],{"class":181},[164,512,513],{"class":177},"\u002F",[164,515,498],{"class":188},[164,517,200],{"class":181},[164,519,520],{"class":166,"line":299},[164,521,449],{"class":181},[164,523,524],{"class":166,"line":315},[164,525,455],{"emptyLinePlaceholder":454},[164,527,528],{"class":166,"line":326},[164,529,530],{"class":170},"  \u002F\u002F Random integer in range [min, max)\n",[164,532,533,536,538,541,543,546],{"class":166,"line":349},[164,534,535],{"class":209},"  nextInt",[164,537,424],{"class":181},[164,539,540],{"class":427},"min",[164,542,25],{"class":181},[164,544,545],{"class":427},"max",[164,547,431],{"class":181},[164,549,551,553,556,559,561,563,566,569,572,574,577,580,583,585],{"class":166,"line":550},14,[164,552,505],{"class":177},[164,554,555],{"class":181}," Math.",[164,557,558],{"class":209},"floor",[164,560,424],{"class":181},[164,562,476],{"class":188},[164,564,565],{"class":181},".",[164,567,568],{"class":209},"next",[164,570,571],{"class":181},"() ",[164,573,481],{"class":177},[164,575,576],{"class":181}," (max ",[164,578,579],{"class":177},"-",[164,581,582],{"class":181}," min)) ",[164,584,335],{"class":177},[164,586,587],{"class":181}," min;\n",[164,589,591],{"class":166,"line":590},15,[164,592,449],{"class":181},[164,594,596],{"class":166,"line":595},16,[164,597,352],{"class":181},[164,599,601],{"class":166,"line":600},17,[164,602,455],{"emptyLinePlaceholder":454},[164,604,606,609,612,615,618,620,622,625],{"class":166,"line":605},18,[164,607,608],{"class":177},"const",[164,610,611],{"class":188}," world",[164,613,614],{"class":177}," =",[164,616,617],{"class":177}," new",[164,619,413],{"class":209},[164,621,424],{"class":181},[164,623,624],{"class":188},"42",[164,626,627],{"class":181},");\n",[164,629,631,633,636,638,641,644,646,649,651,654],{"class":166,"line":630},19,[164,632,608],{"class":177},[164,634,635],{"class":188}," treeX",[164,637,614],{"class":177},[164,639,640],{"class":181}," world.",[164,642,643],{"class":209},"nextInt",[164,645,424],{"class":181},[164,647,648],{"class":188},"0",[164,650,25],{"class":181},[164,652,653],{"class":188},"800",[164,655,627],{"class":181},[164,657,659,661,664,666,668,670,672,674,676,679],{"class":166,"line":658},20,[164,660,608],{"class":177},[164,662,663],{"class":188}," treeY",[164,665,614],{"class":177},[164,667,640],{"class":181},[164,669,643],{"class":209},[164,671,424],{"class":181},[164,673,648],{"class":188},[164,675,25],{"class":181},[164,677,678],{"class":188},"600",[164,680,627],{"class":181},[10,682,684],{"id":683},"loot-drop-mechanics","Loot Drop Mechanics",[146,686,688],{"id":687},"weighted-random-selection","Weighted Random Selection",[15,690,691],{},"Not all items drop with equal probability. Weighted selection assigns probabilities proportional to weights:",[154,693,695],{"className":156,"code":694,"language":158,"meta":159,"style":159},"function weightedRandom(items) {\n  const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);\n  let roll = Math.random() * totalWeight;\n\n  for (const item of items) {\n    roll -= item.weight;\n    if (roll \u003C= 0) return item;\n  }\n  return items[items.length - 1];\n}\n\n\u002F\u002F Usage\nconst loot = weightedRandom([\n  { name: 'Common Sword', weight: 60 },\n  { name: 'Rare Shield',  weight: 25 },\n  { name: 'Epic Ring',    weight: 10 },\n  { name: 'Legendary Staff', weight: 5 },\n]);\n",[161,696,697,711,755,776,780,798,809,830,834,852,856,860,865,879,897,912,927,941],{"__ignoreMap":159},[164,698,699,701,704,706,709],{"class":166,"line":167},[164,700,206],{"class":177},[164,702,703],{"class":209}," weightedRandom",[164,705,424],{"class":181},[164,707,708],{"class":427},"items",[164,710,431],{"class":181},[164,712,713,716,719,721,724,727,730,733,735,738,740,743,746,748,751,753],{"class":166,"line":174},[164,714,715],{"class":177},"  const",[164,717,718],{"class":188}," totalWeight",[164,720,614],{"class":177},[164,722,723],{"class":181}," items.",[164,725,726],{"class":209},"reduce",[164,728,729],{"class":181},"((",[164,731,732],{"class":427},"sum",[164,734,25],{"class":181},[164,736,737],{"class":427},"item",[164,739,492],{"class":181},[164,741,742],{"class":177},"=>",[164,744,745],{"class":181}," sum ",[164,747,335],{"class":177},[164,749,750],{"class":181}," item.weight, ",[164,752,648],{"class":188},[164,754,627],{"class":181},[164,756,757,759,762,764,766,769,771,773],{"class":166,"line":203},[164,758,219],{"class":177},[164,760,761],{"class":181}," roll ",[164,763,185],{"class":177},[164,765,555],{"class":181},[164,767,768],{"class":209},"random",[164,770,571],{"class":181},[164,772,481],{"class":177},[164,774,775],{"class":181}," totalWeight;\n",[164,777,778],{"class":166,"line":216},[164,779,455],{"emptyLinePlaceholder":454},[164,781,782,785,787,789,792,795],{"class":166,"line":230},[164,783,784],{"class":177},"  for",[164,786,473],{"class":181},[164,788,608],{"class":177},[164,790,791],{"class":188}," item",[164,793,794],{"class":177}," of",[164,796,797],{"class":181}," items) {\n",[164,799,800,803,806],{"class":166,"line":243},[164,801,802],{"class":181},"    roll ",[164,804,805],{"class":177},"-=",[164,807,808],{"class":181}," item.weight;\n",[164,810,811,814,817,820,822,824,827],{"class":166,"line":254},[164,812,813],{"class":177},"    if",[164,815,816],{"class":181}," (roll ",[164,818,819],{"class":177},"\u003C=",[164,821,344],{"class":188},[164,823,492],{"class":181},[164,825,826],{"class":177},"return",[164,828,829],{"class":181}," item;\n",[164,831,832],{"class":166,"line":273},[164,833,449],{"class":181},[164,835,836,838,841,844,847,849],{"class":166,"line":290},[164,837,329],{"class":177},[164,839,840],{"class":181}," items[items.",[164,842,843],{"class":188},"length",[164,845,846],{"class":177}," -",[164,848,189],{"class":188},[164,850,851],{"class":181},"];\n",[164,853,854],{"class":166,"line":299},[164,855,352],{"class":181},[164,857,858],{"class":166,"line":315},[164,859,455],{"emptyLinePlaceholder":454},[164,861,862],{"class":166,"line":326},[164,863,864],{"class":170},"\u002F\u002F Usage\n",[164,866,867,869,872,874,876],{"class":166,"line":349},[164,868,608],{"class":177},[164,870,871],{"class":188}," loot",[164,873,614],{"class":177},[164,875,703],{"class":209},[164,877,878],{"class":181},"([\n",[164,880,881,884,888,891,894],{"class":166,"line":550},[164,882,883],{"class":181},"  { name: ",[164,885,887],{"class":886},"sZZnC","'Common Sword'",[164,889,890],{"class":181},", weight: ",[164,892,893],{"class":188},"60",[164,895,896],{"class":181}," },\n",[164,898,899,901,904,907,910],{"class":166,"line":590},[164,900,883],{"class":181},[164,902,903],{"class":886},"'Rare Shield'",[164,905,906],{"class":181},",  weight: ",[164,908,909],{"class":188},"25",[164,911,896],{"class":181},[164,913,914,916,919,922,925],{"class":166,"line":595},[164,915,883],{"class":181},[164,917,918],{"class":886},"'Epic Ring'",[164,920,921],{"class":181},",    weight: ",[164,923,924],{"class":188},"10",[164,926,896],{"class":181},[164,928,929,931,934,936,939],{"class":166,"line":600},[164,930,883],{"class":181},[164,932,933],{"class":886},"'Legendary Staff'",[164,935,890],{"class":181},[164,937,938],{"class":188},"5",[164,940,896],{"class":181},[164,942,943],{"class":166,"line":605},[164,944,945],{"class":181},"]);\n",[146,947,949],{"id":948},"pity-systems","Pity Systems",[15,951,952],{},"Pure random drops frustrate players when luck is bad. Pity timers guarantee a rare drop after N failed attempts:",[154,954,956],{"className":156,"code":955,"language":158,"meta":159,"style":159},"function lootWithPity(attempts, threshold = 10) {\n  if (attempts >= threshold) {\n    return { name: 'Guaranteed Rare', rarity: 'rare' };\n  }\n\n  const dropChance = 0.05 + (attempts * 0.005); \u002F\u002F Soft pity\n  if (Math.random() \u003C dropChance) {\n    return { name: 'Rare Item', rarity: 'rare' };\n  }\n  return { name: 'Common Item', rarity: 'common' };\n}\n",[161,957,958,982,996,1015,1019,1023,1050,1067,1082,1086,1102],{"__ignoreMap":159},[164,959,960,962,965,967,970,972,975,977,980],{"class":166,"line":167},[164,961,206],{"class":177},[164,963,964],{"class":209}," lootWithPity",[164,966,424],{"class":181},[164,968,969],{"class":427},"attempts",[164,971,25],{"class":181},[164,973,974],{"class":427},"threshold",[164,976,614],{"class":177},[164,978,979],{"class":188}," 10",[164,981,431],{"class":181},[164,983,984,987,990,993],{"class":166,"line":174},[164,985,986],{"class":177},"  if",[164,988,989],{"class":181}," (attempts ",[164,991,992],{"class":177},">=",[164,994,995],{"class":181}," threshold) {\n",[164,997,998,1000,1003,1006,1009,1012],{"class":166,"line":203},[164,999,505],{"class":177},[164,1001,1002],{"class":181}," { name: ",[164,1004,1005],{"class":886},"'Guaranteed Rare'",[164,1007,1008],{"class":181},", rarity: ",[164,1010,1011],{"class":886},"'rare'",[164,1013,1014],{"class":181}," };\n",[164,1016,1017],{"class":166,"line":216},[164,1018,449],{"class":181},[164,1020,1021],{"class":166,"line":230},[164,1022,455],{"emptyLinePlaceholder":454},[164,1024,1025,1027,1030,1032,1035,1037,1039,1041,1044,1047],{"class":166,"line":243},[164,1026,715],{"class":177},[164,1028,1029],{"class":188}," dropChance",[164,1031,614],{"class":177},[164,1033,1034],{"class":188}," 0.05",[164,1036,487],{"class":177},[164,1038,989],{"class":181},[164,1040,481],{"class":177},[164,1042,1043],{"class":188}," 0.005",[164,1045,1046],{"class":181},"); ",[164,1048,1049],{"class":170},"\u002F\u002F Soft pity\n",[164,1051,1052,1054,1057,1059,1061,1064],{"class":166,"line":254},[164,1053,986],{"class":177},[164,1055,1056],{"class":181}," (Math.",[164,1058,768],{"class":209},[164,1060,571],{"class":181},[164,1062,1063],{"class":177},"\u003C",[164,1065,1066],{"class":181}," dropChance) {\n",[164,1068,1069,1071,1073,1076,1078,1080],{"class":166,"line":273},[164,1070,505],{"class":177},[164,1072,1002],{"class":181},[164,1074,1075],{"class":886},"'Rare Item'",[164,1077,1008],{"class":181},[164,1079,1011],{"class":886},[164,1081,1014],{"class":181},[164,1083,1084],{"class":166,"line":290},[164,1085,449],{"class":181},[164,1087,1088,1090,1092,1095,1097,1100],{"class":166,"line":299},[164,1089,329],{"class":177},[164,1091,1002],{"class":181},[164,1093,1094],{"class":886},"'Common Item'",[164,1096,1008],{"class":181},[164,1098,1099],{"class":886},"'common'",[164,1101,1014],{"class":181},[164,1103,1104],{"class":166,"line":315},[164,1105,352],{"class":181},[10,1107,1109],{"id":1108},"player-perception-of-fairness","Player Perception of Fairness",[15,1111,1112],{},"Players perceive randomness differently than mathematicians. Key findings from game design research:",[39,1114,1115,1128],{},[42,1116,1117],{},[45,1118,1119,1122,1125],{},[48,1120,1121],{},"Phenomenon",[48,1123,1124],{},"Description",[48,1126,1127],{},"Design Response",[58,1129,1130,1141,1152,1163],{},[45,1131,1132,1135,1138],{},[63,1133,1134],{},"Gambler's fallacy",[63,1136,1137],{},"\"I'm due for a win\"",[63,1139,1140],{},"Pity systems exploit this positively",[45,1142,1143,1146,1149],{},[63,1144,1145],{},"Clustering illusion",[63,1147,1148],{},"\"Three misses in a row is broken\"",[63,1150,1151],{},"Streak breaking logic",[45,1153,1154,1157,1160],{},[63,1155,1156],{},"Loss aversion",[63,1158,1159],{},"Losses feel worse than equivalent gains",[63,1161,1162],{},"Near-miss feedback (show how close)",[45,1164,1165,1168,1171],{},[63,1166,1167],{},"Hindsight bias",[63,1169,1170],{},"\"I should have known that would miss\"",[63,1172,1173],{},"Transparent probability display",[146,1175,1177],{"id":1176},"streak-breaking","Streak Breaking",[15,1179,1180],{},"If a player misses 3+ times in a row, some games silently boost the next hit chance to prevent frustration:",[154,1182,1184],{"className":156,"code":1183,"language":158,"meta":159,"style":159},"function combatRoll(consecutiveMisses) {\n  let hitChance = 0.7;\n  if (consecutiveMisses >= 3) {\n    hitChance = Math.min(hitChance + 0.15 * consecutiveMisses, 0.95);\n  }\n  return Math.random() \u003C hitChance;\n}\n",[161,1185,1186,1200,1214,1228,1258,1262,1277],{"__ignoreMap":159},[164,1187,1188,1190,1193,1195,1198],{"class":166,"line":167},[164,1189,206],{"class":177},[164,1191,1192],{"class":209}," combatRoll",[164,1194,424],{"class":181},[164,1196,1197],{"class":427},"consecutiveMisses",[164,1199,431],{"class":181},[164,1201,1202,1204,1207,1209,1212],{"class":166,"line":174},[164,1203,219],{"class":177},[164,1205,1206],{"class":181}," hitChance ",[164,1208,185],{"class":177},[164,1210,1211],{"class":188}," 0.7",[164,1213,200],{"class":181},[164,1215,1216,1218,1221,1223,1226],{"class":166,"line":203},[164,1217,986],{"class":177},[164,1219,1220],{"class":181}," (consecutiveMisses ",[164,1222,992],{"class":177},[164,1224,1225],{"class":188}," 3",[164,1227,431],{"class":181},[164,1229,1230,1233,1235,1237,1239,1242,1244,1247,1250,1253,1256],{"class":166,"line":216},[164,1231,1232],{"class":181},"    hitChance ",[164,1234,185],{"class":177},[164,1236,555],{"class":181},[164,1238,540],{"class":209},[164,1240,1241],{"class":181},"(hitChance ",[164,1243,335],{"class":177},[164,1245,1246],{"class":188}," 0.15",[164,1248,1249],{"class":177}," *",[164,1251,1252],{"class":181}," consecutiveMisses, ",[164,1254,1255],{"class":188},"0.95",[164,1257,627],{"class":181},[164,1259,1260],{"class":166,"line":230},[164,1261,449],{"class":181},[164,1263,1264,1266,1268,1270,1272,1274],{"class":166,"line":243},[164,1265,329],{"class":177},[164,1267,555],{"class":181},[164,1269,768],{"class":209},[164,1271,571],{"class":181},[164,1273,1063],{"class":177},[164,1275,1276],{"class":181}," hitChance;\n",[164,1278,1279],{"class":166,"line":254},[164,1280,352],{"class":181},[10,1282,1284],{"id":1283},"procedural-generation","Procedural Generation",[15,1286,1287],{},"For terrain and level generation, combine multiple PRNG calls with noise functions:",[154,1289,1291],{"className":156,"code":1290,"language":158,"meta":159,"style":159},"\u002F\u002F Simple 1D terrain using midpoint displacement\nfunction generateTerrain(width, roughness, rng) {\n  const terrain = new Array(width).fill(0);\n  terrain[0] = rng.nextInt(30, 70);\n  terrain[width - 1] = rng.nextInt(30, 70);\n\n  let step = width - 1;\n  let scale = roughness;\n\n  while (step > 1) {\n    const half = Math.floor(step \u002F 2);\n    for (let i = half; i \u003C width; i += step) {\n      const avg = (terrain[i - half] + terrain[i + half]) \u002F 2;\n      terrain[i] = avg + (rng.next() - 0.5) * scale;\n    }\n    step = half;\n    scale *= 0.5;\n  }\n  return terrain;\n}\n",[161,1292,1293,1298,1322,1348,1377,1404,1408,1426,1438,1442,1457,1480,1508,1542,1573,1578,1588,1600,1604,1611],{"__ignoreMap":159},[164,1294,1295],{"class":166,"line":167},[164,1296,1297],{"class":170},"\u002F\u002F Simple 1D terrain using midpoint displacement\n",[164,1299,1300,1302,1305,1307,1310,1312,1315,1317,1320],{"class":166,"line":174},[164,1301,206],{"class":177},[164,1303,1304],{"class":209}," generateTerrain",[164,1306,424],{"class":181},[164,1308,1309],{"class":427},"width",[164,1311,25],{"class":181},[164,1313,1314],{"class":427},"roughness",[164,1316,25],{"class":181},[164,1318,1319],{"class":427},"rng",[164,1321,431],{"class":181},[164,1323,1324,1326,1329,1331,1333,1336,1339,1342,1344,1346],{"class":166,"line":203},[164,1325,715],{"class":177},[164,1327,1328],{"class":188}," terrain",[164,1330,614],{"class":177},[164,1332,617],{"class":177},[164,1334,1335],{"class":209}," Array",[164,1337,1338],{"class":181},"(width).",[164,1340,1341],{"class":209},"fill",[164,1343,424],{"class":181},[164,1345,648],{"class":188},[164,1347,627],{"class":181},[164,1349,1350,1353,1355,1358,1360,1363,1365,1367,1370,1372,1375],{"class":166,"line":216},[164,1351,1352],{"class":181},"  terrain[",[164,1354,648],{"class":188},[164,1356,1357],{"class":181},"] ",[164,1359,185],{"class":177},[164,1361,1362],{"class":181}," rng.",[164,1364,643],{"class":209},[164,1366,424],{"class":181},[164,1368,1369],{"class":188},"30",[164,1371,25],{"class":181},[164,1373,1374],{"class":188},"70",[164,1376,627],{"class":181},[164,1378,1379,1382,1384,1386,1388,1390,1392,1394,1396,1398,1400,1402],{"class":166,"line":230},[164,1380,1381],{"class":181},"  terrain[width ",[164,1383,579],{"class":177},[164,1385,189],{"class":188},[164,1387,1357],{"class":181},[164,1389,185],{"class":177},[164,1391,1362],{"class":181},[164,1393,643],{"class":209},[164,1395,424],{"class":181},[164,1397,1369],{"class":188},[164,1399,25],{"class":181},[164,1401,1374],{"class":188},[164,1403,627],{"class":181},[164,1405,1406],{"class":166,"line":243},[164,1407,455],{"emptyLinePlaceholder":454},[164,1409,1410,1412,1415,1417,1420,1422,1424],{"class":166,"line":254},[164,1411,219],{"class":177},[164,1413,1414],{"class":181}," step ",[164,1416,185],{"class":177},[164,1418,1419],{"class":181}," width ",[164,1421,579],{"class":177},[164,1423,189],{"class":188},[164,1425,200],{"class":181},[164,1427,1428,1430,1433,1435],{"class":166,"line":273},[164,1429,219],{"class":177},[164,1431,1432],{"class":181}," scale ",[164,1434,185],{"class":177},[164,1436,1437],{"class":181}," roughness;\n",[164,1439,1440],{"class":166,"line":290},[164,1441,455],{"emptyLinePlaceholder":454},[164,1443,1444,1447,1450,1453,1455],{"class":166,"line":299},[164,1445,1446],{"class":177},"  while",[164,1448,1449],{"class":181}," (step ",[164,1451,1452],{"class":177},">",[164,1454,189],{"class":188},[164,1456,431],{"class":181},[164,1458,1459,1462,1465,1467,1469,1471,1474,1476,1478],{"class":166,"line":315},[164,1460,1461],{"class":177},"    const",[164,1463,1464],{"class":188}," half",[164,1466,614],{"class":177},[164,1468,555],{"class":181},[164,1470,558],{"class":209},[164,1472,1473],{"class":181},"(step ",[164,1475,513],{"class":177},[164,1477,197],{"class":188},[164,1479,627],{"class":181},[164,1481,1482,1485,1487,1489,1492,1494,1497,1499,1502,1505],{"class":166,"line":326},[164,1483,1484],{"class":177},"    for",[164,1486,473],{"class":181},[164,1488,178],{"class":177},[164,1490,1491],{"class":181}," i ",[164,1493,185],{"class":177},[164,1495,1496],{"class":181}," half; i ",[164,1498,1063],{"class":177},[164,1500,1501],{"class":181}," width; i ",[164,1503,1504],{"class":177},"+=",[164,1506,1507],{"class":181}," step) {\n",[164,1509,1510,1513,1516,1518,1521,1523,1526,1528,1531,1533,1536,1538,1540],{"class":166,"line":349},[164,1511,1512],{"class":177},"      const",[164,1514,1515],{"class":188}," avg",[164,1517,614],{"class":177},[164,1519,1520],{"class":181}," (terrain[i ",[164,1522,579],{"class":177},[164,1524,1525],{"class":181}," half] ",[164,1527,335],{"class":177},[164,1529,1530],{"class":181}," terrain[i ",[164,1532,335],{"class":177},[164,1534,1535],{"class":181}," half]) ",[164,1537,513],{"class":177},[164,1539,197],{"class":188},[164,1541,200],{"class":181},[164,1543,1544,1547,1549,1552,1554,1557,1559,1561,1563,1566,1568,1570],{"class":166,"line":550},[164,1545,1546],{"class":181},"      terrain[i] ",[164,1548,185],{"class":177},[164,1550,1551],{"class":181}," avg ",[164,1553,335],{"class":177},[164,1555,1556],{"class":181}," (rng.",[164,1558,568],{"class":209},[164,1560,571],{"class":181},[164,1562,579],{"class":177},[164,1564,1565],{"class":188}," 0.5",[164,1567,492],{"class":181},[164,1569,481],{"class":177},[164,1571,1572],{"class":181}," scale;\n",[164,1574,1575],{"class":166,"line":590},[164,1576,1577],{"class":181},"    }\n",[164,1579,1580,1583,1585],{"class":166,"line":595},[164,1581,1582],{"class":181},"    step ",[164,1584,185],{"class":177},[164,1586,1587],{"class":181}," half;\n",[164,1589,1590,1593,1596,1598],{"class":166,"line":600},[164,1591,1592],{"class":181},"    scale ",[164,1594,1595],{"class":177},"*=",[164,1597,1565],{"class":188},[164,1599,200],{"class":181},[164,1601,1602],{"class":166,"line":605},[164,1603,449],{"class":181},[164,1605,1606,1608],{"class":166,"line":630},[164,1607,329],{"class":177},[164,1609,1610],{"class":181}," terrain;\n",[164,1612,1613],{"class":166,"line":658},[164,1614,352],{"class":181},[10,1616,1618],{"id":1617},"key-takeaways","Key Takeaways",[375,1620,1621,1624,1627,1630,1633,1636],{},[378,1622,1623],{},"Games need fast, deterministic PRNGs — cryptographic security is unnecessary",[378,1625,1626],{},"Seeded RNG enables reproducible worlds, replays, and synced multiplayer",[378,1628,1629],{},"Weighted random selection is the standard for loot drops and encounters",[378,1631,1632],{},"Pity systems and streak breaking manage player frustration with bad luck",[378,1634,1635],{},"Player perception of fairness often matters more than mathematical fairness",[378,1637,1638],{},"Procedural generation combines PRNG with noise functions for natural-looking content",[10,1640,1642],{"id":1641},"try-it-yourself","Try It Yourself",[15,1644,1645,1646,1651],{},"Generate random numbers for any game mechanic with our ",[1647,1648,1650],"a",{"href":1649},"\u002Ftools\u002Frandom-number","Random Number Generator",". Set custom ranges, generate unique values, or create weighted distributions — all interactively.",[10,1653,1655],{"id":1654},"related-guides","Related Guides",[375,1657,1658,1665],{},[378,1659,1660,1664],{},[1647,1661,1663],{"href":1662},"\u002Fguides\u002Frandom-number-guide","Random Number Guide"," — types of RNG and how they work",[378,1666,1667,1671],{},[1647,1668,1670],{"href":1669},"\u002Fguides\u002Fprobability-and-statistics-tools","Probability and Statistics Tools"," — distributions, permutations, and combinatorics",[1673,1674,1675],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":159,"searchDepth":174,"depth":174,"links":1677},[1678,1679,1680,1685,1686,1690,1693,1694,1695,1696],{"id":12,"depth":174,"text":13},{"id":36,"depth":174,"text":37},{"id":140,"depth":174,"text":141,"children":1681},[1682,1683,1684],{"id":148,"depth":203,"text":149},{"id":355,"depth":203,"text":356},{"id":362,"depth":203,"text":363},{"id":369,"depth":174,"text":370},{"id":683,"depth":174,"text":684,"children":1687},[1688,1689],{"id":687,"depth":203,"text":688},{"id":948,"depth":203,"text":949},{"id":1108,"depth":174,"text":1109,"children":1691},[1692],{"id":1176,"depth":203,"text":1177},{"id":1283,"depth":174,"text":1284},{"id":1617,"depth":174,"text":1618},{"id":1641,"depth":174,"text":1642},{"id":1654,"depth":174,"text":1655},"2026-05-28","Explore how games use random number generation for loot drops, procedural content, dice mechanics, and AI behavior. Learn fairness patterns and player perception.","md",{"keywords":1701,"immutable":454},[1702,1703],"random-number","random-number-generation-games","\u002Fguides\u002Frandom-number-generation-games",{"title":5,"description":1698},"guides\u002Frandom-number-generation-games","Y4esNmieILwmFqeSzwCZI3bCu0WzlQpl4ka69645eLY",1780401336352]