0
\$\begingroup\$

I am developing an RPG that will be played in the browser, so far the development is going very well. However, I reached a point in the project where I'm "stuck" because I can't find a good solution. My game players will duel against monsters, when defeating a monster needs to drop the items, in this scenario an example would be.

Monster A has a chance to drop the items:

  • 5% sword
  • Gold (between 2 and 5 gold)
  • 35% potion (Hp or Mp)

Currently I put it to generate a random number, for example, rand(0, 100), the problem is that there are millions of failures, the first is that sometimes the player gets the sword 2 times in a row because I'm generating the random number and I'm comparing whether it is greater or less than the defined %.

I would like to know if there is a better way to do this control and how it could be done.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Given how propbabilities work, and specifying a drop rate and generating a random number the way you do results in exacly that: there is a chance you get the item twice in a row, or not having the item drop for a long time. An option to have a finer control over the drop is to reduce the rate once it has dropped, and increase the rate progressively over time or in function of how many time the enemy has been defeated. \$\endgroup\$
    – Vaillancourt
    Dec 27, 2021 at 20:04
  • \$\begingroup\$ Consider this, though: if "sword" drops, and there is no concept of durability, and there are no random properties associated with the object (so if every sword that is dropped from that monster is exactly equivalent), there appears to be no need for it to drop more than once. \$\endgroup\$
    – Vaillancourt
    Dec 27, 2021 at 20:05
  • 1
    \$\begingroup\$ There are many ways to shape random drops to achieve desired outcomes. In order to help you achieve yours, we're going to need more details about what specific outcomes are desirable for your game. Try walking us through some scenarios, two players each battling a dozen monsters and getting some set of drops - one that you'd consider a "good" experience that your generator should tend to reproduce, and one you consider "bad" or a scenario your random generator should avoid. That can help you isolate what behaviours you want your custom random generator to have. \$\endgroup\$
    – DMGregory
    Dec 27, 2021 at 20:29
  • \$\begingroup\$ @DMGregory, thanks for answers. Currently I have not developed the scenario, however I have already designed the way it will be, an example will be the Final Fantasy game, you fight the matches and in the end you receive the items, basically it will be the same, what I got "stuck" was in the stage that is the way I'm going to calculate the drops, I started doing superficial tests and the situations that I commented on in the post started to happen. \$\endgroup\$
    – Crazy
    Dec 28, 2021 at 8:37
  • \$\begingroup\$ Related: gamedev.stackexchange.com/q/162976/41345 \$\endgroup\$
    – Evorlor
    Dec 30, 2021 at 1:41

1 Answer 1

1
\$\begingroup\$

Try randomly checking "will this item drop?" for every item. You could store the information for item and drop chance as pairs in a list:

drops = [["sword",5],["hp_potion",35],["mp_potion",35]]
loot = []
for i in drops:
    if random_chance(i[1]):
        loot.append(i[2])
give_player_loot()

...but this does not account for quantity, and maybe you'd like to prevent one item from dropping if another does. My solution for this would be nesting lists even further, with an item name, chance, and min/max quantity going in list A. List A is put within pool B, within the drops variable, C.

So, this would look something like:

# SLOW BUT EASY WAY TO BUILD LOOT TABLE
# You do this when the monster is created, if you are keeping a list of monsters
# that is made at the start of the game, this is also where you'd put this.
# this example loot pool has a 35% chance to drop 1-3 HP potions, OR, failing
# that, a 35% chance to drop 1-2 MP potions.
A = ["hp_potion",35,1,3] # individual item drop chance
A2 = ["mp_potion",35,1,2] # another one, to help describe the concept.
B = [A,A2] # the loot, A and A2 is going into pool B.
C = [B] # B goes into the final drop pool
monster_drops = C
# COMPACT WAY:
monster_drops = [[["hp_potion",35,1,3],["mp_potion",35,1,2]]]

Next, we have to iterate between all drops like so:

loot = []
for i in monster_drops: # go through all pools
    for j in i: # go through all items
        if random_chance(j[1]):
            loot += [j[0]]*random_range(j[2],j[3]) # add this item to the loot,
                                                   # multiplied by the number of
                                                   # items it should drop.
            break # exit the loop
give_player_loot(loot)

Sorry for the poor formatting, it's based on python and I don't really know how to use StackExchange, but I hope this was helpful! (Also, I noticed you are using JS, but hopefully the same concepts apply there!)

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for answers. I've been testing what you went through and I still have some doubts about how it would work in practice. Example, there are some methods that you put as "random_chance"/"random_range" what would this method be? What does he return? I've been testing the code in a pyton compiler but it gave an error. \$\endgroup\$
    – Crazy
    Dec 28, 2021 at 8:44
  • \$\begingroup\$ "But it gave an error" should always be followed by the full and complete text of the error. Folks don't write error messages just for amusement - they do it because the text actually gives you clues about what went wrong and why (and consequently, how to fix it). \$\endgroup\$
    – DMGregory
    Dec 28, 2021 at 19:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .