Search Unity

Stuck in a logic paradox

Discussion in 'Scripting' started by Josiah_Ironclad, Sep 26, 2019.

  1. Josiah_Ironclad

    Josiah_Ironclad

    Joined:
    Sep 24, 2019
    Posts:
    156
    I've been working on random loot generation these past 2 days, and I've tripped into a bit of a quicksand rabbit hole.

    I currently have 4 ScriptableObjects for my base items. My item script uses those as the base data structure. And my generator script then uses that item script by altering its values, and therefore generating random items.

    Here's the problem. The items have a rarity value which is randomly generated (between 5 different pre-defined rarities). They also have a drop rate value, which is dependant on the rarity. E.g. If an item is Uncommon, the drop rate is 40 (40% chance of drop), if it's Epic it's 10.

    So let's say I click the "generate" button, it instantiates the item, sets its rarity and that in turn sets its drop rate. See the problem? The item already exists in the inventory before I can actually calculate whether it should be created.

    Right now I've been trying to just check a random number value (0-100) against the drop rate, and if it's higher (random number > drop rate), delete the item. But it either causes gaps to form in the inventory if I generate multiple items at a time (since the next item is generated before the previous can be fully removed or something).

    If I made a ScriptableObject for each of the base items' rarity, I'm sure it would work fine. But I'd have 20 ScriptableObjects (and 5 more for each new item I come up with) sitting in my assets folder. So I'll do that as a last resort.

    Does anyone have any suggestions on how to get out of this paradox loop?

    TL;DR: I'm randomly generating items with rarity and drop rates. The drop rates are supposed to determine whether the item gets created (based on a random number), but since the item needs to exist for the drop rates to be used, it creates a logic paradox.
     
    Last edited: Sep 26, 2019
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    I see two general approaches you could take here:

    A) Generate all possible items in advance (don't give them to the player, just store abstract representations of them in computer memory), calculate a drop rate for each of them, and save the results. Then, whenever you need to drop loot, use those drop rates to pick which loot to drop.

    B) When you need to drop loot, first pick how rare you want the loot to be, then constrain your random item generation so that it can only generate items of that rarity.

    Option A works well if you have a relatively small list of possible items (though "relatively small" might be thousands) and you want to have detailed control over each one.

    Option B works well if you want to have a huge variety of algorithmic items by combining modifiers, giving you stuff like the Thundering Spiderweave Mantle of Superior Frigidity.

    If you're using strategy A, then to decide which item to drop you'd do something like:
    1. Assign each item a "weight" representing how like it is to drop
    2. Add up the weights of ALL items that would currently be legal to drop.
    3. Generate a random number between 0 and that total. Call it X
    4. Go through the list one item at a time, each time reducing X by the weight of that item
    5. When X <= 0, spawn that item
    An algorithm following strategy B might go something like:
    1. First decide if the item will be common (55%), magical (30%), rare (10%), or unique (5%)
    2. If it's common, choose from the basic item list and spawn it with no modifiers
    3. If it's magical...
      1. Choose a base item type from either the basic list (70%) or special list (30%)
      2. Choose to give it either a prefix (40%) or a suffix (40%) or both (20%)
      3. If giving it a prefix, choose a random prefix out of all possible prefixes with a power rating that is within +/- 5 points of the player's level and that are flagged as being legal for the chosen base item type
      4. Ditto for suffix
      5. Spawn the item
    4. If it's rare...
      1. Choose a base item type from either the basic list (50%) or special list (50%)
      2. Choose to give it either a prefix (50%) or a suffix (50%)
      3. Then, give it 0, 1, or 2 additional prefixes (50%/35%/15%), and 0, 1, or 2 additional suffixes (50%/35%/15%)
      4. For each prefix/suffix, choose a random modifier out of the list as in the magical case, except that duplicates are NOT allowed
      5. Create a random name for the item (the prefixes and suffixes control what bonuses it gets, but not what it's called)
      6. Spawn the item
    5. If it's unique, choose from the unique item list and spawn it. (All possible unique items are generated in advance by hand.)
    Now, using strategy B means it might be hard to control the exact rarity of a particular item. For instance, the drop rate of the Misty Broadsword of Flame is a combination of a bunch of different variables, including the magical drop rate (30%), the basic-list chance (70%), the number of items on that list, the both-a-prefix-and-a-suffix chance (20%), and the number of possible prefixes and suffixes within the player's level range that are allowed to appear on that item type. Just calculating that may be kind of a pain; controlling it is probably impossible without affecting the drop rates of a bunch of other items at the same time.
     
    Josiah_Ironclad likes this.
  3. Josiah_Ironclad

    Josiah_Ironclad

    Joined:
    Sep 24, 2019
    Posts:
    156
    Wow, thank you so much for going above and beyond with the suggestion. :D
    I'm not as far in the development as creating prefixes and suffixes, but that is definitely on my radar, so this is amazing food for thought for now. I bookmarked this thread and I'll be sure to come back to this post regularly until I figure out which best suits my game.

    Thank you again so much. :)