**Jordan Navarro**

Ph.D. Student

University of Illinois

Urbana-Champaign

jmn5@illinois.edu

2016

The information included in this post is for educational purposes only. Any material on this webpage may not be reproduced, retransmitted, or redisplayed other than for personal or educational use.

Random number generation is a process which generates a sequence of numbers or symbols that cannot be reasonably predicted better than by a random chance. Warframe uses Donald Knuth’s variation of a linear congruential generator (LCG) as a base for its random number generation algorithm and scales from rarity weights assigned by Digital Extremes that influence the drop chances of items in `DropTables`

and `MissionDecks`

. The recursive aspect of the algorithm only applies to missions in which players receive rewards over time, such as Defense and Survival. Other mission types simply use the process explained below.

Warframe uses four rarity weights in its random number generation algorithm. These weights are uniform across `DropTables`

and `MissionDecks`

, except for any table that uses `FixedWeights`

(weights of fixed values that may deviate from the standard).

Rarity | Weight | Percentage |
---|---|---|

COMMON | 0.755 | 75.50% |

UNCOMMON | 0.22 | 22.00% |

RARE | 0.02 | 2.00% |

LEGENDARY | 0.005 | 0.50% |

The independent drop chance of an item can be computed through the following equation, with `Rarity`

being COMMON, UNCOMMON, RARE, or LEGENDARY:

**Rarity Drop Chance Per Item = Base Rarity Drop Chance / Number of Rarity Items**

**Exercise 1**. This exercise demonstrates the formulae with a test case of 8 COMMON, 6 UNCOMMON, 4 RARE, and 2 LEGENDARY items.

Rarity | Weight | Count | Quotient | Drop Chance Per Item |
---|---|---|---|---|

COMMON | 0.755 | 8 | 0.094375 | 9.44% |

UNCOMMON | 0.22 | 6 | 0.03666666666 | 3.67% |

RARE | 0.02 | 4 | 0.005 | 0.50% |

LEGENDARY | 0.005 | 2 | 0.0025 | 0.25% |

Normalization refers to the division of available values in order that rarity weights of all items within a table fall between zero and one and amount to one. Normalization occurs when at least one of the rarity weights is not present within a `DropTable`

or `MissionDeck`

.

**Exercise 1**. This exercise demonstrates the normalization procedure with a test case of 1 COMMON, 1 UNCOMMON, 1 RARE, and 0 LEGENDARY items. The value of any rarity weight that does not exist within a table is zero.

Rarity | Weight | Normalization Procedure | Count | Quotient | Drop Chance Per Item |
---|---|---|---|---|---|

COMMON | 0.755 | 0.755 / (0.755 + 0.22 + 0.02) | 1 | 0.75879396984 | 75.88% |

UNCOMMON | 0.22 | 0.22 / (0.755 + 0.22 + 0.02) | 1 | 0.22110552763 | 22.11% |

RARE | 0.02 | 0.02 / (0.755 + 0.22 + 0.02) | 1 | 0.02010050251 | 2.01% |

LEGENDARY | 0 | 0 / (0.755 + 0.22 + 0.02) | 0 | 0 | 0.00% |

Attenuation is a variable exclusive to `DropTables`

. The boolean variable `OverrideLevelAdjustedBiasAtten`

determines whether attenuation is present within a `DropTable`

or not. Attenuation is defined as "the reduction of the force, effect, or value of something." As the value of attenuation increases, the drop chance of the item it impacts *should* decrease. However, due to the insignificance of its set value (0.5) and the fact that it impacts `DropTables`

globally rather than individually across items, it is impossible to determine if it has a noticeable effect at all.

Bias is a variable exclusive to `DropTables`

. Bias is applied to individual items within `DropTables`

. Bias is defined as "a feature of a statistical technique or of its results whereby the expected value of the results differs from the true underlying quantitative parameter being estimated." The intended purpose of bias is to unequally weigh items within `DropTables`

(through a positive (+) or negative (−) value change), even if said items have identical rarity weights. In Warframe, as the value of bias increases, the drop chance of an item decreases. Additionally, because bias scales from the rarity weight that the item it is impacting is assigned to, items with rarity weights of a higher value will be reduced more drastically, depending on the amount of bias which is present. This is evident from the following tables:

Specter | Mod | Drop Chance | Bias | Count | Observed |
---|---|---|---|---|---|

Feyarch Specter | Shotgun Amp | 45.83% | 0.05 | 22 | 52.38% |

Feyarch Specter | Empowered Blades | 4.17% | 0 | 3 | 7.14% |

Feyarch Specter | Final Harbinger | 45.83% | 0.1 | 14 | 33.33% |

Feyarch Specter | High Noon | 4.17% | 0 | 3 | 7.14% |

Specter | Mod | Drop Chance | Bias | Count | Observed |
---|---|---|---|---|---|

Knave Specter | Pistol Amp | 45.83% | 0.05 | 60 | 53.57% |

Knave Specter | Growing Power | 4.17% | 0 | 4 | 3.57% |

Knave Specter | Blind Justice | 45.83% | 0.1 | 43 | 38.39% |

Knave Specter | Crimson Dervish | 4.17% | 0 | 5 | 4.46% |

Specter | Mod | Drop Chance | Bias | Count | Observed |
---|---|---|---|---|---|

Orphid Specter | Stand United | 30.56% | 0.05 | 29 | 27.62% |

Orphid Specter | Brief Respite | 30.56% | 0 | 51 | 48.57% |

Orphid Specter | Atlantis Vulcan | 30.56% | 0.1 | 17 | 16.19% |

Orphid Specter | Crossing Snakes | 8.33% | 0 | 8 | 7.62% |

`rewardSeed`

is a variable exclusive to `MissionDecks`

, and its function is to determine the `missionReward`

players receive at the end of a mission. `rewardSeeds`

are given to the host, and members of the host’s group receive the `sessionId`

in order to participate in the same session. You will only receive a `rewardSeed`

when your client needs to distribute it to players in a group (as the host). This means that you will receive a `rewardSeed`

if you begin a Public, Friends Only, or Invite Only session. But if you begin a Solo session, then you will not be given a `rewardSeed`

. Despite the `SRand`

variable (the seeding for the random number generator which generates a pseudo-random integer between 0 and RAND_MAX) being different for each player, each player will always receive the same `missionReward`

as the host because of their identical `sessionIds`

.

This generates text simulations of an integer seeded by an SRand variable based upon time. The following is my implementation in C:

```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main ()
{
int n = 0;
printf ("NULL SRand:\t %d\n", rand ());
srand (time (0));
for (n = 0; n <= 5; n++)
{
printf ("SRand seeded with:\t %d\n", rand ());
}
return 0;
}
```

This generates text simulations of weighted random number generation based upon one million instances. Initial values are set such that it emulates the Warframe random number generation algorithm. The following is my implementation in PHP:

```
<?php
function WarframeRNG() {
$Uncommon = 0.22 * 1000;
$Rare = 0.02 * 1000;
$Legendary = 0.005 * 1000;
$RarityClass = array();
for ($i = 0; $i <= 1000; $i++) {
if ($i <= $Legendary) {
$RarityClass[$i] = "LEGENDARY";
} else if ($i <= $Legendary + $Rare) {
$RarityClass[$i] = "RARE";
} else if ($i <= $Legendary + $Rare + $Uncommon) {
$RarityClass[$i] = "UNCOMMON";
} else {
$RarityClass[$i] = "COMMON";
}
}
$Rarity = mt_rand(1, 1000);
return ($RarityClass);
}
$RarityArray = WarframeRNG();
$i = 0;
$CommonDrop = 0;
$UncommonDrop = 0;
$RareDrop = 0;
$LegendaryDrop = 0;
$times_to_run = 1000000;
$array = array();
while ($i++ < $times_to_run) {
$RarityClass = $RarityArray[mt_rand(1, 1000)];
if ($RarityClass == "COMMON") {
$CommonDrop = $CommonDrop + 1;
} else if ($RarityClass == "UNCOMMON") {
$UncommonDrop = $UncommonDrop + 1;
} else if ($RarityClass == "RARE") {
$RareDrop = $RareDrop + 1;
} else if ($RarityClass == "LEGENDARY") {
$LegendaryDrop = $LegendaryDrop + 1;
}
}
echo "COMMON: " . $CommonDrop . ", ";
echo "UNCOMMON: " . $UncommonDrop . ", ";
echo "RARE: " . $RareDrop . ", ";
echo "LEGENDARY: " . $LegendaryDrop;
?>
```

Copyright © Jordan Navarro. All rights reserved.