Artifact generation - what exactly do you care about?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Magnate
    Angband Devteam member
    • May 2007
    • 5110

    Artifact generation - what exactly do you care about?

    With many thanks to Derakon for his unfailing patience, I've done a lot of work on item generation in Pyrel. I've written a fairly detailed description of how it works on the Pyrel wiki.

    We have a choice to make about artifact generation. The way I've written it is the way it's done in v4, where every time an item is generated we do a single random check against what we now call artifactChance. If that chance is passed, you're guaranteed to get an artifact (if any are legal for your depth and not yet generated). If it's not, you get a normal item (which could then be magical or ego etc.). In v4, this chance is 1/400 for 'normal' drops, 1/50 for 'good' drops and 1/15 for 'great' drops. In Pyrel you can set it to whatever you want using the new loot system. If you so desire, you can set it differently for each monster.

    Derakon had envisaged a completely different way of doing this, which is to put artifacts and base items together in a single allocation table. Obviously the artifacts would have much lower commonness than normal items. If you get a normal item it is still checked for affixes and themes (magic, ego etc.) in the normal way.

    Both will work, and there would be no difference at all to the player. Sometimes you get an artifact, most times you don't.

    The difference is in how devs and source-divers and other numerate players understand the probabilities. The second method allows you to say, unequivocally, that The One Ring is X times rarer than a dagger (though that dagger could be plain +0,+0 or an awesome Holy Avenger with extra dice). X is simply the ratio of the One Ring's commonness against the dagger's commonness. The same comparison can be made between any artifact and any base item.

    The first method doesn't allow us to do that easily. We can still do it using monte carlo simulations, but that isn't the same degree of certainty at all. But what the first method does allow us to do is know exactly what the likelihood is of generating *an* artifact. The second method obfuscates this - you can calculate it (sum of artifact commonnesses / sum of all commonnesses) but it's not readily available, and will differ for each allocation table.

    Does anyone else have a view on whether either of these is important? Are there any other reasons for choosing one method over the other? Is this all a monstrously abstruse waste of everybody's time?

    (N.B. Both methods allow fine-tuning of *relative* artifact rarities, so I haven't mentioned this. You can tweak how often Nimthanc appears relative to Soulkeeper in both cases. The difference is about how we manage artifact rarity relative to non-artifacts.)
    "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles
  • hyperdex
    Scout
    • Nov 2012
    • 44

    #2
    I don't see why you couldn't have the best of both worlds...

    I believe the 3.4.1 codebase uses some sort of 'commonness' value, where if the commonness of a dagger is 30 and of a blade of chaos is 1, then a dagger is 30 times more common than a blade of chaos. If I am wrong, ignore the rest of my message. ;-)

    Let the sum of the commonesses of objects be O and let the sum of commonnesses of artifacts be A. If we want there to be exactly a 1/400 chance of generating an artifact, we could scale all of the object commonnesses by (399*A)/O and then do a object generation as Derakon suggests. This would lead to artifacts being generated 1/400 of the time, and in addition we can easily calculate the relative rarity of any two objects or artifacts.

    How do you intend to handle this on a level by level basis? Would you basically have 101 allocation tables with commonnesses of every object/artifact on a level by level basis?

    Dave

    Comment

    • Magnate
      Angband Devteam member
      • May 2007
      • 5110

      #3
      Originally posted by hyperdex
      I don't see why you couldn't have the best of both worlds...

      I believe the 3.4.1 codebase uses some sort of 'commonness' value, where if the commonness of a dagger is 30 and of a blade of chaos is 1, then a dagger is 30 times more common than a blade of chaos. If I am wrong, ignore the rest of my message. ;-)

      Let the sum of the commonesses of objects be O and let the sum of commonnesses of artifacts be A. If we want there to be exactly a 1/400 chance of generating an artifact, we could scale all of the object commonnesses by (399*A)/O and then do a object generation as Derakon suggests. This would lead to artifacts being generated 1/400 of the time, and in addition we can easily calculate the relative rarity of any two objects or artifacts.
      I'm not sure you can, because surely multiplying one set of commonnesses by a scalar necessarily breaks the ability to compare artifact commonness directly with base object commonness. I think your suggestion amounts to a way of implementing artifactChance in a single allocation table - interesting and not to be sneezed at, but not, I think, the best of both worlds.
      How do you intend to handle this on a level by level basis? Would you basically have 101 allocation tables with commonnesses of every object/artifact on a level by level basis?
      Essentially yes - this is how it's been done in V since 3.something, and how it will work in pyrel. There'll be an allocation table for objects at each generation level. More than one, in fact, because some will have filters in (e.g. the allocation table for monsters who can only drop spellbooks).
      "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles

      Comment

      • Derakon
        Prophet
        • Dec 2009
        • 9022

        #4
        If you do want to have artifacts be "special" somehow (in terms of allocation), my suggestion for how to do this would be to have a proc attached to the LootTemplate that scales objects' commonness values. So you'd have a SetArtifactChance proc in the LootTemplate that would be handed an ItemAllocator and would then modify the table in the allocator so that the chance of generating an artifact would be the desired value.

        This would, yes, break the ability to say "this artifact is always X times less common than this non-artifact". And I don't think it's necessary. But if we wanted to do it, that's how I'd suggest it be done.

        Comment

        • hyperdex
          Scout
          • Nov 2012
          • 44

          #5
          OK -- since we are constructing a set of allocation tables, there is no reason that the scaled values stored in these tables can't be precomputed.

          Define A and O as before. Scale all objects by 399A, and all artifacts by O (for a normal drop). These scaled values are what is stored in the allocation tables. As before, the chance of an artifact is exactly 1/400, and these scaled values are directly proportional to the probability of those objects being generated and hence can be directly compared. These tables could be generated every time the lib/edit files were modified and stored as a human readable data file.

          As an aside, how do people access the data in Derakon's allocation table now? Is it stored in a source file or in a generated data file? The answer to that may change my answer as to how to do this combining both approaches.

          Comment

          • Derakon
            Prophet
            • Dec 2009
            • 9022

            #6
            Originally posted by hyperdex
            As an aside, how do people access the data in Derakon's allocation table now? Is it stored in a source file or in a generated data file? The answer to that may change my answer as to how to do this combining both approaches.
            Currently the table is not directly accessible; it is always recomputed at runtime (indeed, every time a new ItemAllocator is needed). Seeing as we may need many subtly different allocators (e.g. if you want an orc-themed allocator then there's no point in including spellbooks in the table), I see little point in precompiling the tables and storing them somewhere. At most a cache might come in handy so we can avoid generating identical Allocators over and over.

            Comment

            • fizzix
              Prophet
              • Aug 2009
              • 3025

              #7
              I prefer the first method, and it's probably likely due to conversations we've had in the past. I'll provide my reasoning.

              The second method is based off of the idea that the artifact is a more powerful version of a specific weapon type. Therefore, it makes intuitive sense to tie the artifact generation chance to the generation chance of that object type. The first method separates artifacts altogether. The implication is that an artifact is more than just a more powerful version of a weapon. The reason I think this is the way to go is because artifacts have a much broader range of skills than normal ego items. They can also have varying physical traits like weights or base values. So when it comes to comparing them to the base items, the artifacts often have no gameplay relation to the base item besides the name.

              Lastly, from a tweaking perspective, I think it's easier if we always make the check for the most powerful/rarest occurrence first and then work our way down to the more common and weaker options.

              Comment

              • hyperdex
                Scout
                • Nov 2012
                • 44

                #8
                In that case, I don't see what's wrong with my suggestion (admittedly this could be temporary blindness on my part...)

                For a given ItemAllocator (i.e. level 50, normal drop) we can calculate O and A at runtime and then scale all objects by 399A and all artifacts by O. These scaled values are used to generate the object. Artifacts have exactly a 1/400 chance of being generated, and the scaled values can be compared directly if one wants to compare relative rarities. It works just as well as it works now, with the additional benefit that we can directly control artifact frequency.

                After thinking about this a little more, I believe that the distribution of drops produced by an allocation table generated in this way is equal to the distribution of drops generated by Magnate's algorithm. It really does encompass both techniques.
                Last edited by hyperdex; December 21, 2012, 01:31.

                Comment

                • Derakon
                  Prophet
                  • Dec 2009
                  • 9022

                  #9
                  Originally posted by fizzix
                  The second method is based off of the idea that the artifact is a more powerful version of a specific weapon type. Therefore, it makes intuitive sense to tie the artifact generation chance to the generation chance of that object type. The first method separates artifacts altogether.
                  This isn't actually how the "lump artifacts into the table with everything else" method (the "second method" you refer to, I believe) would work. Pseudocode time.
                  Code:
                  Method 1: explicit artifact check.
                  
                  if 1 in (artifact chance): 
                      generate artifact table
                      try to select item from artifact table
                      if selection succeeds:
                          return artifact
                      otherwise continue as normal
                  generate table of all non-artifact items
                  select item from table
                  Code:
                  Method 2: artifacts in with everything else
                  
                  generate table of all items (including not-yet-generated artifacts)
                  select item from table
                  In the second method, you'd get tables that look something like the following:
                  Code:
                  Entries        item
                  0-40           Dagger
                  40-80          Potion of Cure Light Wounds
                  ...
                  1000-1010      Blade of Chaos
                  1010-1020      Potion of Strength
                  ...
                  10000-10000.1  Narthanc
                  ...
                  50000-50000.0001  The One Ring
                  I don't understand your "from a tweaking perspective" comment. Isn't it easiest from a tweaking perspective to be able to regulate the relative rarity of any item to any other item? The easiest way to accomplish that is to shove everything into the same table.

                  Comment

                  • fizzix
                    Prophet
                    • Aug 2009
                    • 3025

                    #10
                    Originally posted by Derakon
                    "from a tweaking perspective" comment. Isn't it easiest from a tweaking perspective to be able to regulate the relative rarity of any item to any other item? The easiest way to accomplish that is to shove everything into the same table.
                    The way I'm thinking, in the second method the artifact drop chance is dependent on one more thing than the first, the chances of the drop rates of all the other items. I would almost go farther and only allow artifact creation at level generation, but I think this would lead to too much predictability from the player's perspective.

                    Also, my brain is at something like 30% now, so it's possible that I'm blabbing with little actual reasonableness.

                    Comment

                    • Derakon
                      Prophet
                      • Dec 2009
                      • 9022

                      #11
                      Originally posted by fizzix
                      The way I'm thinking, in the second method the artifact drop chance is dependent on one more thing than the first, the chances of the drop rates of all the other items.
                      I think this isn't true (that the second method has more confounding factors than the first), even if all you care about is if any artifact is generated. Remember that artifact generation can fail due to a lack of valid candidates -- for example, if the game tries to make an artifact on level 1 I doubt it would succeed, as even the *thancs* and Paur*s would be invalid. Thus the first method has secondary factors making it hard to predict artifact generation as well. And of course if you care about a specific artifact being generated then that gets rather complicated very quickly.

                      Also, my brain is at something like 30% now, so it's possible that I'm blabbing with little actual reasonableness.
                      I'm well familiar with that problem myself, so I wish you all the best. It seems like each holiday season is busier than the last one, somehow.

                      Comment

                      • Estie
                        Veteran
                        • Apr 2008
                        • 2347

                        #12
                        What happens if we introduce themed objects; for example, call all blessed weapons, holy avengers and apropriate artifacts "holy". Now if we, say, want to give priests/priest pits a higher chance to drop a "holy" item than normal, which of the 2 suggested methods would make that easier ?

                        Comment

                        • Magnate
                          Angband Devteam member
                          • May 2007
                          • 5110

                          #13
                          Originally posted by Estie
                          What happens if we introduce themed objects; for example, call all blessed weapons, holy avengers and apropriate artifacts "holy". Now if we, say, want to give priests/priest pits a higher chance to drop a "holy" item than normal, which of the 2 suggested methods would make that easier ?
                          I've spent weeks creating the most flexible system I possibly could, and within half a day somebody comes up with something I hadn't thought of.

                          At the moment you can specify a 'holy' loot template that includes blessed/pious items, HAs and the like. We can give priest-type monsters a chance of dropping an item from that template instead of (or as well as) a normal drop. That meets your suggestion except for one detail: there's currently no way of increasing the commonness of a specific artifact. So the answer to your question is that neither makes any odds.

                          Ho hum. It seems a niche case but I'll think about it. I don't think, even if it's implementable, that it would make any difference which artifact generation method is used.

                          Thanks for the debate folks - it's Derakon's baby so I went and re-did it Derakon's way. I like the idea of using hyperdex's idea to get the best of both worlds. If I understand correctly it will be quite simple: if artifactChance is an absolute percentage, we multiply all non-artifact commonnesses by (100 / artifactChance - 1) * sum(artifact commonnesses) and multiply all artifact commonnesses by sum(nonartifact commonnesses). That should be doable. Derakon - would that be acceptable to you? Fizzix and I would like it!
                          "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles

                          Comment

                          • Derakon
                            Prophet
                            • Dec 2009
                            • 9022

                            #14
                            Originally posted by Magnate
                            I like the idea of using hyperdex's idea to get the best of both worlds. If I understand correctly it will be quite simple: if artifactChance is an absolute percentage, we multiply all non-artifact commonnesses by (100 / artifactChance - 1) * sum(artifact commonnesses) and multiply all artifact commonnesses by sum(nonartifact commonnesses). That should be doable. Derakon - would that be acceptable to you? Fizzix and I would like it!
                            I'm fine with this but would prefer it be handled in a proc instead of in the game engine directly. I feel rather strongly that the engine should not need to know that artifacts exist (much as it has no clue about unique monsters). Proc-izing loot templates would also enable the "holy items" template that Estie suggested.

                            To go into more detail, we'd add a mapping of proc triggers to Proc instances to the LootTemplate class. In the construction of the ItemAllocator's item table, we would have the following triggers:

                            * allocation table creation: this is where we prevent already-generated artifacts from being regenerated.
                            * allocation table selection: this is where we prevent an artifact from being selected twice (when re-using Allocators).
                            * allocation table scaling: this proc would accept the entire table as an argument and would re-scale it based on the items in it (so that e.g. if you want a table that is merely biased towards, say, spellbooks while still allowing other items, you could just multiply their commonnesses; you could also implement artifactChance here).

                            At appropriate points in the generation of the ItemAllocator, we would check the LootTemplate for these triggers and call them if they exist.

                            "allocation table creation" is also where we would implement smart item filters that can't be handled by the normal LootTemplate. This is where you'd handle the "holy" template's more tricky bits.

                            We might also want to have a proc trigger that fires immediately before the item would normally be generated and would have some final veto power (forcing the entire generation process to try again). I don't know if that's actually needed but I could believe it'd come in handy.

                            Comment

                            • fizzix
                              Prophet
                              • Aug 2009
                              • 3025

                              #15
                              Allowing the game to specify drops based on the player's class is something we should definitely support. How hard is that to do?

                              Comment

                              Working...
                              😀
                              😂
                              🥰
                              😘
                              🤢
                              😎
                              😞
                              😡
                              👍
                              👎