Artifact generation - what exactly do you care about?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Derakon
    Prophet
    • Dec 2009
    • 9022

    #16
    Originally posted by fizzix
    Allowing the game to specify drops based on the player's class is something we should definitely support. How hard is that to do?
    First thought on how you'd do this: make a LootTemplate that accepts everything that any class cares about, with an "allocation table creation" proc that then filters things down based on the player's class. That proc would probably be pretty messy (though there's nothing preventing procs from having their own data files that they load when needed!), but it'd get the job done.

    Presumably this would be for generating class-appropriate rewards for performing certain deeds?

    Comment

    • fizzix
      Prophet
      • Aug 2009
      • 3025

      #17
      Originally posted by Derakon
      Presumably this would be for generating class-appropriate rewards for performing certain deeds?
      In general you might want it. For example, you can imagine someone wanting to drop a prayer book if the character is a priest, a magic book if it's a mage, and a weapon if it's a warrior. Angband, and most games, are ok with dropping items that certain classes can't use. But you can imagine that a game designer might want to eliminate all unusable items.

      Comment

      • Magnate
        Angband Devteam member
        • May 2007
        • 5110

        #18
        Originally posted by fizzix
        In general you might want it. For example, you can imagine someone wanting to drop a prayer book if the character is a priest, a magic book if it's a mage, and a weapon if it's a warrior. Angband, and most games, are ok with dropping items that certain classes can't use. But you can imagine that a game designer might want to eliminate all unusable items.
        Surely the easiest way of doing this is to have a loot template for each class, containing just the interesting stuff. You could even have a series of them "priest great", "priest good", "priest meh" type of thing.
        "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles

        Comment

        • Magnate
          Angband Devteam member
          • May 2007
          • 5110

          #19
          Originally posted by Derakon
          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).
          I'm sure that when I understand procs properly and can write and amend them with ease, I'll never look back.

          But in the meantime, why is it important that the engine should not know that artifacts exist? It knows about affixes and themes, so why not artifacts? Or would you ultimately like affix and theme application to be done by procs too?

          One particular reason for this question is about item naming. Artifact rings and amulets don't follow the same naming conventions as non-artifacts, and I'm struggling to see how to name things properly if the game must remain ignorant of artifact-ness. I can think of lots and lots of ways of sorting out item naming to be consistent, but every single one requires that the game have an "isArtifact" test. I'm guessing the solution is a proc ? :-)

          Another thing that I think is causing me difficulties is how often a proc is used. Isn't the whole point of procs to trigger stuff under specific circumstances, like an item effect? So to use a proc to implement artifactChance, *every* time we create an allocation table, seems like it must be the wrong method.
          Last edited by Magnate; December 21, 2012, 14:41.
          "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles

          Comment

          • buzzkill
            Prophet
            • May 2008
            • 2939

            #20
            Originally posted by fizzix
            ... an artifact is more than just a more powerful version of a weapon.
            I agree with this. I don't see any reason to tie artifact generation chance to base item generation.
            www.mediafire.com/buzzkill - Get your 32x32 tiles here. UT32 now compatible Ironband and Quickband 9/6/2012.
            My banding life on Buzzkill's ladder.

            Comment

            • Derakon
              Prophet
              • Dec 2009
              • 9022

              #21
              Originally posted by Magnate
              But in the meantime, why is it important that the engine should not know that artifacts exist? It knows about affixes and themes, so why not artifacts? Or would you ultimately like affix and theme application to be done by procs too?
              Theoretically we could move those into procs as well, though it'd probably be more complicated.

              The main reason why the engine shouldn't have to know about artifacts is because it doesn't have to know about artifacts. In other words, as long as I can envision a reasonable way to do things such that the engine doesn't have to care about them, I would prefer they be done that way. Keep the engine simple and flexible; move the complexity into the procs (which perhaps ought to be renamed to "game scripts" at this point).

              One particular reason for this question is about item naming. Artifact rings and amulets don't follow the same naming conventions as non-artifacts, and I'm struggling to see how to name things properly if the game must remain ignorant of artifact-ness. I can think of lots and lots of ways of sorting out item naming to be consistent, but every single one requires that the game have an "isArtifact" test. I'm guessing the solution is a proc ? :-)
              Yep! A proc that generates the name for the item is the solution here, with the fallback method being to use util.getGrammaticalName().

              Another thing that I think is causing me difficulties is how often a proc is used. Isn't the whole point of procs to trigger stuff under specific circumstances, like an item effect? So to use a proc to implement artifactChance, *every* time we create an allocation table, seems like it must be the wrong method.
              Why must that be wrong? Just because a proc only triggers under specific circumstances doesn't mean that those circumstances can't come up all the time. And remember, the LootTemplate that the proc is attached to is already modifying that allocation table; just think of the proc as being able to do modifications that are more flexible than the LootTemplate was originally written to handle.

              Originally posted by buzzkill
              I agree with this. I don't see any reason to tie artifact generation chance to base item generation.
              I don't think that either of the proposed generation methods tied artifact generation to base item generation. We're well passed the days when the game would generate a base item, then try to turn that item into an artifact (so that e.g. to get Ringil you'd first have to get the game to generate a longsword). The only way in which artifact generation is "tied" to base item generation is in that they're in the same allocation table, so making one more likely makes the other less likely.

              Comment

              • Magnate
                Angband Devteam member
                • May 2007
                • 5110

                #22
                Originally posted by Derakon
                Theoretically we could move those into procs as well, though it'd probably be more complicated.

                The main reason why the engine shouldn't have to know about artifacts is because it doesn't have to know about artifacts. In other words, as long as I can envision a reasonable way to do things such that the engine doesn't have to care about them, I would prefer they be done that way. Keep the engine simple and flexible; move the complexity into the procs (which perhaps ought to be renamed to "game scripts" at this point).
                Ok. I'm sorry to show such ignorance about this, it's not something I've ever come across in my limited coding experience. Once I get comfortable with procs, I'll happily use them wherever they make sense - including affixes and themes, if that's worth the trouble.
                Why must that be wrong? Just because a proc only triggers under specific circumstances doesn't mean that those circumstances can't come up all the time. And remember, the LootTemplate that the proc is attached to is already modifying that allocation table; just think of the proc as being able to do modifications that are more flexible than the LootTemplate was originally written to handle.
                Well yes, but this begs the question of why have loot templates at all, why not just have an 'on item generation' proc that deals with everything loot templates deal with, so the game just picks an item factory from the table, makes the item and thinks it's done. I'm assuming that at some point doing that becomes more trouble than it's worth, and it bothers me that I can't see a clear line between worthwhile and not. I don't see how looking in every possible container of items every time we want to put an artifact into an allocation table can be a sensible approach, but I guess we have to try it and see.
                I don't think that either of the proposed generation methods tied artifact generation to base item generation. We're well passed the days when the game would generate a base item, then try to turn that item into an artifact (so that e.g. to get Ringil you'd first have to get the game to generate a longsword). The only way in which artifact generation is "tied" to base item generation is in that they're in the same allocation table, so making one more likely makes the other less likely.
                I think fizzix and buzzkill meant something a little different by "tied". If you think of item generation as a decision tree, method #1 was a straight choice between an artifact and a non-artifact as the first decision. Whatever happened afterwards, there was no further connection (tie) between artifacts and non-artifacts.

                Method #2 puts them in the same allocation table and uses the same code to pick from it, so the tree paths don't diverge until all the allocation table creation decisions have been made, and the picking decisions. Only then are the two distinct.

                I think that's what they might have meant, anyway ;-)
                "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles

                Comment

                • hyperdex
                  Scout
                  • Nov 2012
                  • 44

                  #23
                  I've been thinking about this a bit more, and though it's probably not directly useful I have some pseudocode that looks nice and might be useful...

                  Code:
                  import random
                  
                  class AllocationTable(object):
                    def __init__(self, *pairs):
                      self.pairs = pairs
                      self.weight = sum([x[0] for x in pairs])
                  
                    def generate(self):
                      x = random.randint(0, self.weight)
                      for (weight, gen) in self.pairs:
                        x = x - weight
                        if x<0:
                          return gen.generate()
                  
                    def __rmul__(self, c):
                      return AllocationTable((c, self))
                  
                    def __add__(self, other):
                      return AllocationTable(*(self.pairs + other.pairs))
                  
                  
                  class Leaf(AllocationTable):
                    def __init__(self, tval=0, sval=0, e_idx=None, a_idx=None):
                      AllocationTable.__init__(self, (1, self))
                      self.tval = tval
                      self.sval = sval
                      self.e_idx = e_idx
                      self.a_idx = a_idx
                  
                    def generate(self):
                      return (self.tval, self.sval, self.e_idx, self.a_idx)
                  These objects allow us to easily manipulate allocation tables. An allocation table is internally represented as a lit of pairs. The first element of the pair is a weight (commonness) and the second is either a leaf (which generates a given object or artifact) or another allocation table. The __rmul__ and __add__ methods allow us to do things like the following...

                  Code:
                  objects = AllocationTable(*[(X.weight, Leaf(X.tval, X.sval)) for X in OBJECTS])
                  artifacts = AllocationTable(*[(A.weight, Leaf(a_idx=A.idx)] for A in ARTIFACTS])
                  
                  normal = 399*objects + 1*artifacts
                  and this implements Magnate's distribution using a 1/400 chance of generating an artifact. Note that to generate objects with this table, you call normal.generate().

                  Suppose we wanted to implement a distribution where 1/5 of the time you get a book. You could do this:

                  Code:
                  books = AllocationTable(*[(X.weight, Leaf(X.tval, X.sval) for X in OBJECTS if X.tval==90])
                  skewed = 1*books + 4*normal
                  
                  return skewed.generate()
                  it is easy to see how this could be extended further. Note that we still have to account for dungeon level here.

                  Dave

                  Comment

                  • hyperdex
                    Scout
                    • Nov 2012
                    • 44

                    #24
                    On a related note, how are the AllocationTables generated now? As an example, I am looking at 3.4.1's artifact.txt, and I can't really see how the numbers there translate into commonness values...

                    My best guess is that the 'A:' line's first value is used, but the range of this is only 1-50, and that doesn't seem to provide enough of a range. As an example, is it really the case that on dungeon levels 20-100, the Phial is only 40 times more likely to be generated than Ringil? This seems low to me.

                    By the way, RTFS (read the source) is a completely legitimate response to this, though if someone could point me to the right file(s) that would be appreciated. ;-)

                    Comment

                    • Derakon
                      Prophet
                      • Dec 2009
                      • 9022

                      #25
                      Have a link to the current ItemAllocator code. The lines from 35-54 generate the table; 56-65 select an item.

                      Comment

                      • hyperdex
                        Scout
                        • Nov 2012
                        • 44

                        #26
                        Thanks for the link, Derakon. It looks like I was going down the same path that you've already traversed. ;-) The key difference it that my example is more like a tree, where yours is more flat.

                        <Edit: I removed a bug report that turned out to be wrong. I should have tried it out before complaining...>

                        Comment

                        • Derakon
                          Prophet
                          • Dec 2009
                          • 9022

                          #27
                          Yeah, the tree approach is certainly a possibility, and a good way to encode hierarchical loot systems. I feel that trees ought to be declared at the LootTemplate level -- i.e. a LootTemplate that says "20% of the time, pick from this template; 60% of the time pick from this one; the remainder of the time, pick from this third one". That would also handle the "artifactChance" system without needing procs to re-weight every item's commonness: you'd just have a LootTemplate that is "all the artifacts" and another that is "everything else".

                          Comment

                          • Magnate
                            Angband Devteam member
                            • May 2007
                            • 5110

                            #28
                            Originally posted by Derakon
                            Yeah, the tree approach is certainly a possibility, and a good way to encode hierarchical loot systems. I feel that trees ought to be declared at the LootTemplate level -- i.e. a LootTemplate that says "20% of the time, pick from this template; 60% of the time pick from this one; the remainder of the time, pick from this third one".
                            Would you do that during the lootTemplate's constructor, or would you construct all three templates and then choose at item gen time?

                            I think I could probably implement this without too much difficulty.
                            "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

                              #29
                              Originally posted by Magnate
                              Would you do that during the lootTemplate's constructor, or would you construct all three templates and then choose at item gen time?

                              I think I could probably implement this without too much difficulty.
                              During the constructor, I think.

                              Comment

                              • Estie
                                Veteran
                                • Apr 2008
                                • 2347

                                #30
                                Originally posted by buzzkill
                                I agree with this. I don't see any reason to tie artifact generation chance to base item generation.
                                One reason I can see for this is that an artifacts value can be written as sum of base item and additional modifiers. Currently afaik it isnt done that way, but the problems with randomizing Bladeturner in the randart generator could have been avoided if it was.

                                Suppose someone wants (maybe for a mod) reduce the frequency of PDSM drops. If artifact generation isnt tied to base item generation, he probably also has to change the frequency of Bladeturner lest it become more common than the unenchanted base; if the check for artifact is done after the base item is determined, its easier to tune frequencies.

                                Comment

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