Difference between revisions of "SELECTION - A CHOOSE Replacement"

From PCGen Wiki
Jump to: navigation, search
(Created page with "{| align="right" | __TOC__ |} =Introduction= First draft proposal for SELECTION (replaces CHOOSE/supports multiple CHOOSE) Please note that the token names here are for...")
 
 
(3 intermediate revisions by the same user not shown)
Line 5: Line 5:
 
=Introduction=
 
=Introduction=
  
First draft proposal for SELECTION (replaces CHOOSE/supports multiple CHOOSE)
+
First draft proposal for SELECTION (replaces CHOOSE/supports multiple CHOOSE).
  
 
Please note that the token names here are for example purposes.  Some discussion has taken place but they are not  
 
Please note that the token names here are for example purposes.  Some discussion has taken place but they are not  
 
 
finalized.  They are here to show the concepts and how the structures of this new system would work in LST files.
 
finalized.  They are here to show the concepts and how the structures of this new system would work in LST files.
  
Line 28: Line 27:
  
 
CHOOSE currently supports only one selection.  In many cases this produces a challenging format that is forced into the  
 
CHOOSE currently supports only one selection.  In many cases this produces a challenging format that is forced into the  
 
 
code.  If multiple selections were allowed, this would not be necessary, as one could be CLASS and the other LEVEL for  
 
code.  If multiple selections were allowed, this would not be necessary, as one could be CLASS and the other LEVEL for  
 
+
example.
example
 
  
 
===Automatic Expansion===
 
===Automatic Expansion===
  
 
CHOOSE currently automatically expands items.  If you CHOOSE:FEAT, you get things like Weapon Proficiency(x) and Weapon  
 
CHOOSE currently automatically expands items.  If you CHOOSE:FEAT, you get things like Weapon Proficiency(x) and Weapon  
 
 
Proficiency (y).  This also then creates an interesting visual challenge if there are multiple tiers.  If a Feat allows  
 
Proficiency (y).  This also then creates an interesting visual challenge if there are multiple tiers.  If a Feat allows  
 
 
a selection from another MULT:YES feat, then you get Something(a(b)) and Something(a(c)).  This can rapidly proliferate  
 
a selection from another MULT:YES feat, then you get Something(a(b)) and Something(a(c)).  This can rapidly proliferate  
 
 
into a huge list to scroll through.  It would be visually cleaner to select "a" and then select "b or c" within the  
 
into a huge list to scroll through.  It would be visually cleaner to select "a" and then select "b or c" within the  
 
 
context of "a" being selected under "something".  This requires a new UI to handle this hierarchical behavior.
 
context of "a" being selected under "something".  This requires a new UI to handle this hierarchical behavior.
  
 
(This item is not currently addressed further here, as I would like to talk to some of our UI folks before I propose  
 
(This item is not currently addressed further here, as I would like to talk to some of our UI folks before I propose  
 
 
too much here)
 
too much here)
  
Line 64: Line 56:
  
 
This has already been encountered in the past and discussed on the -dev list.  The BONUSes also suffer from the same  
 
This has already been encountered in the past and discussed on the -dev list.  The BONUSes also suffer from the same  
 
 
issue and there have been a few debates over proper behavior.
 
issue and there have been a few debates over proper behavior.
  
 
The solution to this problem is eliminate all ambiguity.  We should to distinguish between the ability itself (applied  
 
The solution to this problem is eliminate all ambiguity.  We should to distinguish between the ability itself (applied  
 
 
only once ever) and what I will call the "instances" of the ability (applied once per time taken by the user).  Note  
 
only once ever) and what I will call the "instances" of the ability (applied once per time taken by the user).  Note  
 
 
that I do NOT say "per selection" or "per choice" because if an item has 3 choices, we still have struggles.  There are  
 
that I do NOT say "per selection" or "per choice" because if an item has 3 choices, we still have struggles.  There are  
 
 
ways to apply once per choice as well, but we need ALL of the capabilities, so we have to have a method to do once per  
 
ways to apply once per choice as well, but we need ALL of the capabilities, so we have to have a method to do once per  
 
 
time taken by the user).
 
time taken by the user).
  
 
From this point onward, I will have an INSTANCE: token that then refers to instances rather than the parent object.   
 
From this point onward, I will have an INSTANCE: token that then refers to instances rather than the parent object.   
 
 
This is much like the current "PART:x|..." token that can appear on equipment to handle equipment heads.  Just like  
 
This is much like the current "PART:x|..." token that can appear on equipment to handle equipment heads.  Just like  
 
 
PART, it will have an argument (as to where it is applied) followed by another full token.
 
PART, it will have an argument (as to where it is applied) followed by another full token.
  
Line 88: Line 73:
  
 
Currently the system defaults to STACK:NO.  Should this be the default behavior when a lot more control exists for the  
 
Currently the system defaults to STACK:NO.  Should this be the default behavior when a lot more control exists for the  
 
 
data to define what is selectable?
 
data to define what is selectable?
  
Line 94: Line 78:
  
 
Part of the reason we have multiple different selection methods is that the code has certain race conditions (two  
 
Part of the reason we have multiple different selection methods is that the code has certain race conditions (two  
 
 
actions that need to happen in a certain order).   
 
actions that need to happen in a certain order).   
  
 
For Race and Template, they get added to the PC first, THEN the selection is made.  This means they have to be  
 
For Race and Template, they get added to the PC first, THEN the selection is made.  This means they have to be  
 
 
defending against undefined choices.  
 
defending against undefined choices.  
  
 
For Abilities, they only get added to the PC when an AbilitySelection object (an ability with its selection) is added  
 
For Abilities, they only get added to the PC when an AbilitySelection object (an ability with its selection) is added  
 
 
to the PlayerCharacter.  This means the selection occurs BEFORE the object is added.
 
to the PlayerCharacter.  This means the selection occurs BEFORE the object is added.
  
Line 113: Line 94:
  
 
Also, since backwards compatibility will not be supported (CHOOSE will not be available in the new formula system at  
 
Also, since backwards compatibility will not be supported (CHOOSE will not be available in the new formula system at  
 
 
least under the current plan), we will need a new token name.  From this point onward, it will be called SELECTION.
 
least under the current plan), we will need a new token name.  From this point onward, it will be called SELECTION.
  
Line 122: Line 102:
  
 
As mentioned above, the Selections will be placed into instances.  These instances are separate objects with a separate  
 
As mentioned above, the Selections will be placed into instances.  These instances are separate objects with a separate  
 
 
SCOPE.  For Skills (For example), the scope will be SKILL.INSTANCE
 
SCOPE.  For Skills (For example), the scope will be SKILL.INSTANCE
  
Line 130: Line 109:
  
 
A naive design would be to keep two lists on the main object.  That way, the first set of choices are [0] in the lists,  
 
A naive design would be to keep two lists on the main object.  That way, the first set of choices are [0] in the lists,  
 
 
the next set [1].  While I don't have a specific rule associated to this, I can quickly come up with some plausible use  
 
the next set [1].  While I don't have a specific rule associated to this, I can quickly come up with some plausible use  
 
 
cases where that would break.  For example: Imagine a feat that allows you to select a class and make 2 skills from the  
 
cases where that would break.  For example: Imagine a feat that allows you to select a class and make 2 skills from the  
 
 
classskilllist of that class get +1 bonus rank.
 
classskilllist of that class get +1 bonus rank.
  
 
Therefore, we delegate containing the result of the selection down into an instance object.  We then make that a  
 
Therefore, we delegate containing the result of the selection down into an instance object.  We then make that a  
 
 
subscope of the main scope for that object type.  Consider the CHOOSE on skills for Speak Language.  We then get  
 
subscope of the main scope for that object type.  Consider the CHOOSE on skills for Speak Language.  We then get  
 
 
something like:
 
something like:
 
   INSTANCE:ALL|SELECTION:SpokenLanguage|LANGUAGE|getAll("LANGUAGE")
 
   INSTANCE:ALL|SELECTION:SpokenLanguage|LANGUAGE|getAll("LANGUAGE")
  
 
Now, every time a new instance of that Skill is selected (which happens to be from getting a new rank of that skill), a  
 
Now, every time a new instance of that Skill is selected (which happens to be from getting a new rank of that skill), a  
 
 
new Instance will be added to the PC and a new selection will need to be made.
 
new Instance will be added to the PC and a new selection will need to be made.
  
Line 154: Line 127:
  
 
To be VERY CLEAR: getSelection("SpokenLanguage") MUST BE USED IN AN INSTANCE.  If you attempt to use it up at the  
 
To be VERY CLEAR: getSelection("SpokenLanguage") MUST BE USED IN AN INSTANCE.  If you attempt to use it up at the  
 
 
parent ability/skill/whatever, it will either (a) fail or (b) be empty.  (It should fail, and we will endeavor to do  
 
parent ability/skill/whatever, it will either (a) fail or (b) be empty.  (It should fail, and we will endeavor to do  
 
 
that, but there will need to be enhancements to have functions available only in a limited scope... that's new effort)
 
that, but there will need to be enhancements to have functions available only in a limited scope... that's new effort)
  
Line 167: Line 138:
  
 
This immediately sets up a problem based on how the formula system works.  Because it only processes items that are  
 
This immediately sets up a problem based on how the formula system works.  Because it only processes items that are  
 
 
actually "granted" to the PC, the MODIFY of MyList would not happen unless the object itself was already granted.  This  
 
actually "granted" to the PC, the MODIFY of MyList would not happen unless the object itself was already granted.  This  
 
 
traps us (a bit) in making sure the object is added to the PC BEFORE a selection is made, so that if it chooses to do  
 
traps us (a bit) in making sure the object is added to the PC BEFORE a selection is made, so that if it chooses to do  
 
 
any list modifications, they can be done BEFORE the selection.
 
any list modifications, they can be done BEFORE the selection.
  
 
To resolve this race condition, we put the MODIFY on the parent object, which is granted BEFORE any selection.  We then  
 
To resolve this race condition, we put the MODIFY on the parent object, which is granted BEFORE any selection.  We then  
 
 
put the SELECTION in the INSTANCE, which is granted AFTER any selection.  Note this also means that if (for some  
 
put the SELECTION in the INSTANCE, which is granted AFTER any selection.  Note this also means that if (for some  
 
 
reason) the data team to have the MODIFY occur AFTER the selection, they have that power.  This gives the data team  
 
reason) the data team to have the MODIFY occur AFTER the selection, they have that power.  This gives the data team  
 
 
full feature, supporting add both BEFORE and AFTER selection:
 
full feature, supporting add both BEFORE and AFTER selection:
  
Line 186: Line 151:
  
 
As a nice side effect, this actually gives us full power to avoid ANY popup windows in a new UI should that be a  
 
As a nice side effect, this actually gives us full power to avoid ANY popup windows in a new UI should that be a  
 
 
feature we want to implement.  Because all instance applications can be deferred, they could be "TODOs" on the PC  
 
feature we want to implement.  Because all instance applications can be deferred, they could be "TODOs" on the PC  
 
 
rather than stopping for user input.
 
rather than stopping for user input.
  
Line 200: Line 163:
  
 
To replace the behavior of SELECT, we need to control the number of actual selections that exist in an instance for  
 
To replace the behavior of SELECT, we need to control the number of actual selections that exist in an instance for  
 
 
that SELECTION.  Since this is associated to the SELECTION, we need to keep it local to that token, so it is appended  
 
that SELECTION.  Since this is associated to the SELECTION, we need to keep it local to that token, so it is appended  
 
 
as an optional control on the SELECTION:
 
as an optional control on the SELECTION:
 
   SELECTION:MySelection|LANGUAGE|getAll("LANGUAGE")|SELECT=2
 
   SELECTION:MySelection|LANGUAGE|getAll("LANGUAGE")|SELECT=2
Line 211: Line 172:
  
 
Please note: ALL objects that are instance-able ALWAYS will produce an instance.  This is true REGARDLESS of whether  
 
Please note: ALL objects that are instance-able ALWAYS will produce an instance.  This is true REGARDLESS of whether  
 
 
there is a SELECTION on the object.  Many of these Instances will be empty shell objects, but they can also have some  
 
there is a SELECTION on the object.  Many of these Instances will be empty shell objects, but they can also have some  
 
 
interesting uses.
 
interesting uses.
  
Line 221: Line 180:
  
 
Note that this means there is no equivalent PRERANK: needed on a MODIFY.  It is directly applied to the "5" instance as  
 
Note that this means there is no equivalent PRERANK: needed on a MODIFY.  It is directly applied to the "5" instance as  
 
 
a MODIFY, and when the Rank hits 5, that INSTANCE will be granted and the MODIFY will be applied.  (If you are thinking  
 
a MODIFY, and when the Rank hits 5, that INSTANCE will be granted and the MODIFY will be applied.  (If you are thinking  
 
 
this could be useful for how pathfinder handles Skill Focus... yes, possibly... stay tuned :) )
 
this could be useful for how pathfinder handles Skill Focus... yes, possibly... stay tuned :) )
  
Line 233: Line 190:
  
 
The %LIST here is actually in the target, which is a bit of a problem!  The second argument to MODIFYOTHER is  
 
The %LIST here is actually in the target, which is a bit of a problem!  The second argument to MODIFYOTHER is  
 
 
definitely NOT a formula, so we need to address that somehow.  In the future, there may be elegant ways of doing this.  For right now, we end up with a not-so-great method, which looks like:
 
definitely NOT a formula, so we need to address that somehow.  In the future, there may be elegant ways of doing this.  For right now, we end up with a not-so-great method, which looks like:
  
MODIFYOTHER:EQUIPMENT.PART|ALL|Range|ADD|if(getFact(parent(),"WEAPONPROF")==getSelection("MySelection"),5,0)
+
  MODIFYOTHER:EQUIPMENT.PART|ALL|Range|ADD|if(getFact(parent(),"WEAPONPROF")==getSelection("MySelection"),5,0)
  
 
=Data Information=
 
=Data Information=
Line 245: Line 201:
  
 
INSTANCE is only supported on object types that are INSTANCE-able.  This will require code support for all existing  
 
INSTANCE is only supported on object types that are INSTANCE-able.  This will require code support for all existing  
 
 
Formats.   
 
Formats.   
  
Line 253: Line 208:
 
   INSTANCE:x|y
 
   INSTANCE:x|y
  
* x is the instances to which the token given in y should be applied.  Currently this supports either an integer value  
+
* x is the instances to which the token given in y should be applied.  Currently this supports either an integer value or "ALL"
 
 
or "ALL"
 
 
* y is a full token to be applied to that instance.   
 
* y is a full token to be applied to that instance.   
  
 
Please note INSTANCE objects are NOT full CDOMObjects.  They cannot support arbitrary tokens.  Only a limited set  
 
Please note INSTANCE objects are NOT full CDOMObjects.  They cannot support arbitrary tokens.  Only a limited set  
 
 
(defined here) will be supported.
 
(defined here) will be supported.
  
Line 265: Line 217:
  
 
SELECTION will ONLY be available on INSTANCE objects.  This means it needs to appear as a subtoken to INSTANCE (which  
 
SELECTION will ONLY be available on INSTANCE objects.  This means it needs to appear as a subtoken to INSTANCE (which  
 
+
itself must only appear on instance-able objects).
itself must only appear on instance-able objects)
 
  
 
Format:
 
Format:
Line 286: Line 237:
  
 
In the scenario where two SELECTION items would interact (such as choosing a level of spell for a given class, where  
 
In the scenario where two SELECTION items would interact (such as choosing a level of spell for a given class, where  
 
 
the class would need to be selected first), there is an ORDER control:
 
the class would need to be selected first), there is an ORDER control:
 
   ORDER=x
 
   ORDER=x
  
 
* x is an integer constant.  The SELECTION with the lowest ORDER will be processed first (just like PRIORITY on  
 
* x is an integer constant.  The SELECTION with the lowest ORDER will be processed first (just like PRIORITY on  
 
 
MODIFY).  If two SELECTION items have the same ORDER, the system will not guarantee which is processed first.  If it  
 
MODIFY).  If two SELECTION items have the same ORDER, the system will not guarantee which is processed first.  If it  
 
 
matters, specify it.  The default value is zero.
 
matters, specify it.  The default value is zero.
  
Line 307: Line 255:
  
 
Note also this function will take some cleanup - we eventually need to figure out how to do the things that the  
 
Note also this function will take some cleanup - we eventually need to figure out how to do the things that the  
 
 
existing items in the CHOOSE system do... this is a patch for now to get the discussion started
 
existing items in the CHOOSE system do... this is a patch for now to get the discussion started
  
Line 320: Line 267:
  
 
NOTE: The FORMAT that getSelection will return will depend on the SELECTION token.  It also depends on whether there is  
 
NOTE: The FORMAT that getSelection will return will depend on the SELECTION token.  It also depends on whether there is  
 
 
a SELECT=x control on the SELECTION
 
a SELECT=x control on the SELECTION
  
Line 331: Line 277:
  
 
* x is a formula in the new formula system to identify the maximum number of instances allowed for that item.
 
* x is a formula in the new formula system to identify the maximum number of instances allowed for that item.
 +
 +
=Issues=
 +
 +
# The current design of tokens shown for instances assumes one instance type per object type, which is actually not true
 +
# The current design does not consider how to process ALLOWED/ENABLED for selections - is that a filter, or not - it should be clear and under control of the data team

Latest revision as of 19:13, 4 March 2018

Introduction

First draft proposal for SELECTION (replaces CHOOSE/supports multiple CHOOSE).

Please note that the token names here are for example purposes. Some discussion has taken place but they are not finalized. They are here to show the concepts and how the structures of this new system would work in LST files.

Code Concepts

Current Issues

Multiple Methods

There are currently 4 different methods for how CHOOSE operates in the code

  • Abilities
  • Race and Template
  • Language
  • Temporary Bonuses

The desire is to reduce this to one methodology (or two at worst if temporary bonuses need to be separate)

Single Selection

CHOOSE currently supports only one selection. In many cases this produces a challenging format that is forced into the code. If multiple selections were allowed, this would not be necessary, as one could be CLASS and the other LEVEL for example.

Automatic Expansion

CHOOSE currently automatically expands items. If you CHOOSE:FEAT, you get things like Weapon Proficiency(x) and Weapon Proficiency (y). This also then creates an interesting visual challenge if there are multiple tiers. If a Feat allows a selection from another MULT:YES feat, then you get Something(a(b)) and Something(a(c)). This can rapidly proliferate into a huge list to scroll through. It would be visually cleaner to select "a" and then select "b or c" within the context of "a" being selected under "something". This requires a new UI to handle this hierarchical behavior.

(This item is not currently addressed further here, as I would like to talk to some of our UI folks before I propose too much here)

CHOOSE:NOCHOICE

Simply shouldn't have to exist.

Stacking Ambiguities

This is true more for MULT:YES than CHOOSE in particular, but imagine something like this:

ABILITY:FEAT|VIRTUAL|Dodge

Now put that on a MULT:YES Feat and select it twice.

Do you get 2 copies of Dodge or 1 copy?

This has already been encountered in the past and discussed on the -dev list. The BONUSes also suffer from the same issue and there have been a few debates over proper behavior.

The solution to this problem is eliminate all ambiguity. We should to distinguish between the ability itself (applied only once ever) and what I will call the "instances" of the ability (applied once per time taken by the user). Note that I do NOT say "per selection" or "per choice" because if an item has 3 choices, we still have struggles. There are ways to apply once per choice as well, but we need ALL of the capabilities, so we have to have a method to do once per time taken by the user).

From this point onward, I will have an INSTANCE: token that then refers to instances rather than the parent object. This is much like the current "PART:x|..." token that can appear on equipment to handle equipment heads. Just like PART, it will have an argument (as to where it is applied) followed by another full token.

Current Quirks

Stacking

Currently the system defaults to STACK:NO. Should this be the default behavior when a lot more control exists for the data to define what is selectable?

Race Conditions

Part of the reason we have multiple different selection methods is that the code has certain race conditions (two actions that need to happen in a certain order).

For Race and Template, they get added to the PC first, THEN the selection is made. This means they have to be defending against undefined choices.

For Abilities, they only get added to the PC when an AbilitySelection object (an ability with its selection) is added to the PlayerCharacter. This means the selection occurs BEFORE the object is added.


Other Considerations

Conversion

No conversion will be automated, as the semantics here are completely different than the old system.

Also, since backwards compatibility will not be supported (CHOOSE will not be available in the new formula system at least under the current plan), we will need a new token name. From this point onward, it will be called SELECTION.


Design

Instances

As mentioned above, the Selections will be placed into instances. These instances are separate objects with a separate SCOPE. For Skills (For example), the scope will be SKILL.INSTANCE

Aligning Concepts to the new Formula System

In general, the new formula system uses the concept of a Scope to determine where a variable is processed.

A naive design would be to keep two lists on the main object. That way, the first set of choices are [0] in the lists, the next set [1]. While I don't have a specific rule associated to this, I can quickly come up with some plausible use cases where that would break. For example: Imagine a feat that allows you to select a class and make 2 skills from the classskilllist of that class get +1 bonus rank.

Therefore, we delegate containing the result of the selection down into an instance object. We then make that a subscope of the main scope for that object type. Consider the CHOOSE on skills for Speak Language. We then get something like:

  INSTANCE:ALL|SELECTION:SpokenLanguage|LANGUAGE|getAll("LANGUAGE")

Now, every time a new instance of that Skill is selected (which happens to be from getting a new rank of that skill), a new Instance will be added to the PC and a new selection will need to be made.

It could then be added to a list of languages via:

  INSTANCE:ALL|MODIFY:LanguageList|ADD|getSelection("SpokenLanguage")

(This assumes LanguageList is a global variable of Format "ARRAY[LANGUAGE]")

To be VERY CLEAR: getSelection("SpokenLanguage") MUST BE USED IN AN INSTANCE. If you attempt to use it up at the parent ability/skill/whatever, it will either (a) fail or (b) be empty. (It should fail, and we will endeavor to do that, but there will need to be enhancements to have functions available only in a limited scope... that's new effort)

Resolving the Race Condition

The race condition is particularly problematic for the new formula system. Consider a naive design like this:

  MODIFY:MyList|ADD|Foo
  SELECTION:MySelection|STUFF|myList

This immediately sets up a problem based on how the formula system works. Because it only processes items that are actually "granted" to the PC, the MODIFY of MyList would not happen unless the object itself was already granted. This traps us (a bit) in making sure the object is added to the PC BEFORE a selection is made, so that if it chooses to do any list modifications, they can be done BEFORE the selection.

To resolve this race condition, we put the MODIFY on the parent object, which is granted BEFORE any selection. We then put the SELECTION in the INSTANCE, which is granted AFTER any selection. Note this also means that if (for some reason) the data team to have the MODIFY occur AFTER the selection, they have that power. This gives the data team full feature, supporting add both BEFORE and AFTER selection:

  MODIFY:MyList|ADD|AddBeforeSelection
  INSTANCE:1|MODIFY:MyList|Add|AddAfterSelection

As a nice side effect, this actually gives us full power to avoid ANY popup windows in a new UI should that be a feature we want to implement. Because all instance applications can be deferred, they could be "TODOs" on the PC rather than stopping for user input.

Replicating NUMCHOICES

To replicate the behavior of NUMCHOICES, we then need to control the number of instances that we are allowed to apply.

This is a new token, MAXINSTANCES.

Replicating SELECT

To replace the behavior of SELECT, we need to control the number of actual selections that exist in an instance for that SELECTION. Since this is associated to the SELECTION, we need to keep it local to that token, so it is appended as an optional control on the SELECTION:

  SELECTION:MySelection|LANGUAGE|getAll("LANGUAGE")|SELECT=2


Happy Side Effects of INSTANCE

Please note: ALL objects that are instance-able ALWAYS will produce an instance. This is true REGARDLESS of whether there is a SELECTION on the object. Many of these Instances will be empty shell objects, but they can also have some interesting uses.

"At Rank 5 this skill adds 2 legs to the PC"

  INSTANCE:5|MODIFY:Legs|ADD|2

Note that this means there is no equivalent PRERANK: needed on a MODIFY. It is directly applied to the "5" instance as a MODIFY, and when the Rank hits 5, that INSTANCE will be granted and the MODIFY will be applied. (If you are thinking this could be useful for how pathfinder handles Skill Focus... yes, possibly... stay tuned :) )

Using a Selection as a Target

In some cases, we end up in situations like "This will increase the range of one type of weapon by 5'". Today there is

BONUS:WEAPONPROF=%LIST|RANGE|5

The %LIST here is actually in the target, which is a bit of a problem! The second argument to MODIFYOTHER is definitely NOT a formula, so we need to address that somehow. In the future, there may be elegant ways of doing this. For right now, we end up with a not-so-great method, which looks like:

  MODIFYOTHER:EQUIPMENT.PART|ALL|Range|ADD|if(getFact(parent(),"WEAPONPROF")==getSelection("MySelection"),5,0)

Data Information

New Tokens

INSTANCE

INSTANCE is only supported on object types that are INSTANCE-able. This will require code support for all existing Formats.

Note: It is the intent to allow DYNAMIC to be instance-able if the data team so specifies. More on this later.

Format:

  INSTANCE:x|y
  • x is the instances to which the token given in y should be applied. Currently this supports either an integer value or "ALL"
  • y is a full token to be applied to that instance.

Please note INSTANCE objects are NOT full CDOMObjects. They cannot support arbitrary tokens. Only a limited set (defined here) will be supported.

SELECTION

SELECTION will ONLY be available on INSTANCE objects. This means it needs to appear as a subtoken to INSTANCE (which itself must only appear on instance-able objects).

Format:

  SELECTION:w|x|y|z|z
  • w is the name of the selection. This is relevant when the data is using the value of the selection in the data
  • x is the FORMAT of the selection. See the Setting up the new formula system for more information on formats.
  • y is the array of available objects for the selection.
  • z is an optional set of controls for the selection.

Selection Control: SELECT

This replaces the SELECT: token in the current CHOOSE System. It is a z value for SELECTION:

  SELECT=x
  • x is a formula for the number of selections to be made.

Selection Control: ORDER

In the scenario where two SELECTION items would interact (such as choosing a level of spell for a given class, where the class would need to be selected first), there is an ORDER control:

  ORDER=x
  • x is an integer constant. The SELECTION with the lowest ORDER will be processed first (just like PRIORITY on

MODIFY). If two SELECTION items have the same ORDER, the system will not guarantee which is processed first. If it matters, specify it. The default value is zero.

getAll(x) Function

getAll will be a function in the new formula system.

Format of this function:

  getAll("x")
  • x is the name of a FORMAT from the new formula system.
    • Note: This format MUST be an limited format, in that you can't do getAll("NUMBER") as that is an unbounded set.

Note also this function will take some cleanup - we eventually need to figure out how to do the things that the existing items in the CHOOSE system do... this is a patch for now to get the discussion started

getSelection(x) Function

getSelection will be a function in the new formula system.

Format of this function:

  getSelection("x")
  • x is the name of the selection from the SELECTION token.

NOTE: The FORMAT that getSelection will return will depend on the SELECTION token. It also depends on whether there is a SELECT=x control on the SELECTION

MAXINSTANCES LST Token

This token will be usable on any format which is instance-able.

Format:

  MAXINSTANCES:x
  • x is a formula in the new formula system to identify the maximum number of instances allowed for that item.

Issues

  1. The current design of tokens shown for instances assumes one instance type per object type, which is actually not true
  2. The current design does not consider how to process ALLOWED/ENABLED for selections - is that a filter, or not - it should be clear and under control of the data team