Home » , , , , » Possible Cause of Bad Ammo Drops in Destiny

Possible Cause of Bad Ammo Drops in Destiny

So are you wondering why the "increase drop rate" of ammo still sucks in Destiny? Programmer PotaToss might have figured out the reason of such bad ammo drops in the game. But before going to the details, check out the image below on how bad the ammo drops at the moment for Destiny:


How RNG Normally Works

Programming languages usually have some core library and functions that will generate a basic series of random numbers when called repeatedly. In Python, for example, it's random.random().

Sometimes you can provide a seed to the random number generator that will determine what series of random numbers it generates. A common practice is to use the system's current time, so you know you're getting a different series from one execution to the next.

When you have the same seed, though, you'll get a repeatable series of random numbers. This can be useful in something like a networked puzzle game, like Tetris, where you want to make sure that both players are getting the same sequence of pieces, so it's a fair game. So you'd only need to send the same seed value to both game clients, once, at game start, instead of having to constantly ping the server for what the next piece should be.

The normal flow is to seed the RNG, then make a bunch of calls of something like random.random() to keep getting new random numbers.
So, normal execution (in Python):
>>> random.seed(1)
>>> random.random()
0.13436424411240122
>>> random.random()
0.8474337369372327
>>> random.random()
0.763774618976614
How RNG Goes Wrong

If you're not careful, and call your seed function in the wrong place, you'll reset the sequence, and get repeated values that you probably don't want.
>>> random.seed(1)
>>> random.random()
0.13436424411240122
>>> random.seed(1)
>>> random.random()
0.13436424411240122
>>> random.seed(1)
>>> random.random()
0.13436424411240122
This is easy to do in a loop.
This Python code will print a series of 5 random numbers:
time = datetime.datetime.now()
random.seed(time) # This happens once. 
for i in range(0, 5):
  print(random.random())
Output:
0.369421685101
0.506646230633
0.0899291705232
0.585978121162
0.43615844392
This Python code will print one random number, 5 times:
time = datetime.datetime.now() 
for i in range(0, 5):
  random.seed(time) # This happens 5 times.
  print(random.random())
Output:
0.591797745488
0.591797745488
0.591797745488
0.591797745488
0.591797745488
The only difference is where random.seed(time) was placed.

Here's a simple Python program that simulates creating ammo drops, tallying the number of drops for each type, with 40% chance of primary drop, 20% of special, and 10% of heavy (Feel free to skip reading the code entirely if you're not a programmer):
import datetime
import random 
ammo_drop_chances = {
    'primary': 0.40,
    'special': 0.20,
    'heavy': 0.10
}
def calculate_drop(rand, probability):
    if(rand <= probability):
        return 1
    return 0
def dict_add(dict1, dict2):
    return {k: dict1[k] + dict2[k] for k in dict1}
def seed_properly(count, drop_chances):
    drop_totals = { k: 0 for k in drop_chances }
    time = datetime.datetime.now()
    random.seed(time)
    for i in range(0, count):
        new_drop = {k: calculate_drop(random.random(), v) for k, v in drop_chances.items()}
        drop_totals = dict_add(drop_totals, new_drop)
    return drop_totals
def seed_in_loop(count, drop_chances):
    drop_totals = { k: 0 for k in drop_chances }
    time = datetime.datetime.now()
    for i in range(0, count):
        random.seed(time)
        new_drop = {k: calculate_drop(random.random(), v) for k, v in drop_chances.items()}
        drop_totals = dict_add(drop_totals, new_drop)
    return drop_totals

trials = 10000 
proper_ammo_drops = seed_properly(trials, ammo_drop_chances)
bugged_ammo_drops = seed_in_loop(trials, ammo_drop_chances) 
print "proper:", proper_ammo_drops
print "bugged:", bugged_ammo_drops
Here, the functions seed_properly and seed_in_loop are identical except for where random.seed(time) is called, as before.

Here's the output on 5 consecutive runs:
proper: {'heavy': 982, 'primary': 4070, 'special': 2030}
bugged: {'heavy': 0, 'primary': 0, 'special': 0} 
proper: {'heavy': 991, 'primary': 3959, 'special': 2026}
bugged: {'heavy': 0, 'primary': 10000, 'special': 0} 
proper: {'heavy': 1028, 'primary': 4005, 'special': 2010}
bugged: {'heavy': 0, 'primary': 10000, 'special': 0} 
proper: {'heavy': 985, 'primary': 3997, 'special': 2054}
bugged: {'heavy': 0, 'primary': 0, 'special': 10000} 
proper: {'heavy': 1012, 'primary': 3997, 'special': 1999}
bugged: {'heavy': 10000, 'primary': 0, 'special': 0}
For the proper seeding cases, for 10,000 total drop chances, the numbers are where you'd expect them for the intended probabilities. About 1,000 heavy. About 4,000 primary. About 2,000 special.

For the case where the RNG is seeded inside the loop, the numbers are totally all or nothing. It's the same random numbers repeated 10,000 times.

Conclusion

Let's look back at that Nova Bomb.

The player is wearing a ghost that gives him 3 glimmer for each thrall he kill. You can see that he get 21 glimmer, so he killed 7 thrall, and he got 6 heavy ammo bricks.


If you slow it down, you can see that the player got the same damage value of 1,772 for 6 of the thrall, in the center of the blast:


The possible reason behind this is when the game engine processes an animation frame, a given damage collider will have a queue of things it's colliding with, and it loops through the queue, reseeding the RNG inside of the loop, so that when a bunch of enemies die from the same collision, like a big explosion, they all drop the same ammo, and we don't get the intended distribution. Destiny is a game with a lot of big explosions, so this happens a lot, and you end up with a lot of one type of ammo, and not enough of the others.

In the case of this Nova Bomb, the 7th thrall died from splash, which is probably handled separately, or it died in a different frame or something.

The ammo drop behavior seems fairly consistently all or nothing. Test it yourself. Wake the hive. Blow them up all at once. Count the boxes.

For more Destiny news and tips, come and join our facebook gaming community @ facebook.com/webjunkiesblog.

Source: Reddit