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

[ARCH] Requirements on the Character Data Store

Expand Messages
  • Tom Parker
    Kar asked a bit ago about using the Graph implementation, but I mentioned that was premature. In this, err, chapter ;) I m going to walk through some of the
    Message 1 of 5 , Jun 19, 2009
    • 0 Attachment
      Kar asked a bit ago about using the Graph implementation, but I mentioned that was premature. In this, err, chapter ;) I'm going to walk through some of the reasoning behind the graph structure we have and some background on the proposal we currently have. This basically sets up requirements. I'll walk through a series of thought cases as we go along, and later I'll address specific usage.

      In particular, this note refers to the Character Data Store. This is how a PlayerCharacter is stored in the memory of PCGen during runtime. It is effectively a database of sorts, with the primary purpose being data storage (vs. behavioral code). At some point, it is a reasonable discussion to have whether we should be using a database for this function or whether it is better served by objects (not to say those are mutually exclusive, given Hibernate and similar object-relational mapping technologies)

      One other note on terminology: You will see me refer to "PObjects". PObject is currently a parent class of things like Feats, Skills, and Templates. This is therefore a "catch all" name for "things that can be given to a PlayerCharacter". Much of the original structure of PObject has been removed and consolidated to PObject's new parent class, CDOMObject. Eventually PObject will be removed, but for the moment, much of what we have written and the historical naming is "PObject", so I will continue to use that name for now.

      I've already observed that the associations between objects is not a pure tree, but rather a mathematical graph. There can be multiple associations to a given PObject. For example, a Template and a piece of Equipment could grant a particular Skill.

      From the perspective of usage, There are common, but mathematically sparse associations between PObjects. (The ratio of associations between implemented PObjects to implemented PObjects to is well below 2:1). This is relevant to how associations are stored; while it is a valid way to store associations in a very dense group, for our purposes, it is not efficient to an array of BitSet to indicate the object association. . . ick!

      At a high level, graphs generally contain nodes and edges. The edges provide connections between the nodes. In the proposed structure, the PObjects will be nodes. Each PObject will contain the static information (information that is universal across all usages of that object, such as the Dexterity Prerequisite for the Dodge Feat) that is associated with that particular PObject. Dynamic information (that which is particular to a PlayerCharacter, such as the value of an ability score) is stored within an edge.

      Each Node is completely ignorant about what it is connected to. Each edge will contain the source Node and sink Node to which it is connected. A master PCGenGraph object stores the list of Nodes and Edges in the Graph, and can be queried to getAdjacentEdgesToNode(Node n). This design is appropriate for a sparse graph, and produces a directed, acyclic graph of classes (which is a good design principle). Since the base design only stores information in one place, there are no risks of putting the graph into an invalid state (from a structural perspective - from a role playing rules perspective, we still have to prove that principle). There are some abilities to cache information (such as the Node to Edge relationships) with an implementation of the Graph for boosted performance, while maintaining any duplication within a single class (avoiding contracts on the programmer and ensuring that the graph avoids an invalid state). Currently, the Graph classes are much like the basic Collections classes and are not designed to be used in a multi-threaded environment.

      As we develop the characteristics of the graph, we need to look at some of the reasons why we are moving our data structure. Note that unlike the Rules Persistence System code (which was integrated into PCGen 5.16 and is in the Trunk), the graph code can only be found in an experimental branch. If you check out branches/cdom from our code repository, the packages are pcgen.base.graph.*

      One of these is performance. Currently, the recursive nature of addition (A adds B, B adds C, C adds D) can get very tricky to keep correct when the addition process for different object types is a different method (recursive loops are painful). This can be done with a "graft" ob objects from the rules data store into the character data store. There is also a strong desire to have a single processing method for adding objects to a PlayerCharacter, vs. separate methods that depend on the type of PObject being processed.

      Second, some significant functions that need to be able to trace the source of an object. Therefore, the graph must track how a particular PObject came to be associated with the PlayerCharacter. (e.g. Chose Combat Reflexes as a feat at third level and Weapon Focus (Dagger) as a first level fighter bonus feat.)

      Third, it would be nice to avoid clutter. Certain Edges will provide the ability to have a `weight' so that an object which provides multiple levels of a Skill can avoid multiple edges connecting the same PObjects (in addition to cluttering the graph, multiple identical edges create identity/equality risk and make identification and removal of edges more difficult).

      As a note, while we have a graph, there are consequences to using the concept of hyperedges and having more than one source node in an edge. One specific counter-case is: How do you manage skill rank?
      Foo1 grants Knowledge (Arcana) Rank 2
      and
      Foo2 grants Knowledge (Arcana) Rank 1
      ...So the PC has rank 3... With only one edge leading into the single reference to the Knowledge (Arcana) skill, how do you distinguish that one source has "weight" 2 and one "weight" 1? (This assumes that the weight, as PC specific information, must be in the edge. Combining these two rank grants into one edge may result in another map in (or from) the edge to measure source weight or some other external method of storing rank that results in either contract issues (programmer has to do 2 things to maintain consistent state) or more complex data structures than simply a system that uses two separate edges.

      So in summary, the Character Data Store needs to:
      (A) Store items granted to the PC (such as a Feat)
      (B) Store items available to the PC (such as a starting language list)
      (C) Quickly answer "does the character have X" queries
      (D) Not confuse availability with granting
      (E) Track the source of every grant and availability
      (F) Be able to cleanly handle MULT:NO v. MULT:YES
      (G) Track exact sources (there are some nasty cases I will draw out later)
      (H) Handle removal of one MULT:NO parent while another is present to maintain the state (such as a user selection of a CHOOSE)
      (I) Appropriately store a CHOOSE result so it can be reused by other tokens/objects (so it has to be stored in a predictable location)
      (J) Replicate behavior from the existing tokens in PCGen 5.16.
      (K) It should also avoid making the assumption that it's a d20 system. Assume it needs to handle Rolemaster & Serenity if you're looking for particular challenges.
      (L) Handle undo/redo.

      We can also set up some structural rules...

      (1) It must be a directed acyclic graph, with no cycles in the code. (And the use of an interface solely to break a cycle is sometimes, but not always indicative of a structural problem)
      (2) When a developer makes a code modification, the developer should not be forced to make a matching modification in another location in the code in order to maintain a valid structure (no contracts, as I would call them)
      (3) When a change is made to the internal data structure, a significant amount of "reorganization" to ensure a valid data structure should not be necessary (if you're incrementing through everything, then that's not good)
      (4) It should be fully unit testable, without major dependencies on other objects. (some will be expected)
      (5) It should have as simple of an interface as reasonably possible (if you're beyond 20 methods, you probably have a problem)
      (6) It will not expose its internal state to external modification other than through direct method calls.
      (7) You must not consume any errors (no catch Throwable or anything like that)
      (8) It should not produce side effects - methods do one thing. No surprises for the uninitiated.
      (9) It should be a class that does one thing.
      (10) You must assume CDOMObjects are not cloneable.
      (11) It should minimize special cases.
      (12) It should have no knowledge of the UI
      (13) It should minimize the number of mental models another programmer needs to learn (see 11)
      (14) It should be built with as few classes as reasonably possible (but not at the expense of clarity or requirement (9) above.)
      (15) Pools (e.g. skill points) must be stored in something that can be recalculated from a known good source. Simply a numerical map that developers are trusted to update correctly is not appropriate. We have demonstrated the challenges of that model in 5.x.
      (16) Known patterns / data structures should be used when appropriate (see 13)
      Recommendation: Type Safety is good

      This is a setup of requirements for the system. Feel free to add to the list if you think I've missed anything. I probably have. I'm going to refer back to these as I go through further explanations. There are specific requirements that are drawn from certain thought cases, and some details of the implementation that are driven by such situations. There are still some unresolved issues as well (and some nuances that we could use some elegant solutions for to avoid brute force fixes)

      TP.
    • Andrew Maitland
      reading and enjoying, don t stop please.
      Message 2 of 5 , Jun 25, 2009
      • 0 Attachment
        reading and enjoying, don't stop please.

        Tom Parker wrote:
        >
        >
        > Kar asked a bit ago about using the Graph implementation, but I
        > mentioned that was premature. In this, err, chapter ;) I'm going to
        > walk through some of the reasoning behind the graph structure we have
        > and some background on the proposal we currently have. This basically
        > sets up requirements. I'll walk through a series of thought cases as
        > we go along, and later I'll address specific usage.
        >
        > In particular, this note refers to the Character Data Store. This is
        > how a PlayerCharacter is stored in the memory of PCGen during runtime.
        > It is effectively a database of sorts, with the primary purpose being
        > data storage (vs. behavioral code). At some point, it is a reasonable
        > discussion to have whether we should be using a database for this
        > function or whether it is better served by objects (not to say those
        > are mutually exclusive, given Hibernate and similar object-relational
        > mapping technologies)
        >
        > One other note on terminology: You will see me refer to "PObjects".
        > PObject is currently a parent class of things like Feats, Skills, and
        > Templates. This is therefore a "catch all" name for "things that can
        > be given to a PlayerCharacter". Much of the original structure of
        > PObject has been removed and consolidated to PObject's new parent
        > class, CDOMObject. Eventually PObject will be removed, but for the
        > moment, much of what we have written and the historical naming is
        > "PObject", so I will continue to use that name for now.
        >
        > I've already observed that the associations between objects is not a
        > pure tree, but rather a mathematical graph. There can be multiple
        > associations to a given PObject. For example, a Template and a piece
        > of Equipment could grant a particular Skill.
        >
        > >From the perspective of usage, There are common, but mathematically
        > sparse associations between PObjects. (The ratio of associations
        > between implemented PObjects to implemented PObjects to is well below
        > 2:1). This is relevant to how associations are stored; while it is a
        > valid way to store associations in a very dense group, for our
        > purposes, it is not efficient to an array of BitSet to indicate the
        > object association. . . ick!
        >
        > At a high level, graphs generally contain nodes and edges. The edges
        > provide connections between the nodes. In the proposed structure, the
        > PObjects will be nodes. Each PObject will contain the static
        > information (information that is universal across all usages of that
        > object, such as the Dexterity Prerequisite for the Dodge Feat) that is
        > associated with that particular PObject. Dynamic information (that
        > which is particular to a PlayerCharacter, such as the value of an
        > ability score) is stored within an edge.
        >
        > Each Node is completely ignorant about what it is connected to. Each
        > edge will contain the source Node and sink Node to which it is
        > connected. A master PCGenGraph object stores the list of Nodes and
        > Edges in the Graph, and can be queried to getAdjacentEdgesToNode(Node
        > n). This design is appropriate for a sparse graph, and produces a
        > directed, acyclic graph of classes (which is a good design principle).
        > Since the base design only stores information in one place, there are
        > no risks of putting the graph into an invalid state (from a structural
        > perspective - from a role playing rules perspective, we still have to
        > prove that principle). There are some abilities to cache information
        > (such as the Node to Edge relationships) with an implementation of the
        > Graph for boosted performance, while maintaining any duplication
        > within a single class (avoiding contracts on the programmer and
        > ensuring that the graph avoids an invalid state). Currently, the Graph
        > classes are much like the basic Collections classes and are not
        > designed to be used in a multi-threaded environment.
        >
        > As we develop the characteristics of the graph, we need to look at
        > some of the reasons why we are moving our data structure. Note that
        > unlike the Rules Persistence System code (which was integrated into
        > PCGen 5.16 and is in the Trunk), the graph code can only be found in
        > an experimental branch. If you check out branches/cdom from our code
        > repository, the packages are pcgen.base.graph.*
        >
        > One of these is performance. Currently, the recursive nature of
        > addition (A adds B, B adds C, C adds D) can get very tricky to keep
        > correct when the addition process for different object types is a
        > different method (recursive loops are painful). This can be done with
        > a "graft" ob objects from the rules data store into the character data
        > store. There is also a strong desire to have a single processing
        > method for adding objects to a PlayerCharacter, vs. separate methods
        > that depend on the type of PObject being processed.
        >
        > Second, some significant functions that need to be able to trace the
        > source of an object. Therefore, the graph must track how a particular
        > PObject came to be associated with the PlayerCharacter. (e.g. Chose
        > Combat Reflexes as a feat at third level and Weapon Focus (Dagger) as
        > a first level fighter bonus feat.)
        >
        > Third, it would be nice to avoid clutter. Certain Edges will provide
        > the ability to have a `weight' so that an object which provides
        > multiple levels of a Skill can avoid multiple edges connecting the
        > same PObjects (in addition to cluttering the graph, multiple identical
        > edges create identity/equality risk and make identification and
        > removal of edges more difficult).
        >
        > As a note, while we have a graph, there are consequences to using the
        > concept of hyperedges and having more than one source node in an edge.
        > One specific counter-case is: How do you manage skill rank?
        > Foo1 grants Knowledge (Arcana) Rank 2
        > and
        > Foo2 grants Knowledge (Arcana) Rank 1
        > ...So the PC has rank 3... With only one edge leading into the single
        > reference to the Knowledge (Arcana) skill, how do you distinguish that
        > one source has "weight" 2 and one "weight" 1? (This assumes that the
        > weight, as PC specific information, must be in the edge. Combining
        > these two rank grants into one edge may result in another map in (or
        > from) the edge to measure source weight or some other external method
        > of storing rank that results in either contract issues (programmer has
        > to do 2 things to maintain consistent state) or more complex data
        > structures than simply a system that uses two separate edges.
        >
        > So in summary, the Character Data Store needs to:
        > (A) Store items granted to the PC (such as a Feat)
        > (B) Store items available to the PC (such as a starting language list)
        > (C) Quickly answer "does the character have X" queries
        > (D) Not confuse availability with granting
        > (E) Track the source of every grant and availability
        > (F) Be able to cleanly handle MULT:NO v. MULT:YES
        > (G) Track exact sources (there are some nasty cases I will draw out later)
        > (H) Handle removal of one MULT:NO parent while another is present to
        > maintain the state (such as a user selection of a CHOOSE)
        > (I) Appropriately store a CHOOSE result so it can be reused by other
        > tokens/objects (so it has to be stored in a predictable location)
        > (J) Replicate behavior from the existing tokens in PCGen 5.16.
        > (K) It should also avoid making the assumption that it's a d20 system.
        > Assume it needs to handle Rolemaster & Serenity if you're looking for
        > particular challenges.
        > (L) Handle undo/redo.
        >
        > We can also set up some structural rules...
        >
        > (1) It must be a directed acyclic graph, with no cycles in the code.
        > (And the use of an interface solely to break a cycle is sometimes, but
        > not always indicative of a structural problem)
        > (2) When a developer makes a code modification, the developer should
        > not be forced to make a matching modification in another location in
        > the code in order to maintain a valid structure (no contracts, as I
        > would call them)
        > (3) When a change is made to the internal data structure, a
        > significant amount of "reorganization" to ensure a valid data
        > structure should not be necessary (if you're incrementing through
        > everything, then that's not good)
        > (4) It should be fully unit testable, without major dependencies on
        > other objects. (some will be expected)
        > (5) It should have as simple of an interface as reasonably possible
        > (if you're beyond 20 methods, you probably have a problem)
        > (6) It will not expose its internal state to external modification
        > other than through direct method calls.
        > (7) You must not consume any errors (no catch Throwable or anything
        > like that)
        > (8) It should not produce side effects - methods do one thing. No
        > surprises for the uninitiated.
        > (9) It should be a class that does one thing.
        > (10) You must assume CDOMObjects are not cloneable.
        > (11) It should minimize special cases.
        > (12) It should have no knowledge of the UI
        > (13) It should minimize the number of mental models another programmer
        > needs to learn (see 11)
        > (14) It should be built with as few classes as reasonably possible
        > (but not at the expense of clarity or requirement (9) above.)
        > (15) Pools (e.g. skill points) must be stored in something that can be
        > recalculated from a known good source. Simply a numerical map that
        > developers are trusted to update correctly is not appropriate. We have
        > demonstrated the challenges of that model in 5.x.
        > (16) Known patterns / data structures should be used when appropriate
        > (see 13)
        > Recommendation: Type Safety is good
        >
        > This is a setup of requirements for the system. Feel free to add to
        > the list if you think I've missed anything. I probably have. I'm going
        > to refer back to these as I go through further explanations. There are
        > specific requirements that are drawn from certain thought cases, and
        > some details of the implementation that are driven by such situations.
        > There are still some unresolved issues as well (and some nuances that
        > we could use some elegant solutions for to avoid brute force fixes)
        >
        > TP.
        >
        >
      • Martijn Verburg
        Hi Tom, ... Who is this Kar person who keeps causing trouble like this, ban them from the project I say! ;p ... I was just about to ask about that, it seems
        Message 3 of 5 , Jul 21, 2009
        • 0 Attachment
          Hi Tom,

          > Kar asked a bit ago about using the Graph implementation, but I
          > mentioned that was premature. In this, err, chapter ;) I'm going
          > to walk through some of the reasoning behind the graph structure we
          > have and some background on the proposal we currently have. This
          > basically sets up requirements. I'll walk through a series of
          > thought cases as we go along, and later I'll address specific usage.

          Who is this Kar person who keeps causing trouble like this, ban them from the project I say! ;p

          > In particular, this note refers to the Character Data Store. This
          > is how a PlayerCharacter is stored in the memory of PCGen during
          > runtime. It is effectively a database of sorts, with the primary
          > purpose being data storage (vs. behavioral code). At some point,
          > it is a reasonable discussion to have whether we should be using a
          > database for this function or whether it is better served by
          > objects (not to say those are mutually exclusive, given Hibernate
          > and similar object-relational mapping technologies).

          I was just about to ask about that, it seems that small lightweight DBs are being used in this fashion, but as you say a discussion for another (much later) day.

          > One other note on terminology: You will see me refer to
          > "PObjects". PObject is currently a parent class of things like
          > Feats, Skills, and Templates. This is therefore a "catch all" name
          > for "things that can be given to a PlayerCharacter". Much of the
          > original structure of PObject has been removed and consolidated to
          > PObject's new parent class, CDOMObject. Eventually PObject will be
          > removed, but for the moment, much of what we have written and the
          > historical naming is "PObject", so I will continue to use that name
          > for now.

          OK, I long to see the day where PObject dies (a noble death after its long service, but a death all the same).

          > I've already observed that the associations between objects is not
          > a pure tree, but rather a mathematical graph. There can be
          > multiple associations to a given PObject. For example, a Template
          > and a piece of Equipment could grant a particular Skill.
          >
          > From the perspective of usage, There are common, but mathematically
          > sparse associations between PObjects. (The ratio of associations
          > between implemented PObjects to implemented PObjects to is well
          > below 2:1). This is relevant to how associations are stored; while
          > it is a valid way to store associations in a very dense group, for
          > our purposes, it is not efficient to an array of BitSet to indicate
          > the object association. . . ick!
          >
          > At a high level, graphs generally contain nodes and edges. The
          > edges provide connections between the nodes. In the proposed
          > structure, the PObjects will be nodes. Each PObject will contain
          > the static information (information that is universal across all
          > usages of that object, such as the Dexterity Prerequisite for the
          > Dodge Feat) that is associated with that particular PObject.
          > Dynamic information (that which is particular to a PlayerCharacter,
          > such as the value of an ability score) is stored within an edge.

          OK, I get that.

          > Each Node is completely ignorant about what it is connected to.
          > Each edge will contain the source Node and sink Node to which it is
          > connected. A master PCGenGraph object stores the list of Nodes and
          > Edges in the Graph, and can be queried to
          > getAdjacentEdgesToNode(Node n). This design is appropriate for a
          > sparse graph, and produces a directed, acyclic graph of classes
          > (which is a good design principle). Since the base design only
          > stores information in one place, there are no risks of putting the
          > graph into an invalid state (from a structural perspective - from a
          > role playing rules perspective, we still have to prove that
          > principle). There are some abilities to cache information (such as
          > the Node to Edge relationships) with an implementation of the Graph
          > for boosted performance, while maintaining any duplication within a
          > single class (avoiding contracts on the programmer and ensuring
          > that the graph avoids an invalid state). Currently, the Graph
          > classes are much like the basic Collections classes and are not
          > designed to be used in a multi-threaded environment.

          OK...

          > As we develop the characteristics of the graph, we need to look at
          > some of the reasons why we are moving our data structure. Note
          > that unlike the Rules Persistence System code (which was integrated
          > into PCGen 5.16 and is in the Trunk), the graph code can only be
          > found in an experimental branch. If you check out branches/cdom
          > from our code repository, the packages are pcgen.base.graph.*
          >
          > One of these is performance. Currently, the recursive nature of
          > addition (A adds B, B adds C, C adds D) can get very tricky to keep
          > correct when the addition process for different object types is a #
          > different method (recursive loops are painful). This can be done
          > with a "graft" ob objects from the rules data store into the
          > character data store. There is also a strong desire to have a
          > single processing method for adding objects to a PlayerCharacter,
          > vs. separate methods that depend on the type of PObject being
          > processed.
          >
          > Second, some significant functions that need to be able to trace
          > the source of an object. Therefore, the graph must track how a
          > particular PObject came to be associated with the PlayerCharacter.
          > (e.g. Chose Combat Reflexes as a feat at third level and Weapon
          > Focus (Dagger) as a first level fighter bonus feat.)

          Makes sense, this is important for if a character loses something which gave him/her the ability to do something else.

          > Third, it would be nice to avoid clutter. Certain Edges will
          > provide the ability to have a `weight' so that an object which
          > provides multiple levels of a Skill can avoid multiple edges
          > connecting the same PObjects (in addition to cluttering the graph,
          > multiple identical edges create identity/equality risk and make
          > identification and removal of edges more difficult).

          So a +skill edge could give +1, +3, +5 etc over its 'lifetime' as opposed to having 3 separate +skill edges of +1, +3 and +5?

          > As a note, while we have a graph, there are consequences to using
          > the concept of hyperedges and having more than one source node in
          > an edge. One specific counter-case is: How do you manage skill
          > rank?
          > Foo1 grants Knowledge (Arcana) Rank 2
          > and
          > Foo2 grants Knowledge (Arcana) Rank 1
          > ...So the PC has rank 3... With only one edge leading into the
          > single reference to the Knowledge (Arcana) skill, how do you
          > distinguish that one source has "weight" 2 and one "weight" 1?
          > (This assumes that the weight, as PC specific information, must be
          > in the edge. Combining these two rank grants into one edge may
          > result in another map in (or from) the edge to measure source
          > weight or some other external method of storing rank that results
          > in either contract issues (programmer has to do 2 things to
          > maintain consistent state) or more complex data structures than
          > simply a system that uses two separate edges.

          OK ignore my previous bit as a question.

          > So in summary, the Character Data Store needs to:
          > (A) Store items granted to the PC (such as a Feat)
          > (B) Store items available to the PC (such as a starting language
          > list)
          > (C) Quickly answer "does the character have X" queries
          > (D) Not confuse availability with granting
          > (E) Track the source of every grant and availability
          > (F) Be able to cleanly handle MULT:NO v. MULT:YES
          > (G) Track exact sources (there are some nasty cases I will draw out
          > later)
          > (H) Handle removal of one MULT:NO parent while another is present
          > to maintain the state (such as a user selection of a CHOOSE)
          > (I) Appropriately store a CHOOSE result so it can be reused by
          > other tokens/objects (so it has to be stored in a predictable
          > location)
          > (J) Replicate behavior from the existing tokens in PCGen 5.16.
          > (K) It should also avoid making the assumption that it's a d20
          > system. Assume it needs to handle Rolemaster & Serenity if you're
          > looking for particular challenges.
          > (L) Handle undo/redo.
          >
          > We can also set up some structural rules...
          >
          > (1) It must be a directed acyclic graph, with no cycles in the
          > code. (And the use of an interface solely to break a cycle is
          > sometimes, but not always indicative of a structural problem)
          > (2) When a developer makes a code modification, the developer
          > should not be forced to make a matching modification in another
          > location in the code in order to maintain a valid structure (no
          > contracts, as I would call them)
          > (3) When a change is made to the internal data structure, a
          > significant amount of "reorganization" to ensure a valid data
          > structure should not be necessary (if you're incrementing through
          > everything, then that's not good)
          > (4) It should be fully unit testable, without major dependencies on
          > other objects. (some will be expected)
          > (5) It should have as simple of an interface as reasonably possible
          > (if you're beyond 20 methods, you probably have a problem)
          > (6) It will not expose its internal state to external modification
          > other than through direct method calls.
          > (7) You must not consume any errors (no catch Throwable or anything
          > like that)
          > (8) It should not produce side effects - methods do one thing. No
          > surprises for the uninitiated.
          > (9) It should be a class that does one thing.
          > (10) You must assume CDOMObjects are not cloneable.
          > (11) It should minimize special cases.
          > (12) It should have no knowledge of the UI
          > (13) It should minimize the number of mental models another
          > programmer needs to learn (see 11)
          > (14) It should be built with as few classes as reasonably possible
          > (but not at the expense of clarity or requirement (9) above.)
          > (15) Pools (e.g. skill points) must be stored in something that
          > can be recalculated from a known good source. Simply a numerical
          > map that developers are trusted to update correctly is not
          > appropriate. We have demonstrated the challenges of that model in
          > 5.x.
          > (16) Known patterns / data structures should be used when
          > appropriate (see 13)
          > Recommendation: Type Safety is good
          >
          > This is a setup of requirements for the system. Feel free to add
          > to the list if you think I've missed anything. I probably have.
          > I'm going to refer back to these as I go through further
          > explanations. There are specific requirements that are drawn from
          > certain thought cases, and some details of the implementation that
          > are driven by such situations. There are still some unresolved
          > issues as well (and some nuances that we could use some elegant
          > solutions for to avoid brute force fixes)

          That's a pretty darn comprehensive list!

          Is this list on the wiki somewhere? I couldn't find it if it is :). If it's not then I'm happy to drop it in where you prefer!

          K
        • Tom Parker
          ... Actually, let s walk through it because it may not be completely clear. If a Skill (let s call it Hide) is granted by Ability Foo and Ability Bar, Hide
          Message 4 of 5 , Jul 21, 2009
          • 0 Attachment
            --- In pcgen_developers@yahoogroups.com, "Martijn Verburg" <martijnverburg@...> wrote:
            > [description of and question on edge weights]

            Actually, let's walk through it because it may not be completely clear.

            If a Skill (let's call it Hide) is granted by Ability Foo and Ability Bar, Hide will have 2 incoming edges. This is true even if Foo grants two ranks.

            The alternative (if edges couldn't have weight) would be for Hide to have 3 incoming edges, two from Foo and one from Bar. I find this to be "cluttered", especially if Foo granted 10 ranks... that leaves a lot of graph traversing for items which could care less about "weight". Using weight as an attribute on the edge allows only those items that really care about weight to do the necessary processing to extract the value from the edge.

            > > So in summary, the Character Data Store needs to:
            > > [snip]
            >
            > That's a pretty darn comprehensive list!
            >
            > Is this list on the wiki somewhere? I couldn't find it if it is :). If it's not then I'm happy to drop it in where you prefer!

            Don't think it is, no.

            TP.
          • Martijn Verburg
            Hi all, ... It is now at: http://wiki.pcgen.org/Character_Data_Store Linked in from the Architecture page as a Open sub project. K
            Message 5 of 5 , Aug 14, 2009
            • 0 Attachment
              Hi all,

              > > That's a pretty darn comprehensive list!
              > >
              > > Is this list on the wiki somewhere? I couldn't find it if it is
              > > :). If it's not then I'm happy to drop it in where you prefer!
              >
              > Don't think it is, no.

              It is now at:

              http://wiki.pcgen.org/Character_Data_Store

              Linked in from the Architecture page as a Open sub project.

              K
            Your message has been successfully submitted and would be delivered to recipients shortly.