Ability Category

From PCGen Wiki
Jump to: navigation, search

Background

This information is taken from a thread on PCGen_experimental from 2008. It originated in concerns related to how ABILITYCATEGORY is used vs. the CATEGORY term, and resulted in a realization that the Category for Ability serves multiple purposes. The original explanation, and this document, are designed to educate those dealing with Ability Categories in order to help resolve any confusion.

Status

There is no quick fix, and we may or may not even want to fix it. We at least need to have everyone understand all of the issues, and this isn't a problem currently scheduled to be addressed in any release of PCGen.


Uses of Category

This document uses POOL for the number of Abilities that can be selected in a set of Abilities (e.g. Wizard Feat) - done as a convenient term to distinguish it from the term GROUP. The number of choices available within a particular Ability is best referred to as "SELECT" or "NUMCHOICES" to match the token/control string names.

Depending on your point of view, an ABILITYCATEGORY can serve as many different things. Here are the functions that ABILITYCATEGORY performs:

Usage 1 - SUPERKEY

When an Ability is created, it is assigned to a CATEGORY:. This is the "SUPERKEY" usage of an ABILITYCATEGORY, or what I referred to earlier as an "Ability CATEGORY". When you refer again to this object, you must refer to it by both the CATEGORY and the key. You can see this in a .MOD: CATEGORY=Mutation|Foo.MOD ...

Usage 2&3 - UNIVERSALSET and SUBSET

When you create an ABILITYCATEGORY, you also assign it a CATEGORY. Only Abilities of that Ability CATEGORY can be placed into the ABILITYCATEGORY. This serves multiple purposes:

First, if the ABILITYCATEGORY name matches the Ability CATEGORY: name, it effectively initializes the "UNIVERSALSET" for a given Ability CATEGORY, e.g.: ABILITYCATEGORY:FEAT CATEGORY:FEAT Note that a line that defines the "UNIVERSALSET" will have NO TYPE on it, and the method used to add to the "UNIVERSALSET" is to place the Ability CATEGORY: token into an Ability (or use a FEAT PCC file for CATEGORY:FEAT). I do not believe it is possible to initialize a "UNIVERSALSET" implicitly (FEAT being the exception, as it's magical for backwards compatibility)

Second, there is the "SUBSET" usage of ABILITYCATEGORY. When an ABILITYCATEGORY is defined where the ABILITYCATEGORY name doesn't match the Ability CATEGORY:, then the TYPE token in ABILITYCATEGORY is used to specify the Abilities that are available in the "SUBSET" of the "UNIVERALSET" for that Ability CATEGORY:.

Third, as each "SUBSET" must draw from a single "UNIVERSALSET", the "SUPERKEY" of an Ability placed within a "SUBSET" is known, simply by being given the "SUBSET" name, as you can query the Ability CATEGORY of the ABILITYCATEGORY.

Usage 4 - GROUP

When an Ability is actually applied to a PC, it places the Ability into a "GROUP". You can assign a given Ability to any ABILITYCATEGORY which uses that Ability CATEGORY "SUPERKEY", e.g.: ABILITYCATEGORY:Fighter Feat CATEGORY:FEAT ... ABILITYCATEGORY:FEAT CATEGORY:FEAT

allows:
ADD:ABILITY|FEAT|AUTOMATIC|Toughness
ADD:ABILITY|Fighter Feat|AUTOMATIC|Toughness

Note that the category in this case is being used in the "GROUP" sense, meaning that the Toughness FEAT ("SUPERKEY" sense) is being placed into the ABILITYCATEGORY specified.

  • Question 1) Is the system capable of testing for the appropriate SUBSET? In other

words, can I trick the system by doing: ADD:ABILITY|Wizard Feat|AUTOMATIC|Toughness ...even though Toughness isn't in the Wizard Feat subset, but it might succeed because the "UNIVERSALSET" ABILITYCATEGORY is the same?

Usage 5 - POOL

You may also specify a "POOL" for the ABILITYCATEGORY, which may allow selection by the user. This is pretty obvious, as we all seem to be familiar with the fact that you can BONUS:ABILITYPOOL|Fighter Feat|1 or something similar. Once a point is available in the "POOL", the user can fill that "slot" with an Ability of that ABILITYCATEGORY. This effectively is a sub-behavior of GROUP, since the use of a point in the POOL (filling the slot, so to speak), effectively adds the Ability to the "GROUP" with Nature=NORMAL.

I'd note that the POOL is distinguished from GROUP, as the AUTOMATIC example shows: ADD:ABILITY|Fighter Feat|AUTOMATIC|Toughness

No POOL is charged in this case (NORMAL would charge the pool), so the POOL concept and the GROUP concept are related, but distinct (based on the nature). Everything filling the POOL of an ABILITYCATEGORY is therefore part of the ABILITYCATEGORY's GROUP, but only items in the GROUP that are Nature NORMAL are part of the POOL.

Discussion

The issue is that it's really tricky to separate these without breaking them. Clearly, the GROUP and POOL can't be separated, because that's contortion over the Nature, and the separation would cause more problems than it's worth. It may be possible to separate out the "*SET" pieces from the GROUP/POOL, though the close relationship of the SUPERKEY behavior with UNIVERALSET (they are the same thing from different points of view) means those need to stay together. So we have: SUPERKEY/UNIVERSALSET/SUBSET and GROUP/POOL...

Maybe this can be split, but it requires a lot more consideration.

Now the interesting aspects that are adding to the confusion: CATEGORY= is being used multiple ways. Note above the .MOD example: CATEGORY=Mutation|Foo.MOD ...

This requires that you are using the "SUPERKEY" usage, which means it must be a CATEGORY that is a "UNIVERSALSET" not a "SUBSET".

Then later in the code when we do CATEGORY=x, we swap that out to allow any ABILITYCATEGORY: PREABILITY:1,CATEGORY=Wizard Feat,Foo This is using the "GROUP" definition of ABILITYCATEGORY, meaning "Is Foo taken in the Wizard Feat GROUP"

Worse, when PREABILITY:1,CATEGORY=FEAT,Foo ...is used, I'm actually unsure of the behavior. One could consider it to remain in "GROUP" mode, but it's also possible that the CATEGORY= CHANGES from the "GROUP" definition to the a "UNIVERSALGROUP" definition, meaning "Is Foo taken in any ABILITYCATEGORY GROUP where the GROUP is part of a SUBSET that was formed from the UNIVERSALSET for the given CATEGORY". I'd actually have to test it to figure out the behavior.

This last ambiguity in the use of CATEGORY= is actually what drives another issue with converting: you can't use CATEGORY for the name for either subset of function that you create, because the behavior of PREABILITY will be set, and you can't alter that behavior. Therefore, we may need to use "GROUP" for the "SUPERKEY/UNIVERSALSET/SUBSET" and "POOL" for the "GROUP/POOL"... unless we can come up with better names. Confused? Good.

Note also ABILITY and ADD:ABILITY, both imply the CATEGORY= by position in the token...and use the later usage ("GROUP"), where any ABILITYCATEGORY is allowed.