Loading ...
Sorry, an error occurred while loading the content.

Skill pool and classes

Expand Messages
  • Frugal
    As everytime I try to refactor out some piece of the spagetti code that is PCGen[1] I realise it is a futile effort I returned my attention to the protype that
    Message 1 of 18 , Mar 25, 2004
    • 0 Attachment
      As everytime I try to refactor out some piece of the spagetti code that is
      PCGen[1] I realise it is a futile effort I returned my attention to the
      protype that Steve had built.

      I altered it so that the model was separaetd from the character and
      optimised the variable (ex score) code so that it can do an update that
      trickles down in about 16ms. I also added a couple of small feat entites
      to ensure that it can add and remove an entity and have the effects
      cascade down.

      I then started to figure out how to do classes. As they are the most
      complicated thing I thought they should be donw first to encounter as many
      problems as possible. It also lets me know if the system will work for
      more than the trivial case.

      I can figure out how to do most of the things that a class requires, but I
      am a bit stumped by skills. I know how to do all of these in code, but I
      can not figure out how to encode the rules in XML...

      1 - I can create a variable that holds the number of skill points a class
      gives at a particular level, but does anyone have any ideas as to how to
      give the 4* skill point bonus at first level?

      2 - Any ideas how to mark a skill as class/cross-class/exclusive? I can
      use 1/2/999999 costs but I need to do this on a per class basis?

      3 - Does anyone have any ideas as to how to allocate skill points? I know
      that I need to keep a track of the number of ranks bought and the
      available skill pool, but again it needs to be done on a per level per
      class basis.

      4 - The other problem is that the maxranks for a class will be determined
      by the characterLevel of the character and if any of their classes has it
      as a class skill.


      Example: Rog2/Sor3

      var.stat.int = 18
      var.stat.int.mod = 4
      var.skillpool.race.human = 4
      var.skillpool.class.rogue.1 = 4*(8+4) = 48
      var.skillpool.class.rogue.2 = 8+4 = 12
      var.skillpool.class.sorceror.1 = 4+4 = 8
      var.skillpool.class.sorceror.2 = 4+4 = 8
      var.skill.bluff.ranks = 0
      var.skillpool.class.rogue.1.available = 48

      How would I add ranks to the var.skill.bluff.ranks being aware of the
      skill point cost, the max ranks without needed to encode it in the
      application?

      How to give the *4 bonus to the rogue.1 and not to the sorceror.1?

      Now the application can know that it is using the
      var.skillpool.class.rogue.1.available allocation to populate the bluff
      ranks and that as it increases one it decreases the other. but how to
      handle the meta-data?


      --
      regards,
      Frugal
      -OS Chimp

      [1] I challenge anyone to remove the Globals.getCurrentPC() method. Or to
      make the data object immutable so that they only contain data and a
      separate heirarchy contains the implementation so that we do not need to
      clone() every single damn object in the system. Or to remove all of the
      GUI layer without causing hundreds of errors in core. Or to remove all of
      the persistance layer without generating hundreds of errors in the core
      etc...




      --
      regards,
      Frugal
      -OS Chimp
    • andargor
      ... that is ... the ... This may be a total tangent, but have you considered using something like Rhino (Mozilla s Javascript engine for Java) for object
      Message 2 of 18 , Mar 25, 2004
      • 0 Attachment
        --- In pcgen-xml@yahoogroups.com, "Frugal" <frugal@p...> wrote:
        >
        > As everytime I try to refactor out some piece of the spagetti code
        that is
        > PCGen[1] I realise it is a futile effort I returned my attention to
        the
        > protype that Steve had built.

        This may be a total tangent, but have you considered using something
        like Rhino (Mozilla's Javascript engine for Java) for object
        behavior? Rhino has a LiveConnect component which exposes Java
        methods/attributes to Javascript and vice-versa.

        http://www.mozilla.org/js/

        What you do is store the Javascript bits and pieces in the XML, load
        them up at start, compile them, associate them with an object, and
        the engine only has to go through bytecode when the object's method,
        say OnCalculate(), is called... (Several methods could be defined,
        OnLoad(), OnAdd(), OnRemove(), whatever) Just put the objects on a
        calculation stack, and you're golden.

        I'm working with SpiderMonkey right now (the C++ equivalent to Rhino)
        to code up a d20 engine that does some thing like this.

        About max ranks: there are feats that modify them, too. Remember the
        (broken) SKILLMAXRANKS tag in LST?

        My turkish $0.02

        Andargor
      • Keith Davies
        ... Create an external progression class levels . For each rank in that, add a level of a class chosen by the user. Give the *4 skill points in the first
        Message 3 of 18 , Mar 25, 2004
        • 0 Attachment
          On Thu, Mar 25, 2004 at 02:58:52PM +0000, Frugal wrote:
          >
          > As everytime I try to refactor out some piece of the spagetti code that is
          > PCGen[1] I realise it is a futile effort I returned my attention to the
          > protype that Steve had built.
          >
          > I altered it so that the model was separaetd from the character and
          > optimised the variable (ex score) code so that it can do an update that
          > trickles down in about 16ms. I also added a couple of small feat entites
          > to ensure that it can add and remove an entity and have the effects
          > cascade down.
          >
          > I then started to figure out how to do classes. As they are the most
          > complicated thing I thought they should be donw first to encounter as many
          > problems as possible. It also lets me know if the system will work for
          > more than the trivial case.
          >
          > I can figure out how to do most of the things that a class requires, but I
          > am a bit stumped by skills. I know how to do all of these in code, but I
          > can not figure out how to encode the rules in XML...
          >
          > 1 - I can create a variable that holds the number of skill points a class
          > gives at a particular level, but does anyone have any ideas as to how to
          > give the 4* skill point bonus at first level?

          Create an external progression 'class levels'. For each rank in that,
          add a level of a class chosen by the user. Give the *4 skill points in
          the first rank of 'class levels', not in the first rank of the class.

          > 2 - Any ideas how to mark a skill as class/cross-class/exclusive? I can
          > use 1/2/999999 costs but I need to do this on a per class basis?

          Exclusive is an attribute of the skill. A 'class' skill has a special
          relationship with a class that makes it cheaper for members of that
          class to buy it up.

          You *could* list the class skills inside a class; personally I don't
          like that mechanism because it complicates maintenance at the file
          level. I'd prefer something more 'normalized' (the association made
          outside the class *and* the skill; in RDBMS this would be a link table).

          Then when processing, it looks something like

          if (skill in class skills) {
          return Skill.CLASS
          } else if (skill.getExclusive) {
          return Skill.EXCLUSIVE
          } else {
          return Skill.CROSSCLASS
          }

          You still need to do something intelligent with those results, but
          identifying class/crossclass/exclusive isn't that bad.

          > 3 - Does anyone have any ideas as to how to allocate skill points? I
          > know that I need to keep a track of the number of ranks bought and the
          > available skill pool, but again it needs to be done on a per level per
          > class basis.

          yes it does; not only do we need it for rolling back, but there are
          rules around how many ranks can be had at any given level and what they
          cost.

          > 4 - The other problem is that the maxranks for a class will be determined
          > by the characterLevel of the character and if any of their classes has it
          > as a class skill.

          Ignoring for the moment the question of exclusive skills and how their
          max ranks are determined, have a list of 'character class skills' that
          identifies which skills are in the character's class skills for at least
          one class. Set a rule that says 'when adding first level of a class,
          add the class skills to this list'. Determining max ranks for this is
          then fairly straightforward.

          For exclusive skills, set a rule that increases a level counter for each
          such skill in the character, then add three to it (if not-zero) when
          referring to it.

          This mechanism could be generalized and made cleaner, of course. I
          could see something like

          CharacterSkill {
          Skill skill;
          int levels;
          boolean exclusiveSkill;
          boolean classSkill;

          float getMaxRanks() {
          if (classSkill) {
          return levels + 3;
          } else {
          return (levels + 3) / 2;
          }
          }
          }

          The exclusiveSkill and classSkill flags are here because it can vary by
          character. Now when you add a character level, you select a class and a
          level of that class is added; at the same time, the character level adds
          one to level for all class skills and cross-class skills for that
          character.

          Clunky, I know, but it should handle it.

          > [1] I challenge anyone to remove the Globals.getCurrentPC() method. Or to
          > make the data object immutable so that they only contain data and a
          > separate heirarchy contains the implementation so that we do not need to
          > clone() every single damn object in the system. Or to remove all of the
          > GUI layer without causing hundreds of errors in core. Or to remove all of
          > the persistance layer without generating hundreds of errors in the core
          > etc...

          Start from the outside and work in. Take what you need from the extant
          code and implement things cleanly. Technically, of course, that's not
          'removing', that's 'rebuilding around it'.


          Keith
          --
          Keith Davies I gave my 2yo daughter a strawberry
          keith.davies@... Naomi: "Strawberry!"
          me: "What do you say?"
          Naomi: "*MY* strawberry!"
        • Frugal
          ... I guess that I am trying to do this using the simplest metadata constructs that I can. Partly becasue I do not want to flood the
          Message 4 of 18 , Mar 29, 2004
          • 0 Attachment
            <quote who="Keith Davies">
            > On Thu, Mar 25, 2004 at 02:58:52PM +0000, Frugal wrote:
            > Create an external progression 'class levels'. For each rank in that,
            > add a level of a class chosen by the user. Give the *4 skill points in
            > the first rank of 'class levels', not in the first rank of the class.

            I guess that I am trying to do this using the simplest metadata constructs
            that I can. Partly becasue I do not want to flood the system with
            different constructs and partly because I want to see just how much can be
            expressed with metadata.

            > You *could* list the class skills inside a class; personally I don't
            > like that mechanism because it complicates maintenance at the file
            > level. I'd prefer something more 'normalized' (the association made
            > outside the class *and* the skill; in RDBMS this would be a link table).
            >
            > Then when processing, it looks something like
            >
            > if (skill in class skills) {
            > return Skill.CLASS
            > } else if (skill.getExclusive) {
            > return Skill.EXCLUSIVE
            > } else {
            > return Skill.CROSSCLASS
            > }
            >
            > You still need to do something intelligent with those results, but
            > identifying class/crossclass/exclusive isn't that bad.

            I was trying to make this as system agnostic as possible. I do not want to
            start coding concepts into the system if I can possibly help it. As soon
            as I start to encode system rules in the code then I have moved away from
            that goal.

            What I can not think of is how to represent that code fragment in metadata
            such that the Java rules interpreter knows nothing about skills and how
            they interact with characters and classes.

            > Ignoring for the moment the question of exclusive skills and how their
            > max ranks are determined, have a list of 'character class skills' that
            > identifies which skills are in the character's class skills for at least
            > one class. Set a rule that says 'when adding first level of a class,
            > add the class skills to this list'. Determining max ranks for this is
            > then fairly straightforward.

            I can just have a var.skill.bluff.max-ranks and set max-suppressable to 1.
            then each class can do a var-bonus of characterLevel+3 with suppressable
            set to true so that only the highest value will count. With a
            var.skill.default.max-ranks set to be (CL+3)/2.

            The trouble is that I keep coming up with exceptions and problems: what
            happens when you have a feat that makes a skill cross class?; what happens
            when you then take a piece of equipment that makes the same skill class?..

            I am sure that all of this is straightforward but I am blaming 5hours
            sleep a night and not needing to use my brain at work for 9 months.

            --
            regards,
            Frugal
            -OS Chimp
          • andargor
            ... what ... happens ... class?.. ... I ve come to the conclusion that you cannot fit all possible variations of possible publisher content into neat little
            Message 5 of 18 , Mar 29, 2004
            • 0 Attachment
              --- In pcgen-xml@yahoogroups.com, "Frugal" <frugal@p...> wrote:
              >
              > The trouble is that I keep coming up with exceptions and problems:
              what
              > happens when you have a feat that makes a skill cross class?; what
              happens
              > when you then take a piece of equipment that makes the same skill
              class?..
              >
              ...
              > --
              > regards,
              > Frugal
              > -OS Chimp

              I've come to the conclusion that you cannot fit all possible
              variations of possible publisher content into neat little buckets.
              The rules follow general principles which can be broken at any
              publisher's whim (including WotC)

              I'm sorry if I'm harping incessantly about this, but I believe the
              only solution is to have bits of code attached to each object (feat,
              special ability, whatever) to allow for the exceptions, which are the
              rule. Sure, you can have a common library to avoid coding
              the "standard" stuff, but you need the flexibility of full-fledged
              code for exceptions. Meta-data won't cut it.

              I hope to have a working prototype of the engine I'm working on in
              the not-too-far future to illustrate what I mean.

              Andargor
            • Keith Davies
              ... Agreed. ... heh, that was intended to look like pseudocode, not Java code. Sorry for not saying as much. I was thinking of the above snippet being a
              Message 6 of 18 , Mar 29, 2004
              • 0 Attachment
                On Mon, Mar 29, 2004 at 02:30:26PM +0100, Frugal wrote:
                >
                > <quote who="Keith Davies">
                > > On Thu, Mar 25, 2004 at 02:58:52PM +0000, Frugal wrote:
                > > Create an external progression 'class levels'. For each rank in that,
                > > add a level of a class chosen by the user. Give the *4 skill points in
                > > the first rank of 'class levels', not in the first rank of the class.
                >
                > I guess that I am trying to do this using the simplest metadata
                > constructs that I can. Partly becasue I do not want to flood the
                > system with different constructs and partly because I want to see just
                > how much can be expressed with metadata.

                Agreed.

                > > You *could* list the class skills inside a class; personally I don't
                > > like that mechanism because it complicates maintenance at the file
                > > level. I'd prefer something more 'normalized' (the association made
                > > outside the class *and* the skill; in RDBMS this would be a link table).
                > >
                > > Then when processing, it looks something like
                > >
                > > if (skill in class skills) {
                > > return Skill.CLASS
                > > } else if (skill.getExclusive) {
                > > return Skill.EXCLUSIVE
                > > } else {
                > > return Skill.CROSSCLASS
                > > }
                > >
                > > You still need to do something intelligent with those results, but
                > > identifying class/crossclass/exclusive isn't that bad.
                >
                > I was trying to make this as system agnostic as possible. I do not
                > want to start coding concepts into the system if I can possibly help
                > it. As soon as I start to encode system rules in the code then I have
                > moved away from that goal.

                heh, that was intended to look like pseudocode, not Java code. Sorry
                for not saying as much. I was thinking of the above snippet being a
                'rule' (expressed in metadata -- in a data file, at least -- rather than
                program code).

                > I can just have a var.skill.bluff.max-ranks and set max-suppressable
                > to 1. then each class can do a var-bonus of characterLevel+3 with
                > suppressable set to true so that only the highest value will count.
                > With a var.skill.default.max-ranks set to be (CL+3)/2.

                I'm not sure what you're trying to describe here.

                > The trouble is that I keep coming up with exceptions and problems:
                > what happens when you have a feat that makes a skill cross class?;
                > what happens when you then take a piece of equipment that makes the
                > same skill class?..

                That's why the snippet above has the structure it does, though there is
                an additional complication if you allow cross-class access to exclusive
                skills.

                > I am sure that all of this is straightforward but I am blaming 5hours
                > sleep a night and not needing to use my brain at work for 9 months.

                How is your daughter doing?


                Keith
                --
                Keith Davies I gave my 2yo daughter a strawberry
                keith.davies@... Naomi: "Strawberry!"
                me: "What do you say?"
                Naomi: "*MY* strawberry!"
              • Steven Bethard
                ...
                Message 7 of 18 , Mar 29, 2004
                • 0 Attachment
                  <quote who="Frugal">
                  > 1 - I can create a variable that holds the number
                  > of skill points a class gives at a particular level,
                  > but does anyone have any ideas as to how to give the
                  > 4* skill point bonus at first level?
                  </quote>

                  <def:var id="var.skillpool.multiplier" maxsuppressable="1">
                  <var-bonus targetid="var.skillpool.multiplier" suppressable="true">
                  1
                  </var-bonus>
                  <var-bonus targetid="var.skillpool.multiplier"
                  suppressable="true"
                  test="$var.classlevels == 1" >
                  4
                  </var-bonus>
                  This sets up a multiplier whose default value is 1, but whose value is 4
                  when the character has exactly 1 level. (I'm assuming var.classlevels will
                  be incremented whenever a class level of any type is added.)

                  So then for each level, you would have something like:
                  <var-bonus targetid="var.skillpool" test="$var.classlevels == 1" >
                  $var.skillpool.multiplier*($var.class.skillpoints +
                  $var.race.skillpoints)
                  </var-bonus>
                  This assumes that when the character takes a level in a class,
                  var.class.skillpoints gets updated to the appropriate number (e.g. 8 for
                  Rogue), and that if the character has a race (like Human) that grants a
                  bonus to the skillpoints, that var.race.skillpoints holds the number of
                  bonus skillpoints per level.

                  The only trouble here is what the test should be set to. You don't want to
                  have to do
                  <var-bonus ... "$var.classlevels == 1">...</var-bonus>
                  <var-bonus ... "$var.classlevels == 2">...</var-bonus>
                  ..
                  one for each level since it would repeat nearly identical data. It might be
                  a good idea to have a shorthand for this, something like "$var.classlevels
                  == *" maybe?




                  <quote who="Frugal">
                  > 2 - Any ideas how to mark a skill as class/cross
                  > class/exclusive? I can use 1/2/999999 costs but I need
                  > to do this on a per class basis?
                  </quote>

                  <def:var id="var.skill.bluff.ranks" />
                  <def:var id="var.skill.bluff.max-ranks" />
                  <def:var id="var.skill.bluff.rank-cost" maxsuppressable="1" />
                  <var-bonus targetid="var.skill.bluff.rank-cost" suppressable="true">
                  999999
                  </var-bonus>
                  This starts each skill as exclusive[1]. Note that var.skill.bluff.rank-cost
                  allows only one suppressable effect, and the rank-cost bonus is
                  suppressable, so if we apply a different modifier, this var-bonus will be
                  suppressed.

                  We could also set up, for each skill, a bonus to calculate the max-ranks
                  appropriately:
                  <var-bonus targetid="var.skill.bluff.max-ranks">
                  ($var.classlevels + 3) / $var.skill.bluff.rank-cost
                  </var-bonus>

                  So then for each class, you define the class and cross-class skill effects:
                  <var-bonus targetid="var.skill.bluff.rank-cost"
                  suppressable="true"
                  test="$var.class.rogue == 1">
                  1
                  </var-bonus>
                  <var-bonus targetid="..."
                  suppressable="true"
                  test="$var.class.rogue == 1">
                  2
                  </var-bonus>
                  ..

                  The only tricky thing here is that when we decide which effects to suppress,
                  we want (generally) to choose the var-bonus with the lowest bonus. In most
                  cases of suppression (where we choose between one bonus or another) we need
                  some selection criterion. The simplest selection criterion is to choose the
                  largest bonus (note that this is what we want to do when determining how to
                  deal with non-stacking bonuses for, say, Armor Class). In this case,
                  however, we want to choose the smallest bonus. My suggestion would be to
                  add an attribute 'order' which indicates how to select the bonuses when
                  maxsuppressable is set. For example:

                  <def:var id="var.skill.bluff.rank-cost"
                  maxsuppressable="1"
                  order="ascending" />

                  So, this would tell us that when we select which effect to apply, we want to
                  look at the bonus that each would apply, sort them in ascending order, and
                  then select the first one.

                  Some orderings that might be of use:
                  ascending - Sort the bonuses by value and pick the lowest
                  descending - Sort the bonuses by value and pick the highest
                  sequential-first - Do not sort the bonuses; just pick the first ones applied
                  sequential-last - Do not sort the bonuses; just pick the last ones applied


                  [1] See my discussion about a failure mechanism in the next bit. If we had
                  a good failure mechanism, it might be better to use failure instead of
                  999999 for exclusive skills.




                  <quote who="Frugal">
                  > 3 - Does anyone have any ideas as to how to allocate
                  > skill points? I know that I need to keep a track of
                  > the number of ranks bought and the available skill
                  > pool, but again it needs to be done on a per level per
                  > class basis.
                  </quote>

                  This brings up an interesting question. What do we want to happen if the
                  user tries to do something that the rules don't allow?

                  So I'm imagining that for allocating skillpoints we'd like to do something
                  simple like:
                  <var-bonus targetid="var.skillpool"> -4 </var-bonus>
                  <var-bonus targetid="var.skill.bluff.ranks"> 4 </var-bonus>
                  Basically just adding to the character a pair of effects, one that decreases
                  the skillpool and one that increases the appropriate ranks[2]. (We also
                  might want to mark these bonuses with the level, e.g. set
                  'test="$classlevels >= 1"' on the var-bonus if the skill was bought at first
                  level.)

                  Now what do we do if this bonus goes over the maximum stored in
                  var.skill.bluff.max-ranks? My intuition here is that we actually want a
                  failure of some sort, i.e. a notification to the system that the user has
                  tried to do something invalid. Note that we could always just do:
                  <var-bonus targetid="var.skill.bluff.ranks"
                  test="var.skill.bluff.ranks + 4 < var.skill.bluff.max-ranks">
                  4
                  </var-bonus>
                  where we do not add the bonus unless it would result in a value less than
                  the max-ranks. But then the user will have no idea why their ranks weren't
                  added.

                  So how would we like to deal with failure? We could add an element like:
                  <fail test="var.skill.bluff.ranks > var.skill.bluff.max-ranks" />
                  and have the system generate a failure notice to the user. The only thing
                  I'm not sure about here is how to undo the effects that caused the failure.

                  Suggestions?


                  [2] Note that bonuses for assigning skillpoints would have to be created by
                  the system (for the user), not defined by the data. We will, at some point,
                  need to discuss a mechanism for encoding what decisions the program must ask
                  the user to make.




                  <quote who="Frugal">
                  > 4 - The other problem is that the maxranks for a class
                  > will be determined by the characterLevel of the
                  > character and if any of their classes has it as a class
                  > skill.
                  </quote>

                  I think I mostly answered this one above when I talked about suppression and
                  ordering, but if I didn't please ask it again and I'll take another stab at
                  it.



                  Ok, I guess that's my bit for the moment.

                  Steve
                  _____

                  True friends stab you in the front.

                  - Oscar Wilde
                • Frugal
                  ... My problem is that I can not see how you can express the pseudo-code in meta data without having a full state machine. You need
                  Message 8 of 18 , Mar 30, 2004
                  • 0 Attachment
                    <quote who="Keith Davies">
                    > On Mon, Mar 29, 2004 at 02:30:26PM +0100, Frugal wrote:
                    > heh, that was intended to look like pseudocode, not Java code. Sorry
                    > for not saying as much. I was thinking of the above snippet being a
                    > 'rule' (expressed in metadata -- in a data file, at least -- rather than
                    > program code).

                    My problem is that I can not see how you can express the pseudo-code in
                    meta data without having a full state machine. You need to be able to
                    iterate over classes in a character, the skills need to know how they are
                    applied to that character, the state machine needs to know how to
                    manipulate variables so that it can set a variable depending on the
                    current state.

                    I keep coming back to the problem of how to express the problem domain
                    without creating the application domain at the same time. Evey time I come
                    up with a solution I reaslise that I have created a system that is based
                    on XSLT transformations to do all of the work. Whilst this may be a
                    workable idea it is not a good way of having a data format independent
                    application layer.

                    >> I can just have a var.skill.bluff.max-ranks and set max-suppressable
                    >> to 1. then each class can do a var-bonus of characterLevel+3 with
                    >> suppressable set to true so that only the highest value will count.
                    >> With a var.skill.default.max-ranks set to be (CL+3)/2.
                    >
                    > I'm not sure what you're trying to describe here.

                    Steve explained what I was trying to say much better than I did in his
                    most recent post.

                    >> The trouble is that I keep coming up with exceptions and problems:
                    >> what happens when you have a feat that makes a skill cross class?;
                    >> what happens when you then take a piece of equipment that makes the
                    >> same skill class?..
                    >
                    > That's why the snippet above has the structure it does, though there is
                    > an additional complication if you allow cross-class access to exclusive
                    > skills.

                    My problem is that I do not want the code/application/metadata to have to
                    interrogate the entire system everytime it wants to know wether a skill is
                    class/cross class/exclusive for a particular level of a class. That puts
                    us right back where we started from. What I would like is some mechanism
                    such that the 'effect's that alter the class/cross classness of the skill
                    push an update rather than having an update pulled from the mass of data.

                    >> I am sure that all of this is straightforward but I am blaming 5hours
                    >> sleep a night and not needing to use my brain at work for 9 months.
                    >
                    > How is your daughter doing?

                    Bonny. She is puttng on weight slowly but steadily. She is not quite 6
                    weeks old, but we had to go out and buy some 3-6 month clothes because she
                    is so long. She is spending a lot of time being 'quiet alert' and looking
                    around at the world, unfortunately her favorite times to do this are
                    midnight and 5am. Plus she is now in flailing-arms state and keeps hitting
                    herself in the head when trying to get to sleep ;O)

                    --
                    regards,
                    Frugal
                    -OS Chimp
                  • Frugal
                    ... I would be interested in seeing this. I have never tried this sort of approach before. What sort of timescale are we looking at:
                    Message 9 of 18 , Mar 30, 2004
                    • 0 Attachment
                      <quote who="andargor">
                      > I've come to the conclusion that you cannot fit all possible
                      > variations of possible publisher content into neat little buckets.
                      > The rules follow general principles which can be broken at any
                      > publisher's whim (including WotC)
                      >
                      > I'm sorry if I'm harping incessantly about this, but I believe the
                      > only solution is to have bits of code attached to each object (feat,
                      > special ability, whatever) to allow for the exceptions, which are the
                      > rule. Sure, you can have a common library to avoid coding
                      > the "standard" stuff, but you need the flexibility of full-fledged
                      > code for exceptions. Meta-data won't cut it.
                      >
                      > I hope to have a working prototype of the engine I'm working on in
                      > the not-too-far future to illustrate what I mean.

                      I would be interested in seeing this. I have never tried this sort of
                      approach before.

                      What sort of timescale are we looking at: days, weeks, months?

                      --
                      regards,
                      Frugal
                      -OS Chimp
                    • Frugal
                      ... The problem is that there is no cnocept of state in this situation. So it all works fine at var.classlevels==1, however as
                      Message 10 of 18 , Mar 30, 2004
                      • 0 Attachment
                        <quote who="Steven Bethard">
                        > <def:var id="var.skillpool.multiplier" maxsuppressable="1">
                        > <var-bonus targetid="var.skillpool.multiplier" suppressable="true">
                        > 1
                        > </var-bonus>
                        > <var-bonus targetid="var.skillpool.multiplier"
                        > suppressable="true"
                        > test="$var.classlevels == 1" >
                        > 4
                        > </var-bonus>
                        > This sets up a multiplier whose default value is 1, but whose value is 4
                        > when the character has exactly 1 level. (I'm assuming var.classlevels
                        > will
                        > be incremented whenever a class level of any type is added.)
                        >
                        > So then for each level, you would have something like:
                        > <var-bonus targetid="var.skillpool" test="$var.classlevels == 1" >
                        > $var.skillpool.multiplier*($var.class.skillpoints +
                        > $var.race.skillpoints)
                        > </var-bonus>

                        The problem is that there is no cnocept of state in this situation.

                        So it all works fine at var.classlevels==1, however as soon as you take
                        another level:

                        var.classlevels = 2

                        which causes a recalculation of

                        var.skillpool.multiplier from 4 to 1

                        which causes a recalculation of

                        var.skillpool


                        I think it can be done using Keiths Progression concept:

                        - A character has a Progression describing the classes he has taken at
                        each level
                        - A rule that detailed a *4 multiplier at the first rank of this progression
                        - Something in the rank suck that it knows that character rank 1 is class
                        rogue rank 1, and character rank 2 is sorceror rank 1.

                        I just need to come up with the rules to handle looking up progression
                        details, and storing one progression as reference inside another.

                        > <quote who="Frugal">
                        >> 2 - Any ideas how to mark a skill as class/cross
                        >> class/exclusive? I can use 1/2/999999 costs but I need
                        >> to do this on a per class basis?
                        > </quote>
                        >
                        > <def:var id="var.skill.bluff.ranks" />
                        > <def:var id="var.skill.bluff.max-ranks" />
                        > <def:var id="var.skill.bluff.rank-cost" maxsuppressable="1" />
                        > <var-bonus targetid="var.skill.bluff.rank-cost" suppressable="true">
                        > 999999
                        > </var-bonus>

                        when I actually sat down and thought it out I came up with a very similar
                        idea. However there are problems with it ;O)

                        > So then for each class, you define the class and cross-class skill
                        > effects:
                        > <var-bonus targetid="var.skill.bluff.rank-cost"
                        > suppressable="true"
                        > test="$var.class.rogue == 1">
                        > 1
                        > </var-bonus>
                        > <var-bonus targetid="..."
                        > suppressable="true"
                        > test="$var.class.rogue == 1">
                        > 2
                        > </var-bonus>

                        Problem 1: We have no idea what the names of the cross class skills are.
                        There are an arbitrary number of cross class skills and we have no idea
                        what they all are.

                        > The only tricky thing here is that when we decide which effects to
                        > suppress,
                        > we want (generally) to choose the var-bonus with the lowest bonus. In
                        > most
                        > cases of suppression (where we choose between one bonus or another) we
                        > need
                        > some selection criterion. The simplest selection criterion is to choose
                        > the
                        > largest bonus (note that this is what we want to do when determining how
                        > to
                        > deal with non-stacking bonuses for, say, Armor Class). In this case,
                        > however, we want to choose the smallest bonus. My suggestion would be to
                        > add an attribute 'order' which indicates how to select the bonuses when
                        > maxsuppressable is set. For example:

                        Problem 2: In this case how do we change a class skill into a cross class
                        or exclusive skill. If we are saying always take the lowest cost, then we
                        can not increase the cost of a skill.

                        We can not even put a hack in saying that we should raise the cost by one
                        using this kind of techinque:

                        <var-bonus targetid="var.skill.bluff.rank-cost" suppressable="false">
                        1
                        </var-bonus>

                        Because we might have more than one effect doing this at the same time.

                        Consider the extreme case:

                        Rogue class has Bluff as a class skill.
                        character takes a feat that gives a bonus to combat, but makes bluff an
                        exclusive skill
                        Character then gets a magic item that makes bluff a class skill.

                        When the character takes a level in rogue, what is the cost of a rank of
                        Bluff?

                        > This brings up an interesting question. What do we want to happen if the
                        > user tries to do something that the rules don't allow?

                        Personally I think that we should set up the rules, if the application
                        wishes to override the rules then that is their right. If we do not give
                        the application the ability to override the rules then we make it much
                        more difficult to implement house rules.

                        > So how would we like to deal with failure? We could add an element like:
                        > <fail test="var.skill.bluff.ranks > var.skill.bluff.max-ranks" />
                        > and have the system generate a failure notice to the user. The only thing
                        > I'm not sure about here is how to undo the effects that caused the
                        > failure.

                        Do not undo the changes, the fail will cause the application to be
                        notified that something broke a rule, then it is up to the application to
                        undo the change.

                        --
                        regards,
                        Frugal
                        -OS Chimp
                      • Frugal
                        ... I think that my big problem is that the skills can not know to which class they are applied and the class levels can not know
                        Message 11 of 18 , Mar 30, 2004
                        • 0 Attachment
                          <quote who="Keith Davies">

                          >> > Then when processing, it looks something like
                          >> >
                          >> > if (skill in class skills) {
                          >> > return Skill.CLASS
                          >> > } else if (skill.getExclusive) {
                          >> > return Skill.EXCLUSIVE
                          >> > } else {
                          >> > return Skill.CROSSCLASS
                          >> > }
                          >> >
                          >> > You still need to do something intelligent with those results, but
                          >> > identifying class/crossclass/exclusive isn't that bad.
                          >>
                          >> I was trying to make this as system agnostic as possible. I do not
                          >> want to start coding concepts into the system if I can possibly help
                          >> it. As soon as I start to encode system rules in the code then I have
                          >> moved away from that goal.
                          >
                          > heh, that was intended to look like pseudocode, not Java code. Sorry
                          > for not saying as much. I was thinking of the above snippet being a
                          > 'rule' (expressed in metadata -- in a data file, at least -- rather than
                          > program code).

                          I think that my big problem is that the skills can not know to which class
                          they are applied and the class levels can not know which character level
                          they re applied to.

                          i.e. A skill has no idea if it is class/cross class or exclusive, so we
                          can not interrogate it to find out. Plus the cost of a skill is not fixed
                          it is dependent on who is asking.

                          i.e. A class level does not know what character level it is applied to.

                          To get the skill points for a character level we end up with pseudo code
                          like this:

                          getSkillPointsForCharacterLevel(int level) {
                          // Get the character level 'level'
                          Progression character = getCharcter();
                          Rank rank = character.getRank( level );

                          // Get the details of the class at that level
                          String className = rank.getAttribute("className");
                          int classLevel = rank.getAtribute("classLevel");

                          // Get the number of skillpoints this character level giev the character
                          int skillPoints = getVariable( "var.skillpool.class." + className +
                          "." + classLevel );
                          if (skillPoints == null)
                          skillPoints = getVariable("var.skillpool.class."+className);
                          if (skillPoints == null)
                          skillPoints = 0;

                          // get the multiplier that this character level gives to the skill points
                          int multiplier = getVariable("var.skillpool.multiplier.charLevel."+
                          level);
                          if (multiplier==null)
                          multiplier = 1;

                          // Get the number of flat bonus skill points we get at this level.
                          int skillBonus = getVariable("var.skillpool.bonus.class." + className +
                          "." + classLevel);
                          skillBonus += getVariable("var.skillpool.bonus.class."+className);
                          skillBonus += getVariable("var.skillpool.bonus.character."+level);
                          skillBonus += getVariable("var.skillpool.bonus);
                          if (skillBonus == null)
                          skillBonus=0;

                          return (skillPoints * multiplier) + skillbonus;
                          }


                          There is lots of pulling of data which leads us down the road of the
                          current implementation.

                          If we have expressions inside expressions and we can get them to collapse
                          we might be able to do something like this:

                          <variable-bonus targetid="var.skillpool.character.level.1">
                          $var.skillpool.class.{$character.rank[1].attribute("className")}.{$character.rank[1].attribute("classLevel")}
                          </variable-bonus>

                          It will collapse to something like this:

                          <variable-bonus targetid="var.skillpool.character.level.1">
                          $var.skillpool.class.rogue.1
                          </variable-bonus>

                          The bonus then depends on the variables:
                          $var.skillpool.class.rogue.1
                          $character.rank[1].attribute("className")
                          $character.rank[1].attribute("classLevel")

                          However we then need to be notified when the attributes of
                          character.rank[1] change, or when the character changes rank[1]. which is
                          problematic at best.


                          To identify the cost of taking a rank of a skill if a function of the
                          character level and the skill:

                          getSkillRankCostForCharacterLevel(Entity skill, int level ) {
                          // Get the character level 'level'
                          Progression character = getCharcter();
                          Rank rank = character.getRank( level );

                          // Get the details of the class at that level
                          String className = rank.getAttribute("className");
                          int classLevel = rank.getAtribute("classLevel");

                          //Get the details of the skill
                          String skillName = skill.getId();
                          String[] skilltypes = skill.getAttribute("types");

                          int rankCost = getVariable("skill." + skillName + ".cost." +
                          className + "." + level);
                          if (rankCost == null)
                          rankCost = getVariable("skill."+skillName+".cost."+className);
                          if (rankCost == null)
                          rankCost = getVariable("skill."+skillName+".cost");

                          foreach (skillTypes && rankCost!=null) {
                          int rankCost = getVariable("skill.type." + skillType + ".cost."
                          + className + "." + level);
                          if (rankCost == null)
                          rankCost = getVariable("skill.type."+skillType+".cost."+className);
                          if (rankCost == null)
                          rankCost = getVariable("skill.type."+skillType+".cost");
                          }

                          if (rankCost == null)
                          return 2;
                          }

                          But this is horrible and messy and does not lend itself to expansion easily.

                          I would be interested to see how other people are thinking of handling the
                          meta-data problem...

                          --
                          regards,
                          Frugal
                          -OS Chimp
                        • andargor
                          ... I have a little learning curve to go over with the embedded Javascript engine. Mainly mapping XML to Javascript objects so I can manipulate them with JS
                          Message 12 of 18 , Mar 30, 2004
                          • 0 Attachment
                            --- In pcgen-xml@yahoogroups.com, "Frugal" <frugal@p...> wrote:
                            >
                            >
                            > What sort of timescale are we looking at: days, weeks, months?
                            >
                            > --
                            > regards,
                            > Frugal
                            > -OS Chimp

                            I have a little learning curve to go over with the embedded
                            Javascript engine. Mainly mapping XML to Javascript objects so I can
                            manipulate them with JS code snippets. I have it pretty well licked,
                            and that was a big hurdle.

                            I'm negotiating some coding time (I have a new gf...), but I think I
                            can have a basic prototype in a couple of weeks. Nothing fancy, maybe
                            just skill calculations as a comparative to the metadata approach.

                            It might be quicker than that if I can have some good weekend coding
                            time...

                            Andargor
                          • Steven Bethard
                            ... Ahhh, of course. Right, so basically what we want is a differentiation between effects that should be recalculated and
                            Message 13 of 18 , Mar 30, 2004
                            • 0 Attachment
                              <quote who="Frugal">
                              > The problem is that there is no cnocept of state in this situation.
                              >
                              > So it all works fine at var.classlevels==1, however as soon as you take
                              > another level:
                              > var.classlevels = 2
                              > which causes a recalculation of
                              > var.skillpool.multiplier from 4 to 1
                              > which causes a recalculation of
                              > var.skillpool
                              </quote>

                              Ahhh, of course. Right, so basically what we want is a differentiation
                              between effects that should be recalculated and effects that shouldn't.
                              This would also have come up as soon as we started thinking about what's
                              supposed to happen to skillpoints when a character increases their
                              Intelligence. SRD says this should not cause a skillpoint recalculation,
                              but I know that PCGen currenly gives the option to allow this to recalculate
                              skillpoints.

                              So to make sure I understand the terminology, is a Progression just a
                              sequence of effects that shouldn't be recalcuated?



                              > Problem 1: We have no idea what the names of the cross class skills are.
                              > There are an arbitrary number of cross class skills and we have no idea
                              > what they all are.

                              Answering this may be irrelevant depending on what Progressions do here, but
                              if you want cross-class to be the default, you should use '2' instead of
                              '999999' for the default initialization.

                              > Problem 2: In this case how do we change a class skill into a cross class
                              > or exclusive skill. If we are saying always take the lowest cost, then we
                              > can not increase the cost of a skill.

                              If I understand you right, you're saying that by default, we still want the
                              'ascending' behavior, but occasionally we'll want the 'sequential-last'
                              behavior at the same time, applying to only some of the effects, right? The
                              only way I can see of doing this is to, instead of indicating 'ascending' on
                              the var, indicate it on the score-bonus. And you probably also need a
                              suppressable count for each of the ordering types, etc. It gets complicated
                              quickly, so I'll be interested to see the Progression approach to this...

                              > Personally I think that we should set up the rules, if the application
                              > wishes to override the rules then that is their right. If we do not give
                              > the application the ability to override the rules then we make it much
                              > more difficult to implement house rules.

                              I tend to agree here, I just think that it's not clear what the rules are.
                              What should happen if a user tries to put 5 skillpoints into a skill with
                              max-ranks of 4? Do 4 of the skillpoints get transferred? Do none of the
                              skillpoints get transferred? That is, when an effect would violate some
                              constraint, do we execute as much of the effect as possible, or do we not
                              execute any part of the effect? My intuition is that none of the effect
                              should be executed, but I'd prefer some sort of consensus opinion on this
                              one.

                              Steve
                              _____

                              You can wordify anything if you just verb it.
                              - Bucky Katt, Get Fuzzy
                            • Keith Davies
                              ... A Progression, as I ve designed it, is an entity that gets applied in steps. For instance, a class is a progression because the effects get applied in a
                              Message 14 of 18 , Mar 30, 2004
                              • 0 Attachment
                                On Tue, Mar 30, 2004 at 09:27:48AM -0700, Steven Bethard wrote:
                                > <quote who="Frugal">
                                > > The problem is that there is no cnocept of state in this situation.
                                > >
                                > > So it all works fine at var.classlevels==1, however as soon as you take
                                > > another level:
                                > > var.classlevels = 2
                                > > which causes a recalculation of
                                > > var.skillpool.multiplier from 4 to 1
                                > > which causes a recalculation of
                                > > var.skillpool
                                > </quote>
                                >
                                > Ahhh, of course. Right, so basically what we want is a
                                > differentiation between effects that should be recalculated and
                                > effects that shouldn't. This would also have come up as soon as we
                                > started thinking about what's supposed to happen to skillpoints when a
                                > character increases their Intelligence. SRD says this should not
                                > cause a skillpoint recalculation, but I know that PCGen currenly gives
                                > the option to allow this to recalculate skillpoints.
                                >
                                > So to make sure I understand the terminology, is a Progression just a
                                > sequence of effects that shouldn't be recalcuated?

                                A Progression, as I've designed it, is an entity that gets applied in
                                steps. For instance, a class is a progression because the effects get
                                applied in a series of effects[1]. Skills can be[2]. One progression
                                that I suspect will be quite useful is 'character levels'. At each rank
                                in this progression, the character chooses a (valid) character class and
                                progresses one rank in that class. This progression also knows to add
                                feats ($level % 3 == 0), and looks to the description of the class to
                                get the number of hit points to add, and the number of skill points.

                                [1] a character can be a 'little bit' (say, two levels) of Fighter; at
                                each level something (increased hit points, BAB, saves, skills,
                                feats) can or does happen.
                                [2] some skills (Speak Language comes to mind, as does Mythos Lore (IIRC
                                CoC name)) give effects at each rank.

                                In my design, a character does not contain a progression, it contains
                                information describing the steps along that progression. For instance,
                                after gaining a few levels the character probably contains something like

                                <character>
                                <add:rank key='race.human'>
                                <add:rank key='characterlevel'>
                                <add:rank progression='class.fighter'>
                                <add:score key='hitpoints' value='10' />
                                <add:set key='feats' selected='feat.power-attack' />
                                <!-- might allow a shorthand for this... might not, since each
                                rank can conceivably have effects -->
                                <add:rank progression='skill.ride' />
                                <add:rank progression='skill.ride' />
                                <add:rank progression='skill.ride' />
                                <add:rank progression='skill.ride' />
                                <add:rank progression='skill.jump' />
                                <add:rank progression='skill.jump' />
                                <add:rank progression='skill.jump' />
                                <add:rank progression='skill.jump' />
                                <add:rank progression='skill.craft.weaponsmith' />
                                <add:rank progression='skill.craft.weaponsmith' />
                                <add:rank progression='skill.craft.weaponsmith' />
                                <add:rank progression='skill.craft.weaponsmith' />
                                </add:rank>
                                <add:set key='feats' selected='feat.improved-sunder' />
                                </add:rank>
                                <add:set key='feats' selected='feat.toughness' />
                                </add:rank>
                                <add:rank key='race.human'>
                                <add:rank key='characterlevel'>
                                <add:rank progression='class.fighter'>
                                <add:score key='hitpoints' value='8' />
                                <add:set key='feats' selected='feat.cleave' />
                                <add:rank progression='skill.ride' />
                                <add:rank progression='skill.jump' />
                                <add:rank progression='skill.craft.weaponsmith' />
                                </add:rank>
                                </add:rank>
                                </add:rank>
                                </character>

                                Only those things that require a decision or can vary between characters
                                (hit points, feats, and skill points). Note that I've added feats both
                                within the class <add:rank> (these are fighter feats) and outside (the
                                first-level feat). Racial bonus feats are probably handled in the race
                                description.

                                As shown above, I've even made race a progression ('advances as'
                                suggests a progression rather than an entity; this actually makes
                                dragons a whole lot easier, I think). A creature can still advance
                                *apart* from this (you can still add character levels to a cat, if you
                                want):

                                <character>
                                <add:rank key='race.cat' />
                                <add:rank key='characterlevel' />
                                <add:rank key='characterlevel' />
                                <add:rank key='characterlevel' />
                                <add:rank key='characterlevel' />
                                </character>

                                There, a fourth-level cat sorcerer. Or whatever. The cat 'race'
                                progression doesn't specify 'advance by class', so no class levels get
                                added. If cats get a size bump through progression (I doubt it, but
                                don't have the book handy to confirm) then that will be applied at the
                                appropriate 'rank in cat'. Character levels are tracked outside the
                                'racial progression' in this structure, as they should be. They also
                                get applied in chronological order; you could have

                                <character>
                                <add:rank key='race.cat' />
                                <add:rank key='characterlevel' />
                                <add:rank key='race.cat' />
                                <add:rank key='characterlevel' />
                                <add:rank key='race.cat' />
                                <add:rank key='characterlevel' />
                                <add:rank key='race.cat' />
                                <add:rank key='characterlevel' />
                                <add:rank key='race.cat' />
                                </character>

                                if you wanted.

                                > > Problem 1: We have no idea what the names of the cross class skills
                                > > are. There are an arbitrary number of cross class skills and we
                                > > have no idea what they all are.
                                >
                                > Answering this may be irrelevant depending on what Progressions do
                                > here, but if you want cross-class to be the default, you should use
                                > '2' instead of '999999' for the default initialization.

                                'Exclusive' is a flag on the skill itself. If not exclusive, assume
                                cross-class. If a class skill in the class being added, or the
                                character has it as a 'personal class' skill (as with Versatile) the
                                cost gets reduced to 1; if the character has it as a class skill for at
                                least one class skill, max ranks is equal to level+3 (barring exclusive
                                skill behavior) but he pays class or cross-class skill cost as
                                appropriate.

                                Blame this one on the rules, I think; there's no really *good* way of
                                modeling this, I think... the best we can do is 'workable'.

                                > > Problem 2: In this case how do we change a class skill into a cross
                                > > class or exclusive skill. If we are saying always take the lowest
                                > > cost, then we can not increase the cost of a skill.
                                >
                                > If I understand you right, you're saying that by default, we still
                                > want the 'ascending' behavior, but occasionally we'll want the
                                > 'sequential-last' behavior at the same time, applying to only some of
                                > the effects, right? The only way I can see of doing this is to,
                                > instead of indicating 'ascending' on the var, indicate it on the
                                > score-bonus. And you probably also need a suppressable count for each
                                > of the ordering types, etc. It gets complicated quickly, so I'll be
                                > interested to see the Progression approach to this...

                                The rule for the characterlevel progression would have to know to look
                                at the list of skills associated with the selected class and add them --
                                if necessary -- to the character's list of class skills. To determine
                                the cost of a rank in a skill necessarily requires information from the
                                character, the race, and the class. Since character is the only one
                                that knows -- directly or indirectly -- about the others, this
                                determination needs to be done in the character-processing rules.

                                Actually, it's possible that the characterlevel progression could do it,
                                since (for other purposes) it has to know things about the character
                                it's being applied to (such as to determine whether feat or class
                                prereqs are being met).

                                Dammit. I wanted to keep information flowing always from the data
                                object to the client object, not both ways. OTOH, having the engine
                                itself aware of prereqs -- which actually seems reasonable, it can be
                                considered a primitive -- could get around a lot of this simply by
                                requiring that things can be added to an entity only if the prereqs are
                                satisfied, or there is an explicit 'waive prereqs' flag.


                                Hrm... it comes to me that it could also be possible to set a
                                'recurring' prereq on the ranks of a skill (all skills; not a *big* deal
                                if we allow data-inheritance) that can only be satisfied when the
                                character meets certain criteria. I suspect it'd be an awkward
                                solution, though.

                                > > Personally I think that we should set up the rules, if the
                                > > application wishes to override the rules then that is their right.
                                > > If we do not give the application the ability to override the rules
                                > > then we make it much more difficult to implement house rules.
                                >
                                > I tend to agree here, I just think that it's not clear what the rules
                                > are. What should happen if a user tries to put 5 skillpoints into a
                                > skill with max-ranks of 4? Do 4 of the skillpoints get transferred?
                                > Do none of the skillpoints get transferred? That is, when an effect
                                > would violate some constraint, do we execute as much of the effect as
                                > possible, or do we not execute any part of the effect? My intuition
                                > is that none of the effect should be executed, but I'd prefer some
                                > sort of consensus opinion on this one.

                                In this case, I think that the behavior should be something like:

                                . if the number of ranks is allowed, apply them;
                                . if the number of ranks is not allowed; deny it and notify user[1];

                                ... and in this case, allow a 'add max ranks' is certainly a reasonable
                                command as well -- don't give a *number*, just say 'as many as you can'.

                                [1] in GUI, error dialog; if CLI processing, error message; etc.


                                Keith
                                --
                                Keith Davies I gave my 2yo daughter a strawberry
                                keith.davies@... Naomi: "Strawberry!"
                                me: "What do you say?"
                                Naomi: "*MY* strawberry!"
                              • Frugal
                                ... So in the above example adding a rank of race.human caused the addition of a rank of characterlevel which in turn causeed the
                                Message 15 of 18 , Apr 1, 2004
                                • 0 Attachment
                                  <quote who="Keith Davies">
                                  > In my design, a character does not contain a progression, it contains
                                  > information describing the steps along that progression. For instance,
                                  > after gaining a few levels the character probably contains something like
                                  >
                                  > <character>
                                  > <add:rank key='race.human'>
                                  > <add:rank key='characterlevel'>
                                  > <add:rank progression='class.fighter'>
                                  > <add:score key='hitpoints' value='10' />
                                  > <add:set key='feats' selected='feat.power-attack' />
                                  > <!-- might allow a shorthand for this... might not, since each
                                  > rank can conceivably have effects -->
                                  > <add:rank progression='skill.ride' />
                                  > <add:rank progression='skill.ride' />
                                  > <add:rank progression='skill.ride' />
                                  > <add:rank progression='skill.ride' />
                                  > <add:rank progression='skill.jump' />
                                  > <add:rank progression='skill.jump' />
                                  > <add:rank progression='skill.jump' />
                                  > <add:rank progression='skill.jump' />
                                  > <add:rank progression='skill.craft.weaponsmith' />
                                  > <add:rank progression='skill.craft.weaponsmith' />
                                  > <add:rank progression='skill.craft.weaponsmith' />
                                  > <add:rank progression='skill.craft.weaponsmith' />
                                  > </add:rank>
                                  > <add:set key='feats' selected='feat.improved-sunder' />
                                  > </add:rank>
                                  > <add:set key='feats' selected='feat.toughness' />
                                  > </add:rank>
                                  > <add:rank key='race.human'>
                                  > <add:rank key='characterlevel'>
                                  > <add:rank progression='class.fighter'>
                                  > <add:score key='hitpoints' value='8' />
                                  > <add:set key='feats' selected='feat.cleave' />
                                  > <add:rank progression='skill.ride' />
                                  > <add:rank progression='skill.jump' />
                                  > <add:rank progression='skill.craft.weaponsmith' />
                                  > </add:rank>
                                  > </add:rank>
                                  > </add:rank>
                                  > </character>
                                  >
                                  > Only those things that require a decision or can vary between characters
                                  > (hit points, feats, and skill points). Note that I've added feats both
                                  > within the class <add:rank> (these are fighter feats) and outside (the
                                  > first-level feat). Racial bonus feats are probably handled in the race
                                  > description.

                                  So in the above example adding a rank of "race.human" caused the addition
                                  of a rank of characterlevel which in turn causeed the adition of the rank
                                  of "class.fighter".

                                  I am assuming that there ar a whole load of <add:score/> that you have not
                                  shown in the example (stats for example)

                                  > 'Exclusive' is a flag on the skill itself. If not exclusive, assume
                                  > cross-class. If a class skill in the class being added, or the
                                  > character has it as a 'personal class' skill (as with Versatile) the
                                  > cost gets reduced to 1; if the character has it as a class skill for at
                                  > least one class skill, max ranks is equal to level+3 (barring exclusive
                                  > skill behavior) but he pays class or cross-class skill cost as
                                  > appropriate.

                                  How do you plan to encode that information in the meta data ?

                                  > The rule for the characterlevel progression would have to know to look
                                  > at the list of skills associated with the selected class and add them --
                                  > if necessary -- to the character's list of class skills. To determine
                                  > the cost of a rank in a skill necessarily requires information from the
                                  > character, the race, and the class.

                                  Actually it requires information from every single entity that the
                                  character has had applied to them. As an example I have come across a
                                  piece of equipment that gives "Open Lock" and "Disable Device" as class
                                  skills...

                                  > Since character is the only one
                                  > that knows -- directly or indirectly -- about the others, this
                                  > determination needs to be done in the character-processing rules.

                                  In the Meta data rules, or the Application rules ?

                                  > Actually, it's possible that the characterlevel progression could do it,
                                  > since (for other purposes) it has to know things about the character
                                  > it's being applied to (such as to determine whether feat or class
                                  > prereqs are being met).

                                  However the character level progression does not know about the race
                                  progression (i.e. +4 skill points to character level 1 if race=human).

                                  The only thing that knows enough information is the character object.

                                  So the characterlevel progression has to hold the counter of the skill
                                  point pool which is determined by the class rank in the characterlevel
                                  rank, plus the race, plus all of the other entities. Plus the fact that
                                  this can all change from level to level...

                                  So the skillpoints for a characterlevel rank are

                                  (X*Y)+Z

                                  Where

                                  X = classrank_skillpoints + bonus_skill_points_for_classlevel
                                  Y = skillpoint_multiplier_for_classlevelrank
                                  Z = extra_bonus_skill_points_for_classlevelrank

                                  So at the meta data level we need a way to index into the contents of a
                                  class rank that has been applied via a characterlevel rank using both the
                                  characterlevel rank number and the class rank number.

                                  The more I look at this the more I realise that in D&D A depends on B
                                  depends on C depends on A ;O(

                                  --
                                  regards,
                                  Frugal
                                  -OS Chimp
                                • Keith Davies
                                  ... Yes. It seems a little odd, but it works, and can cover racial differences and effects at various levels (HD and/or origins of changes). ... Much
                                  Message 16 of 18 , Apr 1, 2004
                                  • 0 Attachment
                                    On Thu, Apr 01, 2004 at 01:06:07PM +0100, Frugal wrote:
                                    >
                                    > <quote who="Keith Davies">
                                    > > In my design, a character does not contain a progression, it contains
                                    > > information describing the steps along that progression. For instance,
                                    > > after gaining a few levels the character probably contains something like
                                    > >
                                    > > Only those things that require a decision or can vary between
                                    > > characters (hit points, feats, and skill points). Note that I've
                                    > > added feats both within the class <add:rank> (these are fighter
                                    > > feats) and outside (the first-level feat). Racial bonus feats are
                                    > > probably handled in the race description.
                                    >
                                    > So in the above example adding a rank of "race.human" caused the
                                    > addition of a rank of characterlevel which in turn causeed the adition
                                    > of the rank of "class.fighter".

                                    Yes. It seems a little odd, but it works, and can cover racial
                                    differences and effects at various 'levels' (HD and/or origins of
                                    changes).

                                    > I am assuming that there ar a whole load of <add:score/> that you have
                                    > not shown in the example (stats for example)

                                    Much elided, yeah. The example was long enough.

                                    > > 'Exclusive' is a flag on the skill itself. If not exclusive, assume
                                    > > cross-class. If a class skill in the class being added, or the
                                    > > character has it as a 'personal class' skill (as with Versatile) the
                                    > > cost gets reduced to 1; if the character has it as a class skill for at
                                    > > least one class skill, max ranks is equal to level+3 (barring exclusive
                                    > > skill behavior) but he pays class or cross-class skill cost as
                                    > > appropriate.
                                    >
                                    > How do you plan to encode that information in the meta data ?

                                    probably as a rule or effect on the 'skill' superclass -- create an
                                    object that knows all this crap and works on flags ('if exclusive is
                                    set, etc.') to handle it. I'm really not happy about skills... but
                                    there doesn't seem to *be* a good way of handling them. The best I'm
                                    hoping for now is effective and correct.

                                    > > The rule for the characterlevel progression would have to know to look
                                    > > at the list of skills associated with the selected class and add them --
                                    > > if necessary -- to the character's list of class skills. To determine
                                    > > the cost of a rank in a skill necessarily requires information from the
                                    > > character, the race, and the class.
                                    >
                                    > Actually it requires information from every single entity that the
                                    > character has had applied to them. As an example I have come across a
                                    > piece of equipment that gives "Open Lock" and "Disable Device" as class
                                    > skills...

                                    That's not so bad -- the equipment changes the character to add the
                                    skills as class skills, then the effects are present after that.

                                    All entities need to be able to make any change to any entity it is
                                    applied to. In this case, the equipment adds the class skill to the
                                    character (which is exactly what you described), we don't determine
                                    through examination 'is there anything that adds this class skill to the
                                    character'.

                                    > > Since character is the only one
                                    > > that knows -- directly or indirectly -- about the others, this
                                    > > determination needs to be done in the character-processing rules.
                                    >
                                    > In the Meta data rules, or the Application rules ?

                                    I'd really, really like to see this in data rather than code. If
                                    necessary we can fold it into code, but I'd prefer to keep it out where
                                    it can be changed without modifying code.

                                    That said, it's probably not unreasonable to allow extensions in code
                                    for things that can't be done reasonably in data. For instance -- and
                                    this might not apply, so don't hold me to it -- weapon handedness might
                                    be best modeled as showing whether the weapon is one-handed, two-handed,
                                    or both, plus the conditions or effects of doing it. I'd rather see a
                                    series of enumerated values for this rather than a bit of nasty data for
                                    each... and shorthand could be very valuable (being able to just say
                                    'bastard' for handedness would be really useful).

                                    OTOH, using entities (define a &bastard; entity that contains the nasty
                                    data needed) can be a reasonable workaround -- in data -- for this. It
                                    gets lost on export, though, because it gets expanded on load; the
                                    program never sees the entity after it passes through the parser.

                                    > > Actually, it's possible that the characterlevel progression could do it,
                                    > > since (for other purposes) it has to know things about the character
                                    > > it's being applied to (such as to determine whether feat or class
                                    > > prereqs are being met).
                                    >
                                    > However the character level progression does not know about the race
                                    > progression (i.e. +4 skill points to character level 1 if race=human).

                                    true, but the race progression *does* (or rather, can) know to give the
                                    additional skill points.

                                    > The only thing that knows enough information is the character object.

                                    Which is why some rules (for instance, prereqs) will need to be able to
                                    bounce off the entity they are being used on to determine validity.
                                    This mechanism can be extended.

                                    > So the characterlevel progression has to hold the counter of the skill
                                    > point pool which is determined by the class rank in the characterlevel
                                    > rank, plus the race, plus all of the other entities. Plus the fact
                                    > that this can all change from level to level...

                                    Not quite, I think, *if* we require that the points be spent at each
                                    level -- as the rule state they must be. If we do that, we get points
                                    from *this* class level, and possibly a bonus for race at *this* level.

                                    On the other hand, it needs to be able to handle *reduced* skill points
                                    (low Int, possibly a racial penalty against skills) as well. Yeah, they
                                    need to be able to accumulate across the character.

                                    > So the skillpoints for a characterlevel rank are
                                    >
                                    > (X*Y)+Z
                                    >
                                    > Where
                                    >
                                    > X = classrank_skillpoints + bonus_skill_points_for_classlevel
                                    > Y = skillpoint_multiplier_for_classlevelrank
                                    > Z = extra_bonus_skill_points_for_classlevelrank
                                    >
                                    > So at the meta data level we need a way to index into the contents of
                                    > a class rank that has been applied via a characterlevel rank using
                                    > both the characterlevel rank number and the class rank number.
                                    >
                                    > The more I look at this the more I realise that in D&D A depends on B
                                    > depends on C depends on A ;O(

                                    This makes me sad. I was hoping it wasn't necessary.


                                    Keith
                                    --
                                    Keith Davies I gave my 2yo daughter a strawberry
                                    keith.davies@... Naomi: "Strawberry!"
                                    me: "What do you say?"
                                    Naomi: "*MY* strawberry!"
                                  • Frugal
                                    ... In the first of your examples the progression was like this:
                                    Message 17 of 18 , Apr 2, 2004
                                    • 0 Attachment
                                      <quote who="Keith Davies">
                                      > On Thu, Apr 01, 2004 at 01:06:07PM +0100, Frugal wrote:
                                      >> So in the above example adding a rank of "race.human" caused the
                                      >> addition of a rank of characterlevel which in turn causeed the adition
                                      >> of the rank of "class.fighter".
                                      >
                                      > Yes. It seems a little odd, but it works, and can cover racial
                                      > differences and effects at various 'levels' (HD and/or origins of
                                      > changes).

                                      In the first of your examples the progression was like this:

                                      <character>
                                      <add:rank key='race.human'>
                                      <add:rank key='characterlevel' />
                                      </add:rank>
                                      <add:rank key='race.human'>
                                      <add:rank key='characterlevel' />
                                      </add:rank>
                                      </character>

                                      And in the next two it was:

                                      <character>
                                      <add:rank key='race.cat' />
                                      <add:rank key='characterlevel' />
                                      <add:rank key='characterlevel' />
                                      <add:rank key='characterlevel' />
                                      <add:rank key='characterlevel' />
                                      </character>

                                      So are you saying that a character is made up of ranks of race (which have
                                      ranks of characterlevel), but that a character can also be made up of just
                                      ranks of characterlevel?

                                      >> However the character level progression does not know about the race
                                      >> progression (i.e. +4 skill points to character level 1 if race=human).
                                      >
                                      > true, but the race progression *does* (or rather, can) know to give the
                                      > additional skill points.

                                      - So the client asks that character for skill points at level 1.
                                      - The Character has no explicit value fo skillpoints
                                      - The Character looks at rank:1 which is race.human.
                                      - The Character asks rank:1 for skillpoints
                                      - The race.human:1 has a formula for calculating skillpoints:
                                      characterlevel_skillpoints * 4
                                      - The race rank asks the character level rank for skillpoints
                                      - The character level rank does not have an explicit value for
                                      skillpoints, so it asks the class rank 1.
                                      - The Class rank 1 has a formula for calculating skillpoinrts: INT.1 + 2
                                      - The Class asks the character for the value of INT.1
                                      - The character looks at all of the bonuses up to rank 1 that apply to
                                      INT, returns +3 (from client set value to stat).
                                      - the class returns 3+2 = 5
                                      - the characterlevel returns 5
                                      - The race level returns 5*4 = 20
                                      - The character returns 20
                                      - The client displays the value 20.

                                      >> So the characterlevel progression has to hold the counter of the skill
                                      >> point pool which is determined by the class rank in the characterlevel
                                      >> rank, plus the race, plus all of the other entities. Plus the fact
                                      >> that this can all change from level to level...
                                      >
                                      > Not quite, I think, *if* we require that the points be spent at each
                                      > level -- as the rule state they must be. If we do that, we get points
                                      > from *this* class level, and possibly a bonus for race at *this* level.

                                      For a whole raft of things I think we are going to need to be able to say:
                                      "What is the value of this at level x".

                                      for hit points we are going to want to know how many hit points were given
                                      at each level.

                                      For skill points we need to know how many skill points are available at
                                      each level

                                      For a lot of formulas we need to know what the value of a variable was at
                                      a certain level (i.e. for skill points at level 5 we need the intelligence
                                      modifier for level 5).



                                      >> (X*Y)+Z
                                      >>
                                      >> Where
                                      >>
                                      >> X = classrank_skillpoints + bonus_skill_points_for_classlevel
                                      >> Y = skillpoint_multiplier_for_classlevelrank
                                      >> Z = extra_bonus_skill_points_for_classlevelrank
                                      >>
                                      >> So at the meta data level we need a way to index into the contents of
                                      >> a class rank that has been applied via a characterlevel rank using
                                      >> both the characterlevel rank number and the class rank number.
                                      >>
                                      >> The more I look at this the more I realise that in D&D A depends on B
                                      >> depends on C depends on A ;O(
                                      >
                                      > This makes me sad. I was hoping it wasn't necessary.

                                      The more I look at this the more I think that the meta-data needs to be
                                      turing complete ;O( I can not think of a way of encoding the rules such
                                      that they can be all defined by simple rules.

                                      I am beginning to think that the only way to do this without going insane
                                      is to define a simple set of data holders in xml, and a character/rule
                                      framework in Java, then implement a concrete instance of the DnD rules.

                                      So just define an XML character as a series of progressions, ranks,
                                      entities and effects. But have all of the rules for manipulating them in
                                      the Java layer.

                                      I think that everything can be defined in simple XML, I just do not
                                      believe that it can be manipulated without a fully featured turing machine
                                      ;o(

                                      --
                                      regards,
                                      Frugal
                                      -OS Chimp
                                    • Keith Davies
                                      ... It depends on the particular race. Humans are defined as advance by class , so their racial progression (race.human) contains instructions to add a class
                                      Message 18 of 18 , Apr 2, 2004
                                      • 0 Attachment
                                        On Fri, Apr 02, 2004 at 09:25:45AM +0100, Frugal wrote:
                                        >
                                        > <quote who="Keith Davies">
                                        > > On Thu, Apr 01, 2004 at 01:06:07PM +0100, Frugal wrote:
                                        > >> So in the above example adding a rank of "race.human" caused the
                                        > >> addition of a rank of characterlevel which in turn causeed the adition
                                        > >> of the rank of "class.fighter".
                                        > >
                                        > > Yes. It seems a little odd, but it works, and can cover racial
                                        > > differences and effects at various 'levels' (HD and/or origins of
                                        > > changes).
                                        >
                                        > In the first of your examples the progression was like this:
                                        >
                                        > <character>
                                        > <add:rank key='race.human'>
                                        > <add:rank key='characterlevel' />
                                        > </add:rank>
                                        > <add:rank key='race.human'>
                                        > <add:rank key='characterlevel' />
                                        > </add:rank>
                                        > </character>
                                        >
                                        > And in the next two it was:
                                        >
                                        > <character>
                                        > <add:rank key='race.cat' />
                                        > <add:rank key='characterlevel' />
                                        > <add:rank key='characterlevel' />
                                        > <add:rank key='characterlevel' />
                                        > <add:rank key='characterlevel' />
                                        > </character>
                                        >
                                        > So are you saying that a character is made up of ranks of race (which
                                        > have ranks of characterlevel), but that a character can also be made
                                        > up of just ranks of characterlevel?

                                        It depends on the particular race.

                                        Humans are defined as 'advance by class', so their racial progression
                                        (race.human) contains instructions to add a class level at each rank of
                                        race.human.

                                        Cats, on the other hand, are animals and would have a simple HD
                                        advancement scheme. They don't (normally) get character levels. As a
                                        result, race.cat does not contain 'add class level' in its definition.
                                        However, class levels can still be added in addition to HD advancement.

                                        > >> However the character level progression does not know about the race
                                        > >> progression (i.e. +4 skill points to character level 1 if race=human).
                                        > >
                                        > > true, but the race progression *does* (or rather, can) know to give the
                                        > > additional skill points.
                                        >
                                        > - So the client asks that character for skill points at level 1.
                                        > - The Character has no explicit value fo skillpoints
                                        > - The Character looks at rank:1 which is race.human.
                                        > - The Character asks rank:1 for skillpoints
                                        > - The race.human:1 has a formula for calculating skillpoints:
                                        > characterlevel_skillpoints * 4
                                        > - The race rank asks the character level rank for skillpoints
                                        > - The character level rank does not have an explicit value for
                                        > skillpoints, so it asks the class rank 1.
                                        > - The Class rank 1 has a formula for calculating skillpoinrts: INT.1 + 2
                                        > - The Class asks the character for the value of INT.1
                                        > - The character looks at all of the bonuses up to rank 1 that apply to
                                        > INT, returns +3 (from client set value to stat).
                                        > - the class returns 3+2 = 5
                                        > - the characterlevel returns 5
                                        > - The race level returns 5*4 = 20
                                        > - The character returns 20
                                        > - The client displays the value 20.

                                        That looks about right. Lots of steps (sad) but I think it tracks
                                        everything necessary.

                                        > >> So the characterlevel progression has to hold the counter of the skill
                                        > >> point pool which is determined by the class rank in the characterlevel
                                        > >> rank, plus the race, plus all of the other entities. Plus the fact
                                        > >> that this can all change from level to level...
                                        > >
                                        > > Not quite, I think, *if* we require that the points be spent at each
                                        > > level -- as the rule state they must be. If we do that, we get points
                                        > > from *this* class level, and possibly a bonus for race at *this* level.
                                        >
                                        > For a whole raft of things I think we are going to need to be able to
                                        > say: "What is the value of this at level x".
                                        >
                                        > for hit points we are going to want to know how many hit points were
                                        > given at each level.
                                        >
                                        > For skill points we need to know how many skill points are available
                                        > at each level
                                        >
                                        > For a lot of formulas we need to know what the value of a variable was
                                        > at a certain level (i.e. for skill points at level 5 we need the
                                        > intelligence modifier for level 5).

                                        I think it's the right way to go to ensure characters that are legal all
                                        the way through, and can be rolled back if necessary.

                                        > The more I look at this the more I think that the meta-data needs to be
                                        > turing complete ;O( I can not think of a way of encoding the rules such
                                        > that they can be all defined by simple rules.
                                        >
                                        > I am beginning to think that the only way to do this without going insane
                                        > is to define a simple set of data holders in xml, and a character/rule
                                        > framework in Java, then implement a concrete instance of the DnD rules.

                                        Probably, though I was trying to keep it a little more abstract. OTOH,
                                        as long as the pieces can be subbed out it shouldn't be too ugly.

                                        Heh, I just remembered the framework UML I did up... GameEngine is
                                        abstract -- it can be replaced. I was hoping it wouldn't be needed, but
                                        ah well.

                                        > So just define an XML character as a series of progressions, ranks,
                                        > entities and effects. But have all of the rules for manipulating them in
                                        > the Java layer.

                                        This isn't quite what I *want*, but I think it will be necessary. It
                                        should be possible to define primitives that are used by the data. For
                                        instance, adding a small rule for 'bastard weapons' into code, then just
                                        hooking onto it for weapon definitions, rather than trying to encode the
                                        mess in data.

                                        I'm not happy about that, but I'm willing to be pragmatic.

                                        > I think that everything can be defined in simple XML, I just do not
                                        > believe that it can be manipulated without a fully featured turing machine
                                        > ;o(

                                        You're probably right. Right now, everything is being done by code.
                                        Ideally I'd reduce that to 'engine is in code, specifics are in data'
                                        but it looks like that won't be feasible. 'Engine plus (extensible)
                                        primitives in code, rest in data' could probably be done, though.


                                        Keith
                                        --
                                        Keith Davies I gave my 2yo daughter a strawberry
                                        keith.davies@... Naomi: "Strawberry!"
                                        me: "What do you say?"
                                        Naomi: "*MY* strawberry!"
                                      Your message has been successfully submitted and would be delivered to recipients shortly.