<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://159.203.101.162/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nuance</id>
	<title>PCGen Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://159.203.101.162/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nuance"/>
	<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php/Special:Contributions/Nuance"/>
	<updated>2026-04-05T19:31:16Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.1</generator>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Setting_up_the_new_Formula_System&amp;diff=4285</id>
		<title>Setting up the new Formula System</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Setting_up_the_new_Formula_System&amp;diff=4285"/>
		<updated>2018-03-09T16:24:58Z</updated>

		<summary type="html">&lt;p&gt;Nuance: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=The basics=&lt;br /&gt;
&lt;br /&gt;
The new formula system is designed to do a few things relative to data:&lt;br /&gt;
* Validate formulas at LST load instead of runtime&lt;br /&gt;
* Dramatically increase flexibility&lt;br /&gt;
* It will replace many tokens, including all the BONUS tokens&lt;br /&gt;
* It allows a sensible location for global modifications (things generally related to rule book type modifications that impact all objects of a given type)&lt;br /&gt;
&lt;br /&gt;
==Key concepts==&lt;br /&gt;
&lt;br /&gt;
To use the new system a few key things need to be remembered:&lt;br /&gt;
* It is possible to have local variables&lt;br /&gt;
* All variables must be defined prior to use&lt;br /&gt;
* Variables are not only numbers, but can be Strings, Dice, etc.&lt;br /&gt;
** We call this the variable FORMAT&lt;br /&gt;
&lt;br /&gt;
You will want to keep track of what these key terms mean as you learn the new formula system:&lt;br /&gt;
* FORMAT: The type of variable, e.g. NUMBER, BOOLEAN, ORDEREDPAIR.&lt;br /&gt;
* SCOPE: The part of the data in which a (local) variable is available&lt;br /&gt;
* MODIFIER: An argument to MODIFY* tokens, specifically the &amp;quot;command&amp;quot; of what the modification represents&lt;br /&gt;
* OPERATOR: A mathematical operator as you would see in a formula (&amp;quot;+&amp;quot;, &amp;quot;-&amp;quot;, etc.)&lt;br /&gt;
* GROUPING: A name for a set of objects in PCGen&lt;br /&gt;
* ASSOCIATION: An additional set of information attached to a MODIFY* token.  This is a key-value pair of information, e.g. PRIORITY=100&lt;br /&gt;
&lt;br /&gt;
=Creating and Using Variables=&lt;br /&gt;
&lt;br /&gt;
==Required Setup==&lt;br /&gt;
&lt;br /&gt;
Every format that needs to be used requires a default value. This value is shared throughout an entire system (it CANNOT be redefined to a different value).  This is placed into a file referred to in a PCC file from the DATACONTROL: token.&lt;br /&gt;
&lt;br /&gt;
===DATACONTROL (PCC File)===&lt;br /&gt;
&lt;br /&gt;
DATACONTROL: is a new Campaign file token (for PCC files).  It is treated &amp;quot;recursively&amp;quot; like other tokens, e.g. TEMPLATE.  &lt;br /&gt;
&lt;br /&gt;
   DATACONTROL:x&lt;br /&gt;
&lt;br /&gt;
* x is the file to be loaded as a DATACONTROL file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
===DEFAULTVARIABLEVALUE (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
The Format is:&lt;br /&gt;
   DEFAULTVARIABLEVALUE:X|Y&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the default value&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   DEFAULTVARIABLEVALUE:NUMBER|0&lt;br /&gt;
&lt;br /&gt;
It is a best practice to always define a DEFAULTVARIABLEVALUE for every FORMAT regardless of whether the data uses that FORMAT.  The internal parts of PCGen may use it, so a default value may be required.&lt;br /&gt;
&lt;br /&gt;
Note: it IS safe to &amp;quot;redefine&amp;quot; a DEFAULTVARIABLEVALUE to the same value.  So if multiple datasets are loaded and they all had DATACONTROL: and all defined the default value for NUMBER to be 0, they will all happily load as the system is capable of recognizing the defaults are the same&lt;br /&gt;
&lt;br /&gt;
==How to define a variable==&lt;br /&gt;
&lt;br /&gt;
===VARIABLE (PCC File)===&lt;br /&gt;
&lt;br /&gt;
To define a variable, you need to add an LST file that is referred to in a PCC file from the VARIABLE: token.  It is treated &amp;quot;recursively&amp;quot; like other tokens, e.g. TEMPLATE.  &lt;br /&gt;
&lt;br /&gt;
   VARIABLE:x&lt;br /&gt;
&lt;br /&gt;
* x is the file to be loaded as a VARIABLE file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
There are 2 basic tokens for the VARIABLE file: GLOBAL and LOCAL.&lt;br /&gt;
&lt;br /&gt;
===GLOBAL (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
* GLOBAL defines a global variable, usable from anywhere within the PlayerCharacter.&lt;br /&gt;
&lt;br /&gt;
The format is:&lt;br /&gt;
   GLOBAL:X=Y&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the variable name&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   GLOBAL:ORDEREDPAIR=Face&lt;br /&gt;
&lt;br /&gt;
A GLOBAL token can take additional token on the line called EXPLANATION, which it is advisable to use to communicate to other data monkeys (and it is likely any future editor will also draw on this information).&lt;br /&gt;
&lt;br /&gt;
===LOCAL (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
* LOCAL defines a local variable, usable only within the object on which the variable exists (or its children)&lt;br /&gt;
** The place where a local variable is usable is called the SCOPE.  This could include a STAT (such as the stat's SCORE or STATMOD) or EQUIPMENT.  The scopes possible in PCGen are hard-coded (see below for more info)&lt;br /&gt;
&lt;br /&gt;
The format is:&lt;br /&gt;
   LOCAL:W|X=Y&lt;br /&gt;
* W is the SCOPE of the variable&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the variable name&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   LOCAL:STAT|NUMBER=Score&lt;br /&gt;
&lt;br /&gt;
A LOCAL token can take additional token on the line called EXPLANATION, which it is advisable to use to communicate to other data monkeys (and it is likely any future editor will also draw on this information).&lt;br /&gt;
&lt;br /&gt;
===EXPLANATION (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
EXPLANATION: is a free-text token (no parsing is really done) that is designed to describe why a variable exists&lt;br /&gt;
&lt;br /&gt;
Format:&lt;br /&gt;
   EXPLANATION:x&lt;br /&gt;
&lt;br /&gt;
* x is the text of the Explanation&lt;br /&gt;
* Limitations: By Design: Must not appear as the first token on a line&lt;br /&gt;
* Behavior: Overwrites (as if someone would use it twice??)&lt;br /&gt;
&lt;br /&gt;
===Defaults in the VARIABLE file===&lt;br /&gt;
&lt;br /&gt;
A few notes about the VARIABLE files:&lt;br /&gt;
If you see an item without a leading token, e.g.:&lt;br /&gt;
   ORDEREDPAIR=Face&lt;br /&gt;
...then the system is using the default (GLOBAL).  For now, the data standard is to avoid using this shortcut (as far as I know)&lt;br /&gt;
&lt;br /&gt;
If you see an item without a leading format (&amp;quot;X&amp;quot; in both GLOBAL and LOCAL above), e.g.:&lt;br /&gt;
   LOCAL:STAT|Score&lt;br /&gt;
...then the format is a NUMBER.  For now, the data standard is to avoid using this shortcut (as far as I know)&lt;br /&gt;
&lt;br /&gt;
Note both defaults can be combined, so a variable name with no other information on that line is a Global NUMBER&lt;br /&gt;
&lt;br /&gt;
===No Overlapping===&lt;br /&gt;
&lt;br /&gt;
In most programming languages, it is legal to have local variable share the same name as the global variable and thus &amp;quot;override&amp;quot; it in that context (although it is considered less than ideal, and in some languages it will now produce a warning).  It is not legal in PCGen.&lt;br /&gt;
&lt;br /&gt;
If a Global variable called &amp;quot;Hands&amp;quot; exists, then NO local variable IN ANY SCOPE can be &amp;quot;Hands&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Similar restrictions exist for scopes and SubScopes.  If &amp;quot;CritMult&amp;quot; is an EQUIPMENT variable, then &amp;quot;CritMult&amp;quot; can't be an EQUIPMENT.PART variable.  &lt;br /&gt;
&lt;br /&gt;
Non-overlapping (when the Scopes do not interact) is legal.  &amp;quot;Score&amp;quot; can be a local STAT variable and a local CHECK variable, for example.&lt;br /&gt;
&lt;br /&gt;
For clarity: &lt;br /&gt;
* This occurs regardless of the FORMAT of the variables - tokens will infer the format from the variable name, so you can't have overlapping variables even of different FORMAT.&lt;br /&gt;
* Two variables of the same name but different FORMAT in the same SCOPE will cause an error as well, because that is effectively overlapping, and those variables can't be distinguished in most circumstances.&lt;br /&gt;
&lt;br /&gt;
===Identical Duplication Legal===&lt;br /&gt;
&lt;br /&gt;
It is legal for a load to include one or more PCC files that have one or more VARIABLE: files that redefine the same variables.  As long as they are the same format and scope, they are not considered an error.  If either the scope or format differs, then the &amp;quot;No Overlapping&amp;quot; rules above are applied.&lt;br /&gt;
&lt;br /&gt;
A difference in the &amp;quot;Explanation&amp;quot; text is not considered a difference in the variables significant enough to trigger an error. (In fact, the last loaded Explanation will &amp;quot;win&amp;quot; -&amp;gt; it is overwritten each time it is encountered for redefined but identical variables)&lt;br /&gt;
&lt;br /&gt;
==Setting and Modifying a variable==&lt;br /&gt;
&lt;br /&gt;
===MODIFY (LST files)===&lt;br /&gt;
&lt;br /&gt;
The MODIFY token is used to set a variable that is accessible in the current SCOPE.  (Note: It could be local to the current scope or any ancestor of the current scope... so modifying a global variable always just requires MODIFY)&lt;br /&gt;
&lt;br /&gt;
The format of the token is: &lt;br /&gt;
   MODIFY:V|W|X|Y=Z|Y=Z&lt;br /&gt;
* V is the Variable name for which the value will be modified&lt;br /&gt;
**  This variable MUST be visible in the current scope.  Therefore, it must be either a global variable or a local variable on the current object or its parents.&lt;br /&gt;
* W is the MODIFIER to be taken on the variable (e.g. SET)&lt;br /&gt;
** There can be multiple actions (more below), but SET will ALWAYS be available for any format.&lt;br /&gt;
* X is the value related to the action.  If the action is set, the variable will be set to the value in this part of the token.&lt;br /&gt;
** Note: The value CAN be a formula.  It is possible, for example, to SET a variable to OtherVar+4 ... the system will solve that formula.  For legal OPERATORS (e.g. &amp;quot;+&amp;quot;) , see below.&lt;br /&gt;
* Y is the name of an (optional) ASSOCIATION.  For now, PRIORITY (more below) is the only available association.&lt;br /&gt;
* Z is the value of the association.&lt;br /&gt;
&lt;br /&gt;
Note: If a PRIORITY is not set it is assumed to be ZERO.&lt;br /&gt;
&lt;br /&gt;
Example: Give a Player Character 2 hands:&lt;br /&gt;
   MODIFY:Hands|SET|2&lt;br /&gt;
&lt;br /&gt;
===MODIFYOTHER (LST files)===&lt;br /&gt;
&lt;br /&gt;
The MODIFYOTHER token is used to set a variable that is not accessible in the current SCOPE.  Beyond what is necessary in MODIFY, this token also requires the &amp;quot;address&amp;quot; of where to go before it runs the modification.  Think of it as the ability to remotely place a MODIFY on another object (but revoke that MODIFY if the current object is no longer granted to the PC)&lt;br /&gt;
&lt;br /&gt;
The format of the token is: &lt;br /&gt;
   MODIFYOTHER:T|U|V|W|X|Y=Z|Y=Z&lt;br /&gt;
* T is the FORMAT of the object on which the resulting MODIFY (as defined by V-Z) should occur&lt;br /&gt;
* U is the object or GROUPING of objects on which the MODIFY (as defined by V-Z) should occur&lt;br /&gt;
** Note that this does not and will not support TYPE.&lt;br /&gt;
* V is the Variable name for which the value will be modified&lt;br /&gt;
**  This variable MUST be visible in the scope of the addressed object.  Therefore, it is likely to be a local variable on the remote object or its parents.  &lt;br /&gt;
** In rare cases, a remote modification of a global variable is useful.  It effectively adds to that global variable only if both objects are granted to the PC.&lt;br /&gt;
* W is the MODIFIER to be taken on the variable (e.g. SET)&lt;br /&gt;
** There can be multiple actions (more below), but SET will ALWAYS be available for any format.&lt;br /&gt;
* X is the value related to the action.  If the action is set, the variable will be set to the value in this part of the token.&lt;br /&gt;
** Note: The value CAN be a formula.  It is possible, for example, to SET a variable to OtherVar+4 ... the system will solve that formula.  For legal OPERATORS (e.g. &amp;quot;+&amp;quot;) , see below.&lt;br /&gt;
* Y is the name of an (optional) ASSOCIATION.  For now, PRIORITY (more below) is the only available association.&lt;br /&gt;
* Z is the value of the association.&lt;br /&gt;
&lt;br /&gt;
Note: If a PRIORITY is not set it is assumed to be ZERO.&lt;br /&gt;
&lt;br /&gt;
Example: Reduce the HandsRequired on all Weapons by 1:&lt;br /&gt;
   MODIFYOTHER:EQUIPMENT|GROUP=Weapon|HandsRequired|ADD|-1&lt;br /&gt;
&lt;br /&gt;
Note this assumes GROUP:Weapon is in the LST line of every Weapon... PCGen can't guess or derive what a weapon is :)&lt;br /&gt;
&lt;br /&gt;
==Formulas==&lt;br /&gt;
&lt;br /&gt;
SET as a MODIFIER allows the use of a formula for the value.  This follows many mathematical systems of using parenthesis - &amp;quot;(&amp;quot; and &amp;quot;)&amp;quot; to be precise - to group (and thus prioritize parts of the calculation). &lt;br /&gt;
There are a number of built in OPERATORs (see below).  The system can also use functions, which use parenthesis to contain their arguments.  For example:&lt;br /&gt;
* min(this,that)&lt;br /&gt;
Would return the minimum of the two variables &amp;quot;this&amp;quot; and &amp;quot;that&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Built in Functions===&lt;br /&gt;
&lt;br /&gt;
The system also has a series of built-in functions that work with the NUMBER format:&lt;br /&gt;
* abs: calculates the absolute value of the one argument.&lt;br /&gt;
* ceil: calculates the next integer that is &amp;gt;= the value of the one argument.&lt;br /&gt;
* floor: calculates the next lower integer that is &amp;lt;= the value of the one argument&lt;br /&gt;
* if: conditionally performs an operation.  The first argument must resolve to a BOOLEAN.  If true, the second argument is evaluated; if false, the third argument is evaluated.&lt;br /&gt;
* max: calculates the maximum of the provided two or more comma-separated arguments&lt;br /&gt;
* min: calculates the minimum of the provided two or more comma-separated arguments&lt;br /&gt;
* round: calculates the closest integer to the value of the one argument.  Exactly 0.5 is rounded up.&lt;br /&gt;
* value: returns the value of the calculation before the current modification was started (no arguments)&lt;br /&gt;
&lt;br /&gt;
Additional functions specifically related to PCGen are available:&lt;br /&gt;
* get: This function takes two arguments.  The first is an Object type (like &amp;quot;SKILL&amp;quot;), the second is the key of a CDOMObject (like a Skill) (also in quotes)&lt;br /&gt;
**Example: get(&amp;quot;SKILL&amp;quot;,&amp;quot;Hide&amp;quot;)&lt;br /&gt;
* getFact: This function returns the value of a FACT.  The first two arguments are much like the two arguments of &amp;quot;get&amp;quot;, the third argument is the name of the FACT to be returned&lt;br /&gt;
&lt;br /&gt;
=Legal Values=&lt;br /&gt;
&lt;br /&gt;
==FORMATs==&lt;br /&gt;
&lt;br /&gt;
Currently, the following are built-in formats:&lt;br /&gt;
* NUMBER: This is a mathematical value.  Note that integer arithmetic is done if possible, so if you have an integer 6 and an integer 3, 6/3 will be an integer 2.  If the 6 or 3 is a decimal value (double), then integer arithmetic was not possible and thus rounding may occur.&lt;br /&gt;
* STRING: A String&lt;br /&gt;
* BOOLEAN: A True/False value&lt;br /&gt;
* ORDEREDPAIR: An ordered pair of numbers.  This could be an X,Y point (or in a game system more like a FACE)&lt;br /&gt;
* DICE: A value that takes the form AdB+C.  A is the number of rolls of the die, B is the number of sides on the die, and C is the value to be added afterwords&lt;br /&gt;
* ALIGNMENT: An alignment object (None is default typically)&lt;br /&gt;
&lt;br /&gt;
==OPERATORs==&lt;br /&gt;
&lt;br /&gt;
For NUMBER, the following modifiers are available:&lt;br /&gt;
* +: performs addition&lt;br /&gt;
* -: performs subtraction (or is the unary minus operator to make a value negative)&lt;br /&gt;
* *: performs multiplication&lt;br /&gt;
* /: performs division&lt;br /&gt;
* %: performs a remainder function&lt;br /&gt;
* ^: performs an exponential calculation&lt;br /&gt;
* ==: Checks for equality (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* !=: Checks for inequality (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;gt;: Checks for greater than (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;lt;: Checks for less than (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;gt;=: Checks for greater than or equal to (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;lt;=: Checks for less than or equal to (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
&lt;br /&gt;
For BOOLEAN, the following modifiers are available:&lt;br /&gt;
* ==: Checks for equality&lt;br /&gt;
* !=: Checks for inequality&lt;br /&gt;
* &amp;amp;&amp;amp;: Performs a logical AND&lt;br /&gt;
* ||: Performs a logical OR&lt;br /&gt;
* !: Negates the value&lt;br /&gt;
&lt;br /&gt;
For other formats, the following operators are always available:&lt;br /&gt;
* ==: Checks for equality (NOTE: Returns a BOOLEAN, not the compared format)&lt;br /&gt;
* !=: Checks for inequality (NOTE: Returns a BOOLEAN, not the compared format)&lt;br /&gt;
&lt;br /&gt;
==MODIFIERs==&lt;br /&gt;
&lt;br /&gt;
For NUMBER, the following modifiers are available:&lt;br /&gt;
* SET: This sets the variable to the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* ADD: This adds the current value of the variable to the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* MAX: This takes the maximum value of the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter (i.e. min(current value, &amp;quot;X&amp;quot;))&lt;br /&gt;
* MIN: This takes the minimum value of the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter (i.e. max(current value, &amp;quot;X&amp;quot;))&lt;br /&gt;
* MULTIPLY: This multiplies the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* DIVIDE: This divides the current value of the variable by the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
&lt;br /&gt;
For other Formats, the SET modifier will always be available&lt;br /&gt;
&lt;br /&gt;
==GROUPINGs==&lt;br /&gt;
&lt;br /&gt;
At present, the second argument of MODIFYOTHER supports 3 possible values:&lt;br /&gt;
* ALL&lt;br /&gt;
** This means the MODIFYOTHER will impact ALL objects of that type.  This is useful for setting a general default for that value (e.g. you could default &amp;quot;HandsRequired&amp;quot; on weapons to 1)&lt;br /&gt;
* GROUP=X&lt;br /&gt;
** This is set by the GROUP token in LST data&lt;br /&gt;
* A specific object KEY&lt;br /&gt;
&lt;br /&gt;
More will be added over time.&lt;br /&gt;
&lt;br /&gt;
==SCOPEs==&lt;br /&gt;
&lt;br /&gt;
The following are the legal scopes (not including GLOBAL):&lt;br /&gt;
* EQUIPMENT: This is a variable local to equipment&lt;br /&gt;
** EQUIPMENT.PART: This is a variable local to an equipment PART (or in older terms, an Equipment HEAD).  Note that due to double sided weapons, Damage, CritMult and other items are generally on an equipment PART, not on the Equipment itself.  Note also that this is a SUBSCOPE of the EQUIPMENT scope (so all variables in the EQUIPMENT scope can also be seen in the EQUIPMENT.PART scope)&lt;br /&gt;
* SAVE: This is a variable local to Save (or if you prefer, Check)&lt;br /&gt;
* SIZE: This is a variable local to the Size of a PC&lt;br /&gt;
* SKILL: This is a variable local to a Skill&lt;br /&gt;
* STAT: This is a variable local to a Stat&lt;br /&gt;
&lt;br /&gt;
More will be added over time.&lt;br /&gt;
&lt;br /&gt;
DYNAMIC can also be used to create a Scope and Object Type (see below)&lt;br /&gt;
&lt;br /&gt;
=Examples=&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScope in practice==&lt;br /&gt;
&lt;br /&gt;
To understand how local variables work in SubScopes, consider the following (note this is not all the variables we will use but a critical set to define the scope):&lt;br /&gt;
   GLOBAL:NUMBER=Hands&lt;br /&gt;
   LOCAL:EQUIPMENT|NUMBER=HandsRequired&lt;br /&gt;
   LOCAL:EQUIPMENT|BOOLEAN=Penalized&lt;br /&gt;
   LOCAL:EQUIPMENT.PART|NUMBER=CritMult&lt;br /&gt;
&lt;br /&gt;
The Equipment part is what the traditional system called a &amp;quot;head&amp;quot; (so a double headed axe has two &amp;quot;parts&amp;quot; in the new system - this was done since in some game systems, an item could have more than 2)&lt;br /&gt;
&lt;br /&gt;
To understand how variables are available and how they get modified consider this:&lt;br /&gt;
&lt;br /&gt;
Inside of a piece of equipment it could do something like:&lt;br /&gt;
   MODIFY:Penalized|SET|HandsRequired&amp;gt;Hands&lt;br /&gt;
&lt;br /&gt;
This would be &amp;quot;true&amp;quot; if HandsRequired on the Equipment were more than the Hands on the PC.  The &amp;quot;Hands&amp;quot; variable is Global, so it is available anywhere.  A Template of &amp;quot;Extra Hands&amp;quot; could do something like: &lt;br /&gt;
   MODIFY:Hands|ADD|2 &lt;br /&gt;
... and that adds to the Global variable &amp;quot;Hands&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now consider an Equipment Modifier that was something like &amp;quot;Lighter Than Normal&amp;quot;.  Assume the game benefit was one less hand is required.  This would look like:&lt;br /&gt;
   Lighter Than Normal   MODIFY:HandsRequired|ADD|-1&lt;br /&gt;
(This ignores for the moment any situation like &amp;quot;can't be reduced to below one&amp;quot;.)&lt;br /&gt;
&lt;br /&gt;
Note that the EquipmentModifier falls into EQUIPMENT.PART, so that it has access to the HandsRequired variable from the EQUIPMENT scope and can modify it.  Note that this change could then impact the result of the BOOLEAN variable Penalized, since HandsRequired changed.  Note also that &amp;quot;HandsRequired&amp;quot;, when evaluated anywhere in that Equipment is now 1 less.  Even if another EquipmentModifier evaluates HandsRequired, it is analyzing the variable from its parent scope, so that value on a variable from EQUIPMENT is the same in every EquipmentModifier (in the EQUIPMENT.PART scope) of that piece of Equipment.&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScope on Equipment==&lt;br /&gt;
&lt;br /&gt;
Since variables like CritMult and Damage would be on an Equipment &amp;quot;part&amp;quot; it is important to understand how to get access to that &amp;quot;part&amp;quot; from the LST code.  If a single-headed weapon wanted a larger CritMult, it would be silly to have to add a Dummy EquipmentModifier just to modify the CritMult on the part.  (Much of the point of the new system is to make things more direct)&lt;br /&gt;
&lt;br /&gt;
There is a token for Equipment called PART.  This effectively takes 2 arguments: A number (today 1 for the primary head, 2 for the secondary head) and a full token otherwise valid on a plain object.  MODIFY and MODIFYOTHER will both work in that situation, so for a piece of Equipment to set its own CritMult to 3 on its primary (and perhaps only) head, it would do:&lt;br /&gt;
   PART:1|MODIFY:CritMult|SET|3&lt;br /&gt;
&lt;br /&gt;
Note since the MODIFY is a &amp;quot;real&amp;quot; token call it uses &amp;quot;:&amp;quot; after the MODIFY which makes PART look slightly different to most tokens which use | as an internal separator.  Since PART is effectively calling a &amp;quot;real&amp;quot; token, we need to use the inner &amp;quot;:&amp;quot; in order to have it pass through the same code/parsing system.&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScopes in relation to MODIFYOTHER==&lt;br /&gt;
&lt;br /&gt;
* Note Jan 29 2018: There is a possibility of a solution for this issue that would allow MODIFYOTHER to do direct addressing of sub-objects under certain conditions&lt;br /&gt;
&lt;br /&gt;
Normally MODIFYOTHER allows you to &amp;quot;address&amp;quot; another scope.  For example:&lt;br /&gt;
   MODIFYOTHER:EQUIPMENT|Bastard Sword|HandsRequired|ADD|-1&lt;br /&gt;
&lt;br /&gt;
However, since items like Damage and CritMult are actually on the EQUIPMENT.PART, that is different.  If you consider how you would have to &amp;quot;address&amp;quot; the first head on &amp;quot;Bastard Sword&amp;quot;, you would need something like:&lt;br /&gt;
   SOMEWEIRDTOKEN:EQUIPMENT|Bastard Sword|PART|1|CritMult|ADD|1&lt;br /&gt;
&lt;br /&gt;
Note that this requires both a primary and secondary address.  No token like this exists (at the moment).  To alter items in a SubScope, you need to pass them down to the SubScope.  An attempt to modify it at the Equipment level, such as:&lt;br /&gt;
   MyAbility   MODIFYOTHER:EQUIPMENT|ALL|CritMult|ADD|1&lt;br /&gt;
... will fail (at LST load) because CritMult was on EQUIPMENT.PART, so it is not visible to the EQUIPMENT scope.  Said another way, you can't universally modify all EQUIPMENT.PART variables by attempting to use that variable at a higher scope.&lt;br /&gt;
&lt;br /&gt;
A more appropriate method (since this is relevant to a Feat that might alter CritMult) is to add another variable at the EQUIPMENT level:&lt;br /&gt;
   LOCAL:EQUIPMENT|NUMBER=CritMultAdder&lt;br /&gt;
If all the heads then get&lt;br /&gt;
   MODIFY:CritMult|ADD|CritMultAdder&lt;br /&gt;
... you can have the Feat do a MODIFYOTHER to alter CritMultAdder and the MODIFY will &amp;quot;pull&amp;quot; that into each PART:&lt;br /&gt;
   SomeFeat   MODIFYOTHER:EQUIPMENT|ALL|CritMultAdd|ADD|1&lt;br /&gt;
So the data can be set up to only require one modification from a Feat and each Equipment Part can pull that modification down into the part.  (A tangential note for those objecting that the known modifiers of CritMult select a specific weapon type: Yep, got it.  That's not possible yet, so not documented yet.  Suspend disbelief on the examples - Imagine a more powerful Feat for now)&lt;br /&gt;
&lt;br /&gt;
==Understanding PRIORITY and processing of MODIFY and MODIFYOTHER==&lt;br /&gt;
&lt;br /&gt;
When a PlayerCharacter has multiple items that attempt to modify a variable, they are sorted by two systems:&lt;br /&gt;
* First, they are sorted by their user priority.  This is provided in the PRIORITY=Z association.  Lower PRIORITY will be processed first.&lt;br /&gt;
* Second, they are sorted by their inherent priority.  This is a built-in system that approximates mathematical priority rules. It ensures, for example, that a SET will occur before ADD if they both have a matching user priority.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
Assume we had the following items:&lt;br /&gt;
   MODIFY:Hands|MULTIPLY|2|PRIORITY=100&lt;br /&gt;
   MODIFY:Hands|SET|2|PRIORITY=50&lt;br /&gt;
   MODIFY:Hands|ADD|1|PRIORITY=50&lt;br /&gt;
&lt;br /&gt;
The first thing is that we can tell from the PRIORITY items that the SET and ADD will both occur BEFORE the multiply (because 50 &amp;lt; 100).  For the SET and ADD, we would need to know the inherent priority (For what it's worth, SET is 0, ADD is 3, MULTIPLY and DIVIDE are 1 and 2 since they are higher priority than ADD in traditional math).  This means the SET will happen first.  So the result is Hands is SET to 2, then ADD 1 to get 3, then MULTIPLY by 2 to get 6.&lt;br /&gt;
&lt;br /&gt;
By controlling the PRIORITY, the data team can reorder any calculation and perform much more complicated calculations than was possible with BONUS (where movement, for example, had multiple different BONUS tokens to try to do adding before and after a multiply).  This is much the same as using parenthesis in a formula in normal math, but this allows you trigger any required ordering even if the MODIFY statements are in different objects.&lt;br /&gt;
&lt;br /&gt;
==Using the previous value in a more complex calculation==&lt;br /&gt;
&lt;br /&gt;
Take a modification that, for example, wishes to perform a calculation such as: &amp;quot;Reduce the value by 1, but to no less than 1&amp;quot;.  We could write this as two MODIFY statements, but that is probably undesirable for a few reasons: &lt;br /&gt;
* If the book states it as one sentence, it would be preferable to write it as one MODIFY&lt;br /&gt;
* It makes the calculation a bit harder to follow as to what is going on&lt;br /&gt;
* If the items are different PRIORITY, there is a risk of another dataset attempting to (or accidentally) putting something in between those two steps, resulting in an incorrect calculation.  &lt;br /&gt;
&lt;br /&gt;
Therefore, we need a method of drawing on the current value in a formula.  To do that we use the value() function.  The calculation above then becomes:&lt;br /&gt;
   max(value()-1,1)&lt;br /&gt;
...and we can use it in a MODIFY as such:&lt;br /&gt;
   MODIFY:HandsRequired|SET|max(value()-1,1)&lt;br /&gt;
&lt;br /&gt;
Note that we are using SET here - if a formula is used, it is likely to be best done as a SET, since that will be much more clear than calculating a formula and then immediately applying another MODIFICATION.  Note that some modifications may also prohibit a formula depending on their underlying behavior.&lt;br /&gt;
&lt;br /&gt;
=Global Modifier File=&lt;br /&gt;
&lt;br /&gt;
There is a new file type that is defined in the PCC files with GLOBALMODIFIER.&lt;br /&gt;
&lt;br /&gt;
This file allows for a centralized (and clear to the data user) location for global modifications (don't hide things on stats or elsewhere anymore).  This supports MODIFY for global variables (if you want to start all PCs with 2 hands for example) or MODIFYOTHER for local variables.&lt;br /&gt;
&lt;br /&gt;
==GLOBALMODIFIER (PCC File)==&lt;br /&gt;
&lt;br /&gt;
Format:&lt;br /&gt;
   GLOBALMODIFIER:x&lt;br /&gt;
* x is the file to be loaded as a GLOBALMODIFIER file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
=Advanced Topics=&lt;br /&gt;
&lt;br /&gt;
==Dynamic Objects and Scope==&lt;br /&gt;
&lt;br /&gt;
This set of features allows the data to supplement the defined SCOPEs with new object types not originally comprehended in PCGen. Within a Dynamic Scope, the data can produce objects.  &lt;br /&gt;
&lt;br /&gt;
Warning: Attempts to define a SCOPE that overlaps with existing objects (e.g. LANGUAGE) will not produce a warning today but will get you in trouble long term.  It won't work in the way you would like it to work (it won't attach a SCOPE to that object type), so just avoid those overlapping names.  Basically if you can CHOOSE it, or use it with FACT, don't DYMAMICSCOPE it.&lt;br /&gt;
&lt;br /&gt;
===DYNAMICSCOPE (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
The DYNAMICSCOPE token (used in files referred to by the DATACONTROL: token in PCC files) can define a Dynamic Scope.&lt;br /&gt;
&lt;br /&gt;
   DYNAMICSCOPE:x&lt;br /&gt;
&lt;br /&gt;
*x is the new scope&lt;br /&gt;
**Any argument to DYNAMICSCOPE becomes a legal &amp;quot;scope&amp;quot; in LOCAL: in the variable definition file&lt;br /&gt;
**Limit of one new scope per line.  (No delimiter on this token)&lt;br /&gt;
*Like other LST tokens, this is case insensitive, but usage in later tokens is always capitalized, so I suspect the data standard should be ALL CAPS&lt;br /&gt;
&lt;br /&gt;
===DYNAMIC (PCC File)=== &lt;br /&gt;
&lt;br /&gt;
In order to create objects within the defined DYNAMICSCOPE, DYNAMIC: becomes a new token legal in PCC files. It's format is:&lt;br /&gt;
&lt;br /&gt;
   DYNAMIC:x&lt;br /&gt;
&lt;br /&gt;
* x is the file just as in tokens like DEITY or DOMAIN&lt;br /&gt;
* INCLUDE/EXCLUDE on the line are are legal.&lt;br /&gt;
&lt;br /&gt;
Within the Dynamic file, the Scope of the new objects being created MUST appear as a prefix token on the line.  For example, if there was a DYNAMICSCOPE:VISION, then the following would be legal in a DYNAMIC file:&lt;br /&gt;
   VISION:Darkvision&lt;br /&gt;
   VISION:Low-Light Vision&lt;br /&gt;
&lt;br /&gt;
* The &amp;quot;Token Name&amp;quot; (what appears before the ':') is the DYNAMICSCOPE name.&lt;br /&gt;
* These are created as basically hollow, simple objects.  &lt;br /&gt;
* These objects CAN contain variables.&lt;br /&gt;
(It is the intent to allow these at some point to also have MODIFY* tokens, but that is not currently supported)&lt;br /&gt;
&lt;br /&gt;
===GRANT (LST files)===&lt;br /&gt;
&lt;br /&gt;
A Dynamic object MUST be granted in order to have its local variables modified or to have its modifiers have an impact (just like any other object) &lt;br /&gt;
&lt;br /&gt;
    GRANT:x|y&lt;br /&gt;
&lt;br /&gt;
* x is a DYNAMICSCOPE&lt;br /&gt;
* y is the name of the dynamic object.&lt;br /&gt;
&lt;br /&gt;
===Export===&lt;br /&gt;
&lt;br /&gt;
Dynamic items can be exported in Freemarker using the &lt;br /&gt;
&lt;br /&gt;
   &amp;lt;#list pc.dynamic.x as y&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* x is the name of the DYNAMICSCOPE&lt;br /&gt;
* y is the local variable within the #list that the output team wants to use to access the dynamic object&lt;br /&gt;
* It is likely for ease of use by the output team, x and y will be identical&lt;br /&gt;
&lt;br /&gt;
For a complete example using output, see below&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
DATACONTROL: file:&lt;br /&gt;
   DYNAMICSCOPE:VISION&lt;br /&gt;
&lt;br /&gt;
DYNAMIC: file:&lt;br /&gt;
   VISION:Normal&lt;br /&gt;
   VISION:Darkvision&lt;br /&gt;
   VISION:Low-Light Vision&lt;br /&gt;
&lt;br /&gt;
VARIABLE: File:&lt;br /&gt;
   LOCAL:VISION|NUMBER=Range&lt;br /&gt;
&lt;br /&gt;
GLOBALMODIFIERFILE:&lt;br /&gt;
    MODIFYOTHER:VISION|ALL|Range|Set|60&lt;br /&gt;
&lt;br /&gt;
Sets a &amp;quot;default&amp;quot; range for any VISION, to avoid setting on each VISION object&lt;br /&gt;
&lt;br /&gt;
RACE LST file:&lt;br /&gt;
   Human &amp;lt;&amp;gt; GRANT:VISION|Normal&lt;br /&gt;
&lt;br /&gt;
Export:&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;#list pc.dynamic.vision as vision&amp;gt;&lt;br /&gt;
    ${vision.name} ${vision.val.range}&lt;br /&gt;
   &amp;lt;/#list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this ignores converting the range to local units and all that, but you get the idea)&lt;br /&gt;
&lt;br /&gt;
==ARRAY Format==&lt;br /&gt;
&lt;br /&gt;
In addition to the base formats, there is an ARRAY[x] format:&lt;br /&gt;
   ARRAY[x]&lt;br /&gt;
* x is an existing valid Format&lt;br /&gt;
** x CANNOT be ARRAY (multi-dimensional arrays not supported&lt;br /&gt;
** Just to be precise, yes DYNAMIC formats are legal&lt;br /&gt;
&lt;br /&gt;
(Note: This may get renamed - we need to decide on a few things for how this will work vs other types of collections)&lt;br /&gt;
&lt;br /&gt;
===Modifiers===&lt;br /&gt;
&lt;br /&gt;
There are two valid MODIFIERs for ARRAY:&lt;br /&gt;
* ADD: This adds a value to the ARRAY&lt;br /&gt;
** Mathematically, ARRAY acts as an ordered set of objects.  Therefore, if you add an item to an array more than once it is ignored.&lt;br /&gt;
* SET: This sets the contents of the ARRAY&lt;br /&gt;
&lt;br /&gt;
==Custom Functions==&lt;br /&gt;
&lt;br /&gt;
Within certain game systems, there are calculations that are likely to be repeated.  In order to simplify the calculation of these items, there is an ability to create custom functions.&lt;br /&gt;
&lt;br /&gt;
A function can have zero or more arguments.  The number is defined by what appears in the VALUE token (see below).&lt;br /&gt;
&lt;br /&gt;
Note that the function actually has to be *used in the data* (not just defined) for most errors to be caught (since the system can't guess at overall context before a function is used and it would be possible to write a function that would work in more than one FORMAT).&lt;br /&gt;
&lt;br /&gt;
===Function (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
   FUNCTION:x&lt;br /&gt;
* This token must appear as the first token on a line in a DATACONTROL file.&lt;br /&gt;
* x is the name of the function.  This name must starts with a letter, e.g. A-Z, additional legal characters are 0-9 and _ (none of those additional legal characters as the first character)&lt;br /&gt;
** x must not contain spaces, no other special characters.&lt;br /&gt;
** Function names are case insensitive (as many other things in LST files) &lt;br /&gt;
&lt;br /&gt;
A Function MUST also contain a VALUE, which defines how the function is calculated.&lt;br /&gt;
&lt;br /&gt;
If a FUNCTION appears more than once, the other characteristics (VALUE) must be identical. &lt;br /&gt;
&lt;br /&gt;
===Value (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
   VALUE:x&lt;br /&gt;
* Must appear as an additional token on the line of a FUNCTION: in the data control file&lt;br /&gt;
* x is a valid formula.  &lt;br /&gt;
** This means it must have valid variable names, valid function names, matching parenthesis, etc. &lt;br /&gt;
&lt;br /&gt;
In addition to all of the built-in functions (e.g. if, ceil, round), two additional items can be used:&lt;br /&gt;
* the arg(n) function (see below).&lt;br /&gt;
* Any previously defined FUNCTION. This MUST appear in the file before the current Function or in a file processed before the current file.&lt;br /&gt;
&lt;br /&gt;
===arg (Function)===&lt;br /&gt;
&lt;br /&gt;
The arg function is a &amp;quot;local&amp;quot; function to the VALUE: part of a FUNCTION (it can not generally be used in LST files). The arg function takes one argument. It MUST be a Integer &amp;gt;= 0.&lt;br /&gt;
&lt;br /&gt;
   arg(x)&lt;br /&gt;
* x is an integer number (zero-indexed)&lt;br /&gt;
&lt;br /&gt;
When arg(x) is used in value, the function pulls from the arguments that were provided to the original function in the data.  &lt;br /&gt;
&lt;br /&gt;
===Using a Function===&lt;br /&gt;
&lt;br /&gt;
When a function is used in LST data, it is called by the name provided in the FUNCTION token. It requires a certain number of arguments. This exactly matches the integer one greater than the highest number of the arg(n) function provided in the VALUE part of a FUNCTION (In computer science terms, the arg(n) function is zero-indexed). The provided arguments can be any legal formula, so:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(INT)&lt;br /&gt;
   d20Mod(INT+4)&lt;br /&gt;
&lt;br /&gt;
...are both perfectly legal.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
The modification calculation in most d20 games is fairly easy to calculate, but is repeated very often.  It basically takes (ability score - 10)/2.&lt;br /&gt;
&lt;br /&gt;
Here is how we would define a new function d20Mod in the DATACONTROL file:&lt;br /&gt;
   FUNCTION:d20Mod    VALUE:floor((arg(0)-10)/2)&lt;br /&gt;
&lt;br /&gt;
This would then be used in LST data as:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(n)&lt;br /&gt;
&lt;br /&gt;
The system will catch both of these as errors:&lt;br /&gt;
&lt;br /&gt;
   d20Mod()&lt;br /&gt;
   d20Mod(14,5) &lt;br /&gt;
&lt;br /&gt;
These have too few or too many arguments, respectively. It would also catch:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(&amp;quot;mystring&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
...as an error (wrong format - requires a Number, found a String). &lt;br /&gt;
&lt;br /&gt;
The n is substituted where &amp;quot;arg(0)&amp;quot; appears in the &amp;quot;VALUE&amp;quot;... so a statmod would be as easy as:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(INT)&lt;br /&gt;
&lt;br /&gt;
or some such... Direct values can also be used, e.g.:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(10)&lt;br /&gt;
&lt;br /&gt;
...would return 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Performance Considerations==&lt;br /&gt;
&lt;br /&gt;
It is possible to write two identical modifiers that perform the same net calculation on a PC.  For example:&lt;br /&gt;
   MODIFY:Age|ADD|2&lt;br /&gt;
   MODIFY:Age|SET|value()+2&lt;br /&gt;
&lt;br /&gt;
...perform the same calculation (adding 2 to Age).&lt;br /&gt;
&lt;br /&gt;
Why have ADD at all?  Answer: These are NOT AT ALL equivalent in memory use or speed/performance.&lt;br /&gt;
&lt;br /&gt;
The ADD (Since it's adding an integer) occupies approximately 40 bytes of memory and is an extremely rapid calculation: If it took 200 nanoseconds I'd be surprised. This is because ADD is using a number. If it was a formula, even 1+2, it would load the formula parser. This special case on constants allows the modification system to modify a value without loading a much larger infrastructure, and this is valuable as a large majority of our calculations are simple modifications of values.&lt;br /&gt;
&lt;br /&gt;
The SET shown above (since it has an operator) loads the formula system, and thus may occupy 500 (or more) bytes of memory (&amp;gt;10x), so it could take 100 times as long to process as the ADD (it also took longer during LST load).&lt;br /&gt;
&lt;br /&gt;
Thus: When possible the data standards should be written to use numeric modifiers and no operator.  (Think &amp;quot;static&amp;quot; modifiers ... that only use numbers) rather than a formula.&lt;br /&gt;
&lt;br /&gt;
==Lookup and Tables==&lt;br /&gt;
&lt;br /&gt;
For some situations, it makes more sense to have a lookup table rather than attempting to have a set of tokens or calculations perform processing.  This also allows for much cleaner translation from books when the books are using tables to organize information.&lt;br /&gt;
&lt;br /&gt;
The Table file format is designed to allow you to use a spreadsheet program to modify the tables and export the table in CSV format.  While we don't strictly follow full CSV rules, as long as you avoid embedded quotes and embedded return carriage/line feed, it should be safe.&lt;br /&gt;
&lt;br /&gt;
More than one table is allowed per file (to avoid sprawl and help simplify modification/management of tables).&lt;br /&gt;
&lt;br /&gt;
===TABLE (PCC File)===&lt;br /&gt;
&lt;br /&gt;
   TABLE:x&lt;br /&gt;
* x is the file to be loaded as a TABLE file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
====Table LST file format====&lt;br /&gt;
&lt;br /&gt;
File formatting considerations:&lt;br /&gt;
* Trailing commas will not impact any TABLE, and will be ignored&lt;br /&gt;
* Blank lines will be ignored.  This includes lines with commas but without content. (allows tables to be separated by blank lines or lines of all commas)&lt;br /&gt;
* Attempts to use embedded line breaks or embedded quotes may or may not be supported by the parsing system, but certainly aren't supported for purposes of PCGen.&lt;br /&gt;
* Lines that have the first cell starting with &amp;quot;#&amp;quot; are considered comment lines and will be ignored.  This will likely need to include if the first cell is escaped in quotes, just for protection from any tools that quote by default.&lt;br /&gt;
* Since the CSV format ignores leading/trailing spaces, one can easily have a spaced out version that is a table in a text editor if folks don't want to edit in a spreadsheet.  (Having someone write a &amp;quot;PrettyTable&amp;quot; ... a trivial perl or python program to do that for the data team seems fairly easy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A TABLE starts with STARTTABLE:&lt;br /&gt;
   STARTTABLE:x&lt;br /&gt;
* x is the name of the Table.  Most characters are allowed, avoiding quotes is advisable.&lt;br /&gt;
* Allowing Trailing commas allows the STARTTABLE lines to have blank cells where the rest are the table contents... we don't want to complain on minor things that may tools will do.&lt;br /&gt;
&lt;br /&gt;
If a STARTTABLE is encountered when another Table is active, an LST load error will occur.&lt;br /&gt;
&lt;br /&gt;
A TABLE ends with ENDTABLE:&lt;br /&gt;
   ENDTABLE:x&lt;br /&gt;
* x is the name of the Table.  Most characters are allowed, avoiding quotes is advisable.&lt;br /&gt;
* Allowing Trailing commas allows the ENDTABLE lines to have blank cells where the rest are the table contents... we don't want to complain on minor things that may tools will do.&lt;br /&gt;
&lt;br /&gt;
If an ENDTABLE is encountered without a STARTTABLE, an LST load error will occur.&lt;br /&gt;
&lt;br /&gt;
A Table must have a minimum of 3 rows, NOT counting the STARTTABLE and ENDTABLE tokens.&lt;br /&gt;
&lt;br /&gt;
The First row:&lt;br /&gt;
   x,x&lt;br /&gt;
* x is the column name.  These are always the first line of the table after STARTTABLE:&lt;br /&gt;
&lt;br /&gt;
Any column which has data MUST have a name.&lt;br /&gt;
&lt;br /&gt;
The Second row:&lt;br /&gt;
   y,y&lt;br /&gt;
* y is the format for the column.  Any column that was named must have a FORMAT.&lt;br /&gt;
&lt;br /&gt;
Additional rows:&lt;br /&gt;
   z,z&lt;br /&gt;
* z represents contents of the table.  These must be in the FORMAT provided for the appropriate column.&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
&lt;br /&gt;
   STARTTABLE:Carrying Capacity,&lt;br /&gt;
   Strength,Capacity&lt;br /&gt;
   NUMBER,NUMBER&lt;br /&gt;
   1,10&lt;br /&gt;
   2,20&lt;br /&gt;
   ...&lt;br /&gt;
   29,1400&lt;br /&gt;
   ENDTABLE:Carrying Capacity,&lt;br /&gt;
&lt;br /&gt;
===TABLE[x] Format===&lt;br /&gt;
&lt;br /&gt;
When a TABLE is created, it implicitly picks up a FORMAT based on the FORMAT of the first column of the Table.  &lt;br /&gt;
Unlike basic FORMATs shown above, TABLE has a SUBFORMAT (in brackets).&lt;br /&gt;
&lt;br /&gt;
   TABLE[x]&lt;br /&gt;
* x is the SUB-FORMAT of the TABLE (this is the format of the first column of the Table)&lt;br /&gt;
** x must be an otherwise valid FORMAT, and it is advised to avoid any FORMAT that has a SUB-FORMAT&lt;br /&gt;
*** This limitation may be inconsistently enforced.  It certainly is prohibited to create a TABLE[TABLE[x]], but other situations the behavior may not be prohibited by the code (but the behavior is also not guaranteed)&lt;br /&gt;
&lt;br /&gt;
===COLUMN[x] Format===&lt;br /&gt;
&lt;br /&gt;
When a Column needs to be referred to in the data, it has a special format as well:&lt;br /&gt;
&lt;br /&gt;
Unlike basic FORMATs shown above, COLUMN has a SUBFORMAT (in brackets).&lt;br /&gt;
   COLUMN[x]&lt;br /&gt;
* x is the SUB-FORMAT of the COLUMN (this is the format of the data that appears in that column in a Table)&lt;br /&gt;
** x must be an otherwise valid FORMAT, and it is advised to avoid any FORMAT that has a SUB-FORMAT&lt;br /&gt;
*** This limitation may be inconsistently enforced.  Such behavior may not be prohibited by the code (but avoiding bad behavior is also not guaranteed in a situation where embedded brackets occur)&lt;br /&gt;
&lt;br /&gt;
===Using Tables===&lt;br /&gt;
&lt;br /&gt;
With MODIFY, a TABLE[x] variable doesn't look any different.  It's still:&lt;br /&gt;
   MODIFY:TableNameVar|SET|&amp;quot;SomeTable&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SomeTable&amp;quot; is still a string to a naive reader, but what the system will do at that point is make sure that SomeTable can actually be interpreted as a TABLE[x]... rather than just treating it as a String.  Similar for column names when they are encountered (see below).&lt;br /&gt;
&lt;br /&gt;
In that way, the sub variable will allow multiple tables to be swapped in, AS LONG AS they are the right format.  If the format is not compatible, then all bets are off and you'll get an error.&lt;br /&gt;
&lt;br /&gt;
===lookup() Function===&lt;br /&gt;
&lt;br /&gt;
The major consideration is how to do the lookup in data.  We can borrow some inspiration from things like Excel and Google Docs:&lt;br /&gt;
&lt;br /&gt;
   lookup(X,Y,Z)&lt;br /&gt;
&lt;br /&gt;
* X is a table.  This must resolve in the formula system to a valid table.  For now, a get(...) function may be required.&lt;br /&gt;
* Y is the lookup value in the table.  It must match the format of the first column in the table.  At this time, it does an EXACT match.&lt;br /&gt;
* Z is the target column.  This must resolve in the formula system to a valid table column. It must appear in the table named by the contents of the first argument of lookup.&lt;br /&gt;
&lt;br /&gt;
Example: Max load calculation would be something like:&lt;br /&gt;
   lookup(&amp;quot;Carrying Capacity&amp;quot;,floor(StrScore),&amp;quot;Capacity&amp;quot;)*SizeMult&lt;br /&gt;
We have to do the floor due to the exact name of the lookup&lt;br /&gt;
&lt;br /&gt;
Note: The format of both TABLE &amp;quot;Carrying Capacity&amp;quot; and COLUMN &amp;quot;Capacity&amp;quot; can be derived by PCGen internally and thus are no longer required to have a get (current as of Jan 30, 2018)&lt;br /&gt;
&lt;br /&gt;
Note that this function allows some runtime errors, but catches a lot of possible issues.  It is still possible to do a lookup on a Table that doesn't contain a specific column of the given name or format, simply because those items can be variables resolved at runtime.  For example, if the third variable is COLUMN[NUMBER], we can check at load that the TABLEFORMAT has columns of FORMAT=NUMBER, but we can't guarantee the variable will resolve to a name actually in that table... that will have to wait for a runtime error.  That's life, but it does allow us to know the formats at load time, so we do get a lot of error checking in the context of the usage, if not the exact table and column names.&lt;br /&gt;
&lt;br /&gt;
Note you can do some really dynamic behaviors to have folks override game mode behaviors.  For example, one neat item would be that we could alter a query for dice steps to extract the table name into the Global Modifier file:&lt;br /&gt;
   MODIFY:DiceStepTable|SET|&amp;quot;Dice Step&amp;quot;&lt;br /&gt;
   lookup(get(&amp;quot;TABLE[NUMBER]&amp;quot;,DiceStepTable),BaseDamage,get(&amp;quot;COLUMN[NUMBER]&amp;quot;,lookup(&amp;quot;Step Column&amp;quot;,CurrentSize-BaseSize,&amp;quot;Name&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
Note: In both cases here, the &amp;quot;get&amp;quot; is shown for completeness.  In the case of DiceStepTable - it MAY be required or prohibited - it depends on what the Format is of the &amp;quot;DiceStepTable&amp;quot; variable.  If it's TABLE, then the get is not necessary (and is actually prohibited).  The example shown above assumes DiceStepTable is a String.  The better design would be for it to be a TABLE (specifically TABLE[NUMBER]).  For the &amp;quot;get&amp;quot; after the lookup, that is required - the lookup value will return a STRING, and as such, will needs to be converted to a COLUMN.&lt;br /&gt;
&lt;br /&gt;
Now, if someone needs different dice steps for some reason... they can override the DiceStepTable variable and it will look up in a different table... so expansions could truly be expansions and not have to reach back into core PCC files in order to change key behaviors.&lt;br /&gt;
&lt;br /&gt;
Consider also that spell tables can be shared across classes, or if a subclass alters the default, just create a new table rather than having to BONUS/MODIFY all the numbers in a table with adding and subtracting...&lt;br /&gt;
&lt;br /&gt;
==To be completed==&lt;br /&gt;
* dropIntoContext&lt;br /&gt;
* Channels&lt;br /&gt;
&lt;br /&gt;
=Material Changes=&lt;br /&gt;
&lt;br /&gt;
==lookup function simplification==&lt;br /&gt;
&lt;br /&gt;
Effective January 30, 2018, tables and columns can be referred to directly in lookup().  This is actually a &amp;quot;broad&amp;quot; change to how strings are interpreted.  The system - when possible - fully asserts a FORMAT, and first attempts to convert the given String per the rules of that FORMAT.  This also means an assignment of an ALIGNMENT, by key, will not require a &amp;quot;get&amp;quot;:&lt;br /&gt;
   MODIFY:Alignment|SET|&amp;quot;LE&amp;quot;&lt;br /&gt;
...will be fully legal.  (This assumes Alignment is FORMAT: of ALIGNMENT)&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Setting_up_the_new_Formula_System&amp;diff=4284</id>
		<title>Setting up the new Formula System</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Setting_up_the_new_Formula_System&amp;diff=4284"/>
		<updated>2018-03-09T16:10:11Z</updated>

		<summary type="html">&lt;p&gt;Nuance: Correct typo/grammar error.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=The basics=&lt;br /&gt;
&lt;br /&gt;
The new formula system is designed to do a few things relative to data:&lt;br /&gt;
* Validate formulas at LST load instead of runtime&lt;br /&gt;
* Dramatically increase flexibility&lt;br /&gt;
* It will replace many tokens, including all the BONUS tokens&lt;br /&gt;
* It allows a sensible location for global modifications (things generally related to rule book type modifications that impact all objects of a given type)&lt;br /&gt;
&lt;br /&gt;
==Key concepts==&lt;br /&gt;
&lt;br /&gt;
To use the new system a few key things need to be remembered:&lt;br /&gt;
* It is possible to have local variables&lt;br /&gt;
* All variables must be defined prior to use&lt;br /&gt;
* Variables are not only numbers, but can be Strings, Dice, etc.&lt;br /&gt;
** We call this the variable FORMAT&lt;br /&gt;
&lt;br /&gt;
You will want to keep track of what these key terms mean as you learn the new formula system:&lt;br /&gt;
* FORMAT: The type of variable, e.g. NUMBER, BOOLEAN, ORDEREDPAIR.&lt;br /&gt;
* SCOPE: The part of the data in which a (local) variable is available&lt;br /&gt;
* MODIFIER: An argument to MODIFY* tokens, specifically the &amp;quot;command&amp;quot; of what the modification represents&lt;br /&gt;
* OPERATOR: A mathematical operator as you would see in a formula (&amp;quot;+&amp;quot;, &amp;quot;-&amp;quot;, etc.)&lt;br /&gt;
* GROUPING: A name for a set of objects in PCGen&lt;br /&gt;
* ASSOCIATION: An additional set of information attached to a MODIFY* token.  This is a key-value pair of information, e.g. PRIORITY=100&lt;br /&gt;
&lt;br /&gt;
=Creating and Using Variables=&lt;br /&gt;
&lt;br /&gt;
==Required Setup==&lt;br /&gt;
&lt;br /&gt;
Every format that needs to be used requires a default value. This value is shared throughout an entire system (it CANNOT be redefined to a different value).  This is placed into a file referred to in a PCC file from the DATACONTROL: token.&lt;br /&gt;
&lt;br /&gt;
===DATACONTROL (PCC File)===&lt;br /&gt;
&lt;br /&gt;
DATACONTROL: is a new Campaign file token (for PCC files).  It is treated &amp;quot;recursively&amp;quot; like other tokens, e.g. TEMPLATE.  &lt;br /&gt;
&lt;br /&gt;
   DATACONTROL:x&lt;br /&gt;
&lt;br /&gt;
* x is the file to be loaded as a DATACONTROL file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
===DEFAULTVARIABLEVALUE (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
The Format is:&lt;br /&gt;
   DEFAULTVARIABLEVALUE:X|Y&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the default value&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   DEFAULTVARIABLEVALUE:NUMBER|0&lt;br /&gt;
&lt;br /&gt;
It is a best practice to always define a DEFAULTVARIABLEVALUE for every FORMAT regardless of whether the data uses that FORMAT.  The internal parts of PCGen may use it, so a default value may be required.&lt;br /&gt;
&lt;br /&gt;
Note: it IS safe to &amp;quot;redefine&amp;quot; a DEFAULTVARIABLEVALUE to the same value.  So if multiple datasets are loaded and they all had DATACONTROL: and all defined the default value for NUMBER to be 0, they will all happily load as the system is capable of recognizing the defaults are the same&lt;br /&gt;
&lt;br /&gt;
==How to define a variable==&lt;br /&gt;
&lt;br /&gt;
===VARIABLE (PCC File)===&lt;br /&gt;
&lt;br /&gt;
To define a variable, you need to add an LST file that is referred to in a PCC file from the VARIABLE: token.  It is treated &amp;quot;recursively&amp;quot; like other tokens, e.g. TEMPLATE.  &lt;br /&gt;
&lt;br /&gt;
   VARIABLE:x&lt;br /&gt;
&lt;br /&gt;
* x is the file to be loaded as a VARIABLE file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
There are 2 basic tokens for the VARIABLE file: GLOBAL and LOCAL.&lt;br /&gt;
&lt;br /&gt;
===GLOBAL (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
* GLOBAL defines a global variable, usable from anywhere within the PlayerCharacter.&lt;br /&gt;
&lt;br /&gt;
The format is:&lt;br /&gt;
   GLOBAL:X=Y&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the variable name&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   GLOBAL:ORDEREDPAIR=Face&lt;br /&gt;
&lt;br /&gt;
A GLOBAL token can take additional token on the line called EXPLANATION, which it is advisable to use to communicate to other data monkeys (and it is likely any future editor will also draw on this information).&lt;br /&gt;
&lt;br /&gt;
===LOCAL (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
* LOCAL defines a local variable, usable only within the object on which the variable exists (or its children)&lt;br /&gt;
** The place where a local variable is usable is called the SCOPE.  This could include a STAT (such as the stat's SCORE or STATMOD) or EQUIPMENT.  The scopes possible in PCGen are hard-coded (see below for more info)&lt;br /&gt;
&lt;br /&gt;
The format is:&lt;br /&gt;
   LOCAL:W|X=Y&lt;br /&gt;
* W is the SCOPE of the variable&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the variable name&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   LOCAL:STAT|NUMBER=Score&lt;br /&gt;
&lt;br /&gt;
A LOCAL token can take additional token on the line called EXPLANATION, which it is advisable to use to communicate to other data monkeys (and it is likely any future editor will also draw on this information).&lt;br /&gt;
&lt;br /&gt;
===EXPLANATION (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
EXPLANATION: is a free-text token (no parsing is really done) that is designed to describe why a variable exists&lt;br /&gt;
&lt;br /&gt;
Format:&lt;br /&gt;
   EXPLANATION:x&lt;br /&gt;
&lt;br /&gt;
* x is the text of the Explanation&lt;br /&gt;
* Limitations: By Design: Must not appear as the first token on a line&lt;br /&gt;
* Behavior: Overwrites (as if someone would use it twice??)&lt;br /&gt;
&lt;br /&gt;
===Defaults in the VARIABLE file===&lt;br /&gt;
&lt;br /&gt;
A few notes about the VARIABLE files:&lt;br /&gt;
If you see an item without a leading token, e.g.:&lt;br /&gt;
   ORDEREDPAIR=Face&lt;br /&gt;
...then the system is using the default (GLOBAL).  For now, the data standard is to avoid using this shortcut (as far as I know)&lt;br /&gt;
&lt;br /&gt;
If you see an item without a leading format (&amp;quot;X&amp;quot; in both GLOBAL and LOCAL above), e.g.:&lt;br /&gt;
   LOCAL:STAT|Score&lt;br /&gt;
...then the format is a NUMBER.  For now, the data standard is to avoid using this shortcut (as far as I know)&lt;br /&gt;
&lt;br /&gt;
Note both defaults can be combined, so a variable name with no other information on that line is a Global NUMBER&lt;br /&gt;
&lt;br /&gt;
===No Overlapping===&lt;br /&gt;
&lt;br /&gt;
In most programming languages, it is legal to have local variable share the same name as the global variable and thus &amp;quot;override&amp;quot; it in that context (although it is considered less than ideal, and in some languages it will now produce a warning).  It is not legal in PCGen.&lt;br /&gt;
&lt;br /&gt;
If a Global variable called &amp;quot;Hands&amp;quot; exists, then NO local variable IN ANY SCOPE can be &amp;quot;Hands&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Similar restrictions exist for scopes and SubScopes.  If &amp;quot;CritMult&amp;quot; is an EQUIPMENT variable, then &amp;quot;CritMult&amp;quot; can't be an EQUIPMENT.PART variable.  &lt;br /&gt;
&lt;br /&gt;
Non-overlapping (when the Scopes do not interact) is legal.  &amp;quot;Score&amp;quot; can be a local STAT variable and a local CHECK variable, for example.&lt;br /&gt;
&lt;br /&gt;
For clarity: &lt;br /&gt;
* This occurs regardless of the FORMAT of the variables - tokens will infer the format from the variable name, so you can't have overlapping variables even of different FORMAT.&lt;br /&gt;
* Two variables of the same name but different FORMAT in the same SCOPE will cause an error as well, because that is effectively overlapping, and those variables can't be distinguished in most circumstances.&lt;br /&gt;
&lt;br /&gt;
===Identical Duplication Legal===&lt;br /&gt;
&lt;br /&gt;
It is legal for a load to include one or more PCC files that have one or more VARIABLE: files that redefine the same variables.  As long as they are the same format and scope, they are not considered an error.  If either the scope or format differs, then the &amp;quot;No Overlapping&amp;quot; rules above are applied.&lt;br /&gt;
&lt;br /&gt;
A difference in the &amp;quot;Explanation&amp;quot; text is not considered a difference in the variables significant enough to trigger an error. (In fact, the last loaded Explanation will &amp;quot;win&amp;quot; -&amp;gt; it is overwritten each time it is encountered for redefined but identical variables)&lt;br /&gt;
&lt;br /&gt;
==Setting and Modifying a variable==&lt;br /&gt;
&lt;br /&gt;
===MODIFY (LST files)===&lt;br /&gt;
&lt;br /&gt;
The MODIFY token is used to set a variable that is accessible in the current SCOPE.  (Note: It could be local to the current scope or any ancestor of the current scope... so modifying a global variable always just requires MODIFY)&lt;br /&gt;
&lt;br /&gt;
The format of the token is: &lt;br /&gt;
   MODIFY:V|W|X|Y=Z|Y=Z&lt;br /&gt;
* V is the Variable name for which the value will be modified&lt;br /&gt;
**  This variable MUST be visible in the current scope.  Therefore, it must be either a global variable or a local variable on the current object or its parents.&lt;br /&gt;
* W is the MODIFIER to be taken on the variable (e.g. SET)&lt;br /&gt;
** There can be multiple actions (more below), but SET will ALWAYS be available for any format.&lt;br /&gt;
* X is the value related to the action.  If the action is set, the variable will be set to the value in this part of the token.&lt;br /&gt;
** Note: The value CAN be a formula.  It is possible, for example, to SET a variable to OtherVar+4 ... the system will solve that formula.  For legal OPERATORS (e.g. &amp;quot;+&amp;quot;) , see below.&lt;br /&gt;
* Y is the name of an (optional) ASSOCIATION.  For now, PRIORITY (more below) is the only available association.&lt;br /&gt;
* Z is the value of the association.&lt;br /&gt;
&lt;br /&gt;
Note: If a PRIORITY is not set it is assumed to be ZERO.&lt;br /&gt;
&lt;br /&gt;
Example: Give a Player Character 2 hands:&lt;br /&gt;
   MODIFY:Hands|SET|2&lt;br /&gt;
&lt;br /&gt;
===MODIFYOTHER (LST files)===&lt;br /&gt;
&lt;br /&gt;
The MODIFYOTHER token is used to set a variable that is not accessible in the current SCOPE.  Beyond what is necessary in MODIFY, this token also requires the &amp;quot;address&amp;quot; of where to go before it runs the modification.  Think of it as the ability to remotely place a MODIFY on another object (but revoke that MODIFY if the current object is no longer granted to the PC)&lt;br /&gt;
&lt;br /&gt;
The format of the token is: &lt;br /&gt;
   MODIFYOTHER:T|U|V|W|X|Y=Z|Y=Z&lt;br /&gt;
* T is the FORMAT of the object on which the resulting MODIFY (as defined by V-Z) should occur&lt;br /&gt;
* U is the object or GROUPING of objects on which the MODIFY (as defined by V-Z) should occur&lt;br /&gt;
** Note that this does not and will not support TYPE.&lt;br /&gt;
* V is the Variable name for which the value will be modified&lt;br /&gt;
**  This variable MUST be visible in the scope of the addressed object.  Therefore, it is likely to be a local variable on the remote object or its parents.  &lt;br /&gt;
** In rare cases, a remote modification of a global variable is useful.  It effectively adds to that global variable only if both objects are granted to the PC.&lt;br /&gt;
* W is the MODIFIER to be taken on the variable (e.g. SET)&lt;br /&gt;
** There can be multiple actions (more below), but SET will ALWAYS be available for any format.&lt;br /&gt;
* X is the value related to the action.  If the action is set, the variable will be set to the value in this part of the token.&lt;br /&gt;
** Note: The value CAN be a formula.  It is possible, for example, to SET a variable to OtherVar+4 ... the system will solve that formula.  For legal OPERATORS (e.g. &amp;quot;+&amp;quot;) , see below.&lt;br /&gt;
* Y is the name of an (optional) ASSOCIATION.  For now, PRIORITY (more below) is the only available association.&lt;br /&gt;
* Z is the value of the association.&lt;br /&gt;
&lt;br /&gt;
Note: If a PRIORITY is not set it is assumed to be ZERO.&lt;br /&gt;
&lt;br /&gt;
Example: Reduce the HandsRequired on all Weapons by 1:&lt;br /&gt;
   MODIFYOTHER:EQUIPMENT|GROUP=Weapon|HandsRequired|ADD|-1&lt;br /&gt;
&lt;br /&gt;
Note this assumes GROUP:Weapon is in the LST line of every Weapon... PCGen can't guess or derive what a weapon is :)&lt;br /&gt;
&lt;br /&gt;
==Formulas==&lt;br /&gt;
&lt;br /&gt;
SET as a MODIFIER allows the use of a formula for the value.  This follows many mathematical systems of using parenthesis - &amp;quot;(&amp;quot; and &amp;quot;)&amp;quot; to be precise - to group (and thus prioritize parts of the calculation). &lt;br /&gt;
There are a number of built in OPERATORs (see below).  The system can also use functions, which use parenthesis to contain their arguments.  For example:&lt;br /&gt;
* min(this,that)&lt;br /&gt;
Would return the minimum of the two variables &amp;quot;this&amp;quot; and &amp;quot;that&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Built in Functions===&lt;br /&gt;
&lt;br /&gt;
The system also has a series of built-in functions that work with the NUMBER format:&lt;br /&gt;
* abs: calculates the absolute value of the one argument.&lt;br /&gt;
* ceil: calculates the next integer that is &amp;gt;= the value of the one argument.&lt;br /&gt;
* floor: calculates the next lower integer that is &amp;lt;= the value of the one argument&lt;br /&gt;
* if: conditionally performs an operation.  The first argument must resolve to a BOOLEAN.  If true, the second argument is evaluated; if false, the third argument is evaluated.&lt;br /&gt;
* max: calculates the maximum of the provided two or more comma-separated arguments&lt;br /&gt;
* min: calculates the minimum of the provided two or more comma-separated arguments&lt;br /&gt;
* round: calculates the closest integer to the value of the one argument.  Exactly 0.5 is rounded up.&lt;br /&gt;
* value: returns the value of the calculation before the current modification was started (no arguments)&lt;br /&gt;
&lt;br /&gt;
Additional functions specifically related to PCGen are available:&lt;br /&gt;
* get: This function takes two arguments.  The first is a Object type (like &amp;quot;SKILL&amp;quot;), the second is the key of a CDOMObject (like a Skill) (also in quotes)&lt;br /&gt;
**Example: get(&amp;quot;SKILL&amp;quot;,&amp;quot;Hide&amp;quot;)&lt;br /&gt;
* getFact: This function returns the value of a FACT.  The first two arguments are much like the two arguments of &amp;quot;get&amp;quot;, the third argument is the name of the FACT to be returned&lt;br /&gt;
&lt;br /&gt;
=Legal Values=&lt;br /&gt;
&lt;br /&gt;
==FORMATs==&lt;br /&gt;
&lt;br /&gt;
Currently, the following are built-in formats:&lt;br /&gt;
* NUMBER: This is a mathematical value.  Note that integer arithmetic is done if possible, so if you have an integer 6 and an integer 3, 6/3 will be an integer 2.  If the 6 or 3 is a decimal value (double), then integer arithmetic was not possible and thus rounding may occur.&lt;br /&gt;
* STRING: A String&lt;br /&gt;
* BOOLEAN: A True/False value&lt;br /&gt;
* ORDEREDPAIR: An ordered pair of numbers.  This could be an X,Y point (or in a game system more like a FACE)&lt;br /&gt;
* DICE: A value that takes the form AdB+C.  A is the number of rolls of the die, B is the number of sides on the die, and C is the value to be added afterwords&lt;br /&gt;
* ALIGNMENT: An alignment object (None is default typically)&lt;br /&gt;
&lt;br /&gt;
==OPERATORs==&lt;br /&gt;
&lt;br /&gt;
For NUMBER, the following modifiers are available:&lt;br /&gt;
* +: performs addition&lt;br /&gt;
* -: performs subtraction (or is the unary minus operator to make a value negative)&lt;br /&gt;
* *: performs multiplication&lt;br /&gt;
* /: performs division&lt;br /&gt;
* %: performs a remainder function&lt;br /&gt;
* ^: performs an exponential calculation&lt;br /&gt;
* ==: Checks for equality (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* !=: Checks for inequality (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;gt;: Checks for greater than (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;lt;: Checks for less than (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;gt;=: Checks for greater than or equal to (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;lt;=: Checks for less than or equal to (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
&lt;br /&gt;
For BOOLEAN, the following modifiers are available:&lt;br /&gt;
* ==: Checks for equality&lt;br /&gt;
* !=: Checks for inequality&lt;br /&gt;
* &amp;amp;&amp;amp;: Performs a logical AND&lt;br /&gt;
* ||: Performs a logical OR&lt;br /&gt;
* !: Negates the value&lt;br /&gt;
&lt;br /&gt;
For other formats, the following operators are always available:&lt;br /&gt;
* ==: Checks for equality (NOTE: Returns a BOOLEAN, not the compared format)&lt;br /&gt;
* !=: Checks for inequality (NOTE: Returns a BOOLEAN, not the compared format)&lt;br /&gt;
&lt;br /&gt;
==MODIFIERs==&lt;br /&gt;
&lt;br /&gt;
For NUMBER, the following modifiers are available:&lt;br /&gt;
* SET: This sets the variable to the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* ADD: This adds the current value of the variable to the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* MAX: This takes the maximum value of the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter (i.e. min(current value, &amp;quot;X&amp;quot;))&lt;br /&gt;
* MIN: This takes the minimum value of the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter (i.e. max(current value, &amp;quot;X&amp;quot;))&lt;br /&gt;
* MULTIPLY: This multiplies the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* DIVIDE: This divides the current value of the variable by the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
&lt;br /&gt;
For other Formats, the SET modifier will always be available&lt;br /&gt;
&lt;br /&gt;
==GROUPINGs==&lt;br /&gt;
&lt;br /&gt;
At present, the second argument of MODIFYOTHER supports 3 possible values:&lt;br /&gt;
* ALL&lt;br /&gt;
** This means the MODIFYOTHER will impact ALL objects of that type.  This is useful for setting a general default for that value (e.g. you could default &amp;quot;HandsRequired&amp;quot; on weapons to 1)&lt;br /&gt;
* GROUP=X&lt;br /&gt;
** This is set by the GROUP token in LST data&lt;br /&gt;
* A specific object KEY&lt;br /&gt;
&lt;br /&gt;
More will be added over time.&lt;br /&gt;
&lt;br /&gt;
==SCOPEs==&lt;br /&gt;
&lt;br /&gt;
The following are the legal scopes (not including GLOBAL):&lt;br /&gt;
* EQUIPMENT: This is a variable local to equipment&lt;br /&gt;
** EQUIPMENT.PART: This is a variable local to an equipment PART (or in older terms, an Equipment HEAD).  Note that due to double sided weapons, Damage, CritMult and other items are generally on an equipment PART, not on the Equipment itself.  Note also that this is a SUBSCOPE of the EQUIPMENT scope (so all variables in the EQUIPMENT scope can also be seen in the EQUIPMENT.PART scope)&lt;br /&gt;
* SAVE: This is a variable local to Save (or if you prefer, Check)&lt;br /&gt;
* SIZE: This is a variable local to the Size of a PC&lt;br /&gt;
* SKILL: This is a variable local to a Skill&lt;br /&gt;
* STAT: This is a variable local to a Stat&lt;br /&gt;
&lt;br /&gt;
More will be added over time.&lt;br /&gt;
&lt;br /&gt;
DYNAMIC can also be used to create a Scope and Object Type (see below)&lt;br /&gt;
&lt;br /&gt;
=Examples=&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScope in practice==&lt;br /&gt;
&lt;br /&gt;
To understand how local variables work in SubScopes, consider the following (note this is not all the variables we will use but a critical set to define the scope):&lt;br /&gt;
   GLOBAL:NUMBER=Hands&lt;br /&gt;
   LOCAL:EQUIPMENT|NUMBER=HandsRequired&lt;br /&gt;
   LOCAL:EQUIPMENT|BOOLEAN=Penalized&lt;br /&gt;
   LOCAL:EQUIPMENT.PART|NUMBER=CritMult&lt;br /&gt;
&lt;br /&gt;
The Equipment part is what the traditional system called a &amp;quot;head&amp;quot; (so a double headed axe has two &amp;quot;parts&amp;quot; in the new system - this was done since in some game systems, an item could have more than 2)&lt;br /&gt;
&lt;br /&gt;
To understand how variables are available and how they get modified consider this:&lt;br /&gt;
&lt;br /&gt;
Inside of a piece of equipment it could do something like:&lt;br /&gt;
   MODIFY:Penalized|SET|HandsRequired&amp;gt;Hands&lt;br /&gt;
&lt;br /&gt;
This would be &amp;quot;true&amp;quot; if HandsRequired on the Equipment were more than the Hands on the PC.  The &amp;quot;Hands&amp;quot; variable is Global, so it is available anywhere.  A Template of &amp;quot;Extra Hands&amp;quot; could do something like: &lt;br /&gt;
   MODIFY:Hands|ADD|2 &lt;br /&gt;
... and that adds to the Global variable &amp;quot;Hands&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now consider an Equipment Modifier that was something like &amp;quot;Lighter Than Normal&amp;quot;.  Assume the game benefit was one less hand is required.  This would look like:&lt;br /&gt;
   Lighter Than Normal   MODIFY:HandsRequired|ADD|-1&lt;br /&gt;
(This ignores for the moment any situation like &amp;quot;can't be reduced to below one&amp;quot;.)&lt;br /&gt;
&lt;br /&gt;
Note that the EquipmentModifier falls into EQUIPMENT.PART, so that it has access to the HandsRequired variable from the EQUIPMENT scope and can modify it.  Note that this change could then impact the result of the BOOLEAN variable Penalized, since HandsRequired changed.  Note also that &amp;quot;HandsRequired&amp;quot;, when evaluated anywhere in that Equipment is now 1 less.  Even if another EquipmentModifier evaluates HandsRequired, it is analyzing the variable from its parent scope, so that value on a variable from EQUIPMENT is the same in every EquipmentModifier (in the EQUIPMENT.PART scope) of that piece of Equipment.&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScope on Equipment==&lt;br /&gt;
&lt;br /&gt;
Since variables like CritMult and Damage would be on an Equipment &amp;quot;part&amp;quot; it is important to understand how to get access to that &amp;quot;part&amp;quot; from the LST code.  If a single-headed weapon wanted a larger CritMult, it would be silly to have to add a Dummy EquipmentModifier just to modify the CritMult on the part.  (Much of the point of the new system is to make things more direct)&lt;br /&gt;
&lt;br /&gt;
There is a token for Equipment called PART.  This effectively takes 2 arguments: A number (today 1 for the primary head, 2 for the secondary head) and a full token otherwise valid on a plain object.  MODIFY and MODIFYOTHER will both work in that situation, so for a piece of Equipment to set its own CritMult to 3 on its primary (and perhaps only) head, it would do:&lt;br /&gt;
   PART:1|MODIFY:CritMult|SET|3&lt;br /&gt;
&lt;br /&gt;
Note since the MODIFY is a &amp;quot;real&amp;quot; token call it uses &amp;quot;:&amp;quot; after the MODIFY which makes PART look slightly different to most tokens which use | as an internal separator.  Since PART is effectively calling a &amp;quot;real&amp;quot; token, we need to use the inner &amp;quot;:&amp;quot; in order to have it pass through the same code/parsing system.&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScopes in relation to MODIFYOTHER==&lt;br /&gt;
&lt;br /&gt;
* Note Jan 29 2018: There is a possibility of a solution for this issue that would allow MODIFYOTHER to do direct addressing of sub-objects under certain conditions&lt;br /&gt;
&lt;br /&gt;
Normally MODIFYOTHER allows you to &amp;quot;address&amp;quot; another scope.  For example:&lt;br /&gt;
   MODIFYOTHER:EQUIPMENT|Bastard Sword|HandsRequired|ADD|-1&lt;br /&gt;
&lt;br /&gt;
However, since items like Damage and CritMult are actually on the EQUIPMENT.PART, that is different.  If you consider how you would have to &amp;quot;address&amp;quot; the first head on &amp;quot;Bastard Sword&amp;quot;, you would need something like:&lt;br /&gt;
   SOMEWEIRDTOKEN:EQUIPMENT|Bastard Sword|PART|1|CritMult|ADD|1&lt;br /&gt;
&lt;br /&gt;
Note that this requires both a primary and secondary address.  No token like this exists (at the moment).  To alter items in a SubScope, you need to pass them down to the SubScope.  An attempt to modify it at the Equipment level, such as:&lt;br /&gt;
   MyAbility   MODIFYOTHER:EQUIPMENT|ALL|CritMult|ADD|1&lt;br /&gt;
... will fail (at LST load) because CritMult was on EQUIPMENT.PART, so it is not visible to the EQUIPMENT scope.  Said another way, you can't universally modify all EQUIPMENT.PART variables by attempting to use that variable at a higher scope.&lt;br /&gt;
&lt;br /&gt;
A more appropriate method (since this is relevant to a Feat that might alter CritMult) is to add another variable at the EQUIPMENT level:&lt;br /&gt;
   LOCAL:EQUIPMENT|NUMBER=CritMultAdder&lt;br /&gt;
If all the heads then get&lt;br /&gt;
   MODIFY:CritMult|ADD|CritMultAdder&lt;br /&gt;
... you can have the Feat do a MODIFYOTHER to alter CritMultAdder and the MODIFY will &amp;quot;pull&amp;quot; that into each PART:&lt;br /&gt;
   SomeFeat   MODIFYOTHER:EQUIPMENT|ALL|CritMultAdd|ADD|1&lt;br /&gt;
So the data can be set up to only require one modification from a Feat and each Equipment Part can pull that modification down into the part.  (A tangential note for those objecting that the known modifiers of CritMult select a specific weapon type: Yep, got it.  That's not possible yet, so not documented yet.  Suspend disbelief on the examples - Imagine a more powerful Feat for now)&lt;br /&gt;
&lt;br /&gt;
==Understanding PRIORITY and processing of MODIFY and MODIFYOTHER==&lt;br /&gt;
&lt;br /&gt;
When a PlayerCharacter has multiple items that attempt to modify a variable, they are sorted by two systems:&lt;br /&gt;
* First, they are sorted by their user priority.  This is provided in the PRIORITY=Z association.  Lower PRIORITY will be processed first.&lt;br /&gt;
* Second, they are sorted by their inherent priority.  This is a built-in system that approximates mathematical priority rules. It ensures, for example, that a SET will occur before ADD if they both have a matching user priority.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
Assume we had the following items:&lt;br /&gt;
   MODIFY:Hands|MULTIPLY|2|PRIORITY=100&lt;br /&gt;
   MODIFY:Hands|SET|2|PRIORITY=50&lt;br /&gt;
   MODIFY:Hands|ADD|1|PRIORITY=50&lt;br /&gt;
&lt;br /&gt;
The first thing is that we can tell from the PRIORITY items that the SET and ADD will both occur BEFORE the multiply (because 50 &amp;lt; 100).  For the SET and ADD, we would need to know the inherent priority (For what it's worth, SET is 0, ADD is 3, MULTIPLY and DIVIDE are 1 and 2 since they are higher priority than ADD in traditional math).  This means the SET will happen first.  So the result is Hands is SET to 2, then ADD 1 to get 3, then MULTIPLY by 2 to get 6.&lt;br /&gt;
&lt;br /&gt;
By controlling the PRIORITY, the data team can reorder any calculation and perform much more complicated calculations than was possible with BONUS (where movement, for example, had multiple different BONUS tokens to try to do adding before and after a multiply).  This is much the same as using parenthesis in a formula in normal math, but this allows you trigger any required ordering even if the MODIFY statements are in different objects.&lt;br /&gt;
&lt;br /&gt;
==Using the previous value in a more complex calculation==&lt;br /&gt;
&lt;br /&gt;
Take a modification that, for example, wishes to perform a calculation such as: &amp;quot;Reduce the value by 1, but to no less than 1&amp;quot;.  We could write this as two MODIFY statements, but that is probably undesirable for a few reasons: &lt;br /&gt;
* If the book states it as one sentence, it would be preferable to write it as one MODIFY&lt;br /&gt;
* It makes the calculation a bit harder to follow as to what is going on&lt;br /&gt;
* If the items are different PRIORITY, there is a risk of another dataset attempting to (or accidentally) putting something in between those two steps, resulting in an incorrect calculation.  &lt;br /&gt;
&lt;br /&gt;
Therefore, we need a method of drawing on the current value in a formula.  To do that we use the value() function.  The calculation above then becomes:&lt;br /&gt;
   max(value()-1,1)&lt;br /&gt;
...and we can use it in a MODIFY as such:&lt;br /&gt;
   MODIFY:HandsRequired|SET|max(value()-1,1)&lt;br /&gt;
&lt;br /&gt;
Note that we are using SET here - if a formula is used, it is likely to be best done as a SET, since that will be much more clear than calculating a formula and then immediately applying another MODIFICATION.  Note that some modifications may also prohibit a formula depending on their underlying behavior.&lt;br /&gt;
&lt;br /&gt;
=Global Modifier File=&lt;br /&gt;
&lt;br /&gt;
There is a new file type that is defined in the PCC files with GLOBALMODIFIER.&lt;br /&gt;
&lt;br /&gt;
This file allows for a centralized (and clear to the data user) location for global modifications (don't hide things on stats or elsewhere anymore).  This supports MODIFY for global variables (if you want to start all PCs with 2 hands for example) or MODIFYOTHER for local variables.&lt;br /&gt;
&lt;br /&gt;
==GLOBALMODIFIER (PCC File)==&lt;br /&gt;
&lt;br /&gt;
Format:&lt;br /&gt;
   GLOBALMODIFIER:x&lt;br /&gt;
* x is the file to be loaded as a GLOBALMODIFIER file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
=Advanced Topics=&lt;br /&gt;
&lt;br /&gt;
==Dynamic Objects and Scope==&lt;br /&gt;
&lt;br /&gt;
This set of features allows the data to supplement the defined SCOPEs with new object types not originally comprehended in PCGen. Within a Dynamic Scope, the data can produce objects.  &lt;br /&gt;
&lt;br /&gt;
Warning: Attempts to define a SCOPE that overlaps with existing objects (e.g. LANGUAGE) will not produce a warning today but will get you in trouble long term.  It won't work in the way you would like it to work (it won't attach a SCOPE to that object type), so just avoid those overlapping names.  Basically if you can CHOOSE it, or use it with FACT, don't DYMAMICSCOPE it.&lt;br /&gt;
&lt;br /&gt;
===DYNAMICSCOPE (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
The DYNAMICSCOPE token (used in files referred to by the DATACONTROL: token in PCC files) can define a Dynamic Scope.&lt;br /&gt;
&lt;br /&gt;
   DYNAMICSCOPE:x&lt;br /&gt;
&lt;br /&gt;
*x is the new scope&lt;br /&gt;
**Any argument to DYNAMICSCOPE becomes a legal &amp;quot;scope&amp;quot; in LOCAL: in the variable definition file&lt;br /&gt;
**Limit of one new scope per line.  (No delimiter on this token)&lt;br /&gt;
*Like other LST tokens, this is case insensitive, but usage in later tokens is always capitalized, so I suspect the data standard should be ALL CAPS&lt;br /&gt;
&lt;br /&gt;
===DYNAMIC (PCC File)=== &lt;br /&gt;
&lt;br /&gt;
In order to create objects within the defined DYNAMICSCOPE, DYNAMIC: becomes a new token legal in PCC files. It's format is:&lt;br /&gt;
&lt;br /&gt;
   DYNAMIC:x&lt;br /&gt;
&lt;br /&gt;
* x is the file just as in tokens like DEITY or DOMAIN&lt;br /&gt;
* INCLUDE/EXCLUDE on the line are are legal.&lt;br /&gt;
&lt;br /&gt;
Within the Dynamic file, the Scope of the new objects being created MUST appear as a prefix token on the line.  For example, if there was a DYNAMICSCOPE:VISION, then the following would be legal in a DYNAMIC file:&lt;br /&gt;
   VISION:Darkvision&lt;br /&gt;
   VISION:Low-Light Vision&lt;br /&gt;
&lt;br /&gt;
* The &amp;quot;Token Name&amp;quot; (what appears before the ':') is the DYNAMICSCOPE name.&lt;br /&gt;
* These are created as basically hollow, simple objects.  &lt;br /&gt;
* These objects CAN contain variables.&lt;br /&gt;
(It is the intent to allow these at some point to also have MODIFY* tokens, but that is not currently supported)&lt;br /&gt;
&lt;br /&gt;
===GRANT (LST files)===&lt;br /&gt;
&lt;br /&gt;
A Dynamic object MUST be granted in order to have its local variables modified or to have its modifiers have an impact (just like any other object) &lt;br /&gt;
&lt;br /&gt;
    GRANT:x|y&lt;br /&gt;
&lt;br /&gt;
* x is a DYNAMICSCOPE&lt;br /&gt;
* y is the name of the dynamic object.&lt;br /&gt;
&lt;br /&gt;
===Export===&lt;br /&gt;
&lt;br /&gt;
Dynamic items can be exported in Freemarker using the &lt;br /&gt;
&lt;br /&gt;
   &amp;lt;#list pc.dynamic.x as y&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* x is the name of the DYNAMICSCOPE&lt;br /&gt;
* y is the local variable within the #list that the output team wants to use to access the dynamic object&lt;br /&gt;
* It is likely for ease of use by the output team, x and y will be identical&lt;br /&gt;
&lt;br /&gt;
For a complete example using output, see below&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
DATACONTROL: file:&lt;br /&gt;
   DYNAMICSCOPE:VISION&lt;br /&gt;
&lt;br /&gt;
DYNAMIC: file:&lt;br /&gt;
   VISION:Normal&lt;br /&gt;
   VISION:Darkvision&lt;br /&gt;
   VISION:Low-Light Vision&lt;br /&gt;
&lt;br /&gt;
VARIABLE: File:&lt;br /&gt;
   LOCAL:VISION|NUMBER=Range&lt;br /&gt;
&lt;br /&gt;
GLOBALMODIFIERFILE:&lt;br /&gt;
    MODIFYOTHER:VISION|ALL|Range|Set|60&lt;br /&gt;
&lt;br /&gt;
Sets a &amp;quot;default&amp;quot; range for any VISION, to avoid setting on each VISION object&lt;br /&gt;
&lt;br /&gt;
RACE LST file:&lt;br /&gt;
   Human &amp;lt;&amp;gt; GRANT:VISION|Normal&lt;br /&gt;
&lt;br /&gt;
Export:&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;#list pc.dynamic.vision as vision&amp;gt;&lt;br /&gt;
    ${vision.name} ${vision.val.range}&lt;br /&gt;
   &amp;lt;/#list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this ignores converting the range to local units and all that, but you get the idea)&lt;br /&gt;
&lt;br /&gt;
==ARRAY Format==&lt;br /&gt;
&lt;br /&gt;
In addition to the base formats, there is an ARRAY[x] format:&lt;br /&gt;
   ARRAY[x]&lt;br /&gt;
* x is an existing valid Format&lt;br /&gt;
** x CANNOT be ARRAY (multi-dimensional arrays not supported&lt;br /&gt;
** Just to be precise, yes DYNAMIC formats are legal&lt;br /&gt;
&lt;br /&gt;
(Note: This may get renamed - we need to decide on a few things for how this will work vs other types of collections)&lt;br /&gt;
&lt;br /&gt;
===Modifiers===&lt;br /&gt;
&lt;br /&gt;
There are two valid MODIFIERs for ARRAY:&lt;br /&gt;
* ADD: This adds a value to the ARRAY&lt;br /&gt;
** Mathematically, ARRAY acts as an ordered set of objects.  Therefore, if you add an item to an array more than once it is ignored.&lt;br /&gt;
* SET: This sets the contents of the ARRAY&lt;br /&gt;
&lt;br /&gt;
==Custom Functions==&lt;br /&gt;
&lt;br /&gt;
Within certain game systems, there are calculations that are likely to be repeated.  In order to simplify the calculation of these items, there is an ability to create custom functions.&lt;br /&gt;
&lt;br /&gt;
A function can have zero or more arguments.  The number is defined by what appears in the VALUE token (see below).&lt;br /&gt;
&lt;br /&gt;
Note that the function actually has to be *used in the data* (not just defined) for most errors to be caught (since the system can't guess at overall context before a function is used and it would be possible to write a function that would work in more than one FORMAT).&lt;br /&gt;
&lt;br /&gt;
===Function (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
   FUNCTION:x&lt;br /&gt;
* This token must appear as the first token on a line in a DATACONTROL file.&lt;br /&gt;
* x is the name of the function.  This name must starts with a letter, e.g. A-Z, additional legal characters are 0-9 and _ (none of those additional legal characters as the first character)&lt;br /&gt;
** x must not contain spaces, no other special characters.&lt;br /&gt;
** Function names are case insensitive (as many other things in LST files) &lt;br /&gt;
&lt;br /&gt;
A Function MUST also contain a VALUE, which defines how the function is calculated.&lt;br /&gt;
&lt;br /&gt;
If a FUNCTION appears more than once, the other characteristics (VALUE) must be identical. &lt;br /&gt;
&lt;br /&gt;
===Value (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
   VALUE:x&lt;br /&gt;
* Must appear as an additional token on the line of a FUNCTION: in the data control file&lt;br /&gt;
* x is a valid formula.  &lt;br /&gt;
** This means it must have valid variable names, valid function names, matching parenthesis, etc. &lt;br /&gt;
&lt;br /&gt;
In addition to all of the built-in functions (e.g. if, ceil, round), two additional items can be used:&lt;br /&gt;
* the arg(n) function (see below).&lt;br /&gt;
* Any previously defined FUNCTION. This MUST appear in the file before the current Function or in a file processed before the current file.&lt;br /&gt;
&lt;br /&gt;
===arg (Function)===&lt;br /&gt;
&lt;br /&gt;
The arg function is a &amp;quot;local&amp;quot; function to the VALUE: part of a FUNCTION (it can not generally be used in LST files). The arg function takes one argument. It MUST be a Integer &amp;gt;= 0.&lt;br /&gt;
&lt;br /&gt;
   arg(x)&lt;br /&gt;
* x is an integer number (zero-indexed)&lt;br /&gt;
&lt;br /&gt;
When arg(x) is used in value, the function pulls from the arguments that were provided to the original function in the data.  &lt;br /&gt;
&lt;br /&gt;
===Using a Function===&lt;br /&gt;
&lt;br /&gt;
When a function is used in LST data, it is called by the name provided in the FUNCTION token. It requires a certain number of arguments. This exactly matches the integer one greater than the highest number of the arg(n) function provided in the VALUE part of a FUNCTION (In computer science terms, the arg(n) function is zero-indexed). The provided arguments can be any legal formula, so:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(INT)&lt;br /&gt;
   d20Mod(INT+4)&lt;br /&gt;
&lt;br /&gt;
...are both perfectly legal.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
The modification calculation in most d20 games is fairly easy to calculate, but is repeated very often.  It basically takes (ability score - 10)/2.&lt;br /&gt;
&lt;br /&gt;
Here is how we would define a new function d20Mod in the DATACONTROL file:&lt;br /&gt;
   FUNCTION:d20Mod    VALUE:floor((arg(0)-10)/2)&lt;br /&gt;
&lt;br /&gt;
This would then be used in LST data as:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(n)&lt;br /&gt;
&lt;br /&gt;
The system will catch both of these as errors:&lt;br /&gt;
&lt;br /&gt;
   d20Mod()&lt;br /&gt;
   d20Mod(14,5) &lt;br /&gt;
&lt;br /&gt;
These have too few or too many arguments, respectively. It would also catch:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(&amp;quot;mystring&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
...as an error (wrong format - requires a Number, found a String). &lt;br /&gt;
&lt;br /&gt;
The n is substituted where &amp;quot;arg(0)&amp;quot; appears in the &amp;quot;VALUE&amp;quot;... so a statmod would be as easy as:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(INT)&lt;br /&gt;
&lt;br /&gt;
or some such... Direct values can also be used, e.g.:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(10)&lt;br /&gt;
&lt;br /&gt;
...would return 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Performance Considerations==&lt;br /&gt;
&lt;br /&gt;
It is possible to write two identical modifiers that perform the same net calculation on a PC.  For example:&lt;br /&gt;
   MODIFY:Age|ADD|2&lt;br /&gt;
   MODIFY:Age|SET|value()+2&lt;br /&gt;
&lt;br /&gt;
...perform the same calculation (adding 2 to Age).&lt;br /&gt;
&lt;br /&gt;
Why have ADD at all?  Answer: These are NOT AT ALL equivalent in memory use or speed/performance.&lt;br /&gt;
&lt;br /&gt;
The ADD (Since it's adding an integer) occupies approximately 40 bytes of memory and is an extremely rapid calculation: If it took 200 nanoseconds I'd be surprised. This is because ADD is using a number. If it was a formula, even 1+2, it would load the formula parser. This special case on constants allows the modification system to modify a value without loading a much larger infrastructure, and this is valuable as a large majority of our calculations are simple modifications of values.&lt;br /&gt;
&lt;br /&gt;
The SET shown above (since it has an operator) loads the formula system, and thus may occupy 500 (or more) bytes of memory (&amp;gt;10x), so it could take 100 times as long to process as the ADD (it also took longer during LST load).&lt;br /&gt;
&lt;br /&gt;
Thus: When possible the data standards should be written to use numeric modifiers and no operator.  (Think &amp;quot;static&amp;quot; modifiers ... that only use numbers) rather than a formula.&lt;br /&gt;
&lt;br /&gt;
==Lookup and Tables==&lt;br /&gt;
&lt;br /&gt;
For some situations, it makes more sense to have a lookup table rather than attempting to have a set of tokens or calculations perform processing.  This also allows for much cleaner translation from books when the books are using tables to organize information.&lt;br /&gt;
&lt;br /&gt;
The Table file format is designed to allow you to use a spreadsheet program to modify the tables and export the table in CSV format.  While we don't strictly follow full CSV rules, as long as you avoid embedded quotes and embedded return carriage/line feed, it should be safe.&lt;br /&gt;
&lt;br /&gt;
More than one table is allowed per file (to avoid sprawl and help simplify modification/management of tables).&lt;br /&gt;
&lt;br /&gt;
===TABLE (PCC File)===&lt;br /&gt;
&lt;br /&gt;
   TABLE:x&lt;br /&gt;
* x is the file to be loaded as a TABLE file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
====Table LST file format====&lt;br /&gt;
&lt;br /&gt;
File formatting considerations:&lt;br /&gt;
* Trailing commas will not impact any TABLE, and will be ignored&lt;br /&gt;
* Blank lines will be ignored.  This includes lines with commas but without content. (allows tables to be separated by blank lines or lines of all commas)&lt;br /&gt;
* Attempts to use embedded line breaks or embedded quotes may or may not be supported by the parsing system, but certainly aren't supported for purposes of PCGen.&lt;br /&gt;
* Lines that have the first cell starting with &amp;quot;#&amp;quot; are considered comment lines and will be ignored.  This will likely need to include if the first cell is escaped in quotes, just for protection from any tools that quote by default.&lt;br /&gt;
* Since the CSV format ignores leading/trailing spaces, one can easily have a spaced out version that is a table in a text editor if folks don't want to edit in a spreadsheet.  (Having someone write a &amp;quot;PrettyTable&amp;quot; ... a trivial perl or python program to do that for the data team seems fairly easy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A TABLE starts with STARTTABLE:&lt;br /&gt;
   STARTTABLE:x&lt;br /&gt;
* x is the name of the Table.  Most characters are allowed, avoiding quotes is advisable.&lt;br /&gt;
* Allowing Trailing commas allows the STARTTABLE lines to have blank cells where the rest are the table contents... we don't want to complain on minor things that may tools will do.&lt;br /&gt;
&lt;br /&gt;
If a STARTTABLE is encountered when another Table is active, an LST load error will occur.&lt;br /&gt;
&lt;br /&gt;
A TABLE ends with ENDTABLE:&lt;br /&gt;
   ENDTABLE:x&lt;br /&gt;
* x is the name of the Table.  Most characters are allowed, avoiding quotes is advisable.&lt;br /&gt;
* Allowing Trailing commas allows the ENDTABLE lines to have blank cells where the rest are the table contents... we don't want to complain on minor things that may tools will do.&lt;br /&gt;
&lt;br /&gt;
If an ENDTABLE is encountered without a STARTTABLE, an LST load error will occur.&lt;br /&gt;
&lt;br /&gt;
A Table must have a minimum of 3 rows, NOT counting the STARTTABLE and ENDTABLE tokens.&lt;br /&gt;
&lt;br /&gt;
The First row:&lt;br /&gt;
   x,x&lt;br /&gt;
* x is the column name.  These are always the first line of the table after STARTTABLE:&lt;br /&gt;
&lt;br /&gt;
Any column which has data MUST have a name.&lt;br /&gt;
&lt;br /&gt;
The Second row:&lt;br /&gt;
   y,y&lt;br /&gt;
* y is the format for the column.  Any column that was named must have a FORMAT.&lt;br /&gt;
&lt;br /&gt;
Additional rows:&lt;br /&gt;
   z,z&lt;br /&gt;
* z represents contents of the table.  These must be in the FORMAT provided for the appropriate column.&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
&lt;br /&gt;
   STARTTABLE:Carrying Capacity,&lt;br /&gt;
   Strength,Capacity&lt;br /&gt;
   NUMBER,NUMBER&lt;br /&gt;
   1,10&lt;br /&gt;
   2,20&lt;br /&gt;
   ...&lt;br /&gt;
   29,1400&lt;br /&gt;
   ENDTABLE:Carrying Capacity,&lt;br /&gt;
&lt;br /&gt;
===TABLE[x] Format===&lt;br /&gt;
&lt;br /&gt;
When a TABLE is created, it implicitly picks up a FORMAT based on the FORMAT of the first column of the Table.  &lt;br /&gt;
Unlike basic FORMATs shown above, TABLE has a SUBFORMAT (in brackets).&lt;br /&gt;
&lt;br /&gt;
   TABLE[x]&lt;br /&gt;
* x is the SUB-FORMAT of the TABLE (this is the format of the first column of the Table)&lt;br /&gt;
** x must be an otherwise valid FORMAT, and it is advised to avoid any FORMAT that has a SUB-FORMAT&lt;br /&gt;
*** This limitation may be inconsistently enforced.  It certainly is prohibited to create a TABLE[TABLE[x]], but other situations the behavior may not be prohibited by the code (but the behavior is also not guaranteed)&lt;br /&gt;
&lt;br /&gt;
===COLUMN[x] Format===&lt;br /&gt;
&lt;br /&gt;
When a Column needs to be referred to in the data, it has a special format as well:&lt;br /&gt;
&lt;br /&gt;
Unlike basic FORMATs shown above, COLUMN has a SUBFORMAT (in brackets).&lt;br /&gt;
   COLUMN[x]&lt;br /&gt;
* x is the SUB-FORMAT of the COLUMN (this is the format of the data that appears in that column in a Table)&lt;br /&gt;
** x must be an otherwise valid FORMAT, and it is advised to avoid any FORMAT that has a SUB-FORMAT&lt;br /&gt;
*** This limitation may be inconsistently enforced.  Such behavior may not be prohibited by the code (but avoiding bad behavior is also not guaranteed in a situation where embedded brackets occur)&lt;br /&gt;
&lt;br /&gt;
===Using Tables===&lt;br /&gt;
&lt;br /&gt;
With MODIFY, a TABLE[x] variable doesn't look any different.  It's still:&lt;br /&gt;
   MODIFY:TableNameVar|SET|&amp;quot;SomeTable&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SomeTable&amp;quot; is still a string to a naive reader, but what the system will do at that point is make sure that SomeTable can actually be interpreted as a TABLE[x]... rather than just treating it as a String.  Similar for column names when they are encountered (see below).&lt;br /&gt;
&lt;br /&gt;
In that way, the sub variable will allow multiple tables to be swapped in, AS LONG AS they are the right format.  If the format is not compatible, then all bets are off and you'll get an error.&lt;br /&gt;
&lt;br /&gt;
===lookup() Function===&lt;br /&gt;
&lt;br /&gt;
The major consideration is how to do the lookup in data.  We can borrow some inspiration from things like Excel and Google Docs:&lt;br /&gt;
&lt;br /&gt;
   lookup(X,Y,Z)&lt;br /&gt;
&lt;br /&gt;
* X is a table.  This must resolve in the formula system to a valid table.  For now, a get(...) function may be required.&lt;br /&gt;
* Y is the lookup value in the table.  It must match the format of the first column in the table.  At this time, it does an EXACT match.&lt;br /&gt;
* Z is the target column.  This must resolve in the formula system to a valid table column. It must appear in the table named by the contents of the first argument of lookup.&lt;br /&gt;
&lt;br /&gt;
Example: Max load calculation would be something like:&lt;br /&gt;
   lookup(&amp;quot;Carrying Capacity&amp;quot;,floor(StrScore),&amp;quot;Capacity&amp;quot;)*SizeMult&lt;br /&gt;
We have to do the floor due to the exact name of the lookup&lt;br /&gt;
&lt;br /&gt;
Note: The format of both TABLE &amp;quot;Carrying Capacity&amp;quot; and COLUMN &amp;quot;Capacity&amp;quot; can be derived by PCGen internally and thus are no longer required to have a get (current as of Jan 30, 2018)&lt;br /&gt;
&lt;br /&gt;
Note that this function allows some runtime errors, but catches a lot of possible issues.  It is still possible to do a lookup on a Table that doesn't contain a specific column of the given name or format, simply because those items can be variables resolved at runtime.  For example, if the third variable is COLUMN[NUMBER], we can check at load that the TABLEFORMAT has columns of FORMAT=NUMBER, but we can't guarantee the variable will resolve to a name actually in that table... that will have to wait for a runtime error.  That's life, but it does allow us to know the formats at load time, so we do get a lot of error checking in the context of the usage, if not the exact table and column names.&lt;br /&gt;
&lt;br /&gt;
Note you can do some really dynamic behaviors to have folks override game mode behaviors.  For example, one neat item would be that we could alter a query for dice steps to extract the table name into the Global Modifier file:&lt;br /&gt;
   MODIFY:DiceStepTable|SET|&amp;quot;Dice Step&amp;quot;&lt;br /&gt;
   lookup(get(&amp;quot;TABLE[NUMBER]&amp;quot;,DiceStepTable),BaseDamage,get(&amp;quot;COLUMN[NUMBER]&amp;quot;,lookup(&amp;quot;Step Column&amp;quot;,CurrentSize-BaseSize,&amp;quot;Name&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
Note: In both cases here, the &amp;quot;get&amp;quot; is shown for completeness.  In the case of DiceStepTable - it MAY be required or prohibited - it depends on what the Format is of the &amp;quot;DiceStepTable&amp;quot; variable.  If it's TABLE, then the get is not necessary (and is actually prohibited).  The example shown above assumes DiceStepTable is a String.  The better design would be for it to be a TABLE (specifically TABLE[NUMBER]).  For the &amp;quot;get&amp;quot; after the lookup, that is required - the lookup value will return a STRING, and as such, will needs to be converted to a COLUMN.&lt;br /&gt;
&lt;br /&gt;
Now, if someone needs different dice steps for some reason... they can override the DiceStepTable variable and it will look up in a different table... so expansions could truly be expansions and not have to reach back into core PCC files in order to change key behaviors.&lt;br /&gt;
&lt;br /&gt;
Consider also that spell tables can be shared across classes, or if a subclass alters the default, just create a new table rather than having to BONUS/MODIFY all the numbers in a table with adding and subtracting...&lt;br /&gt;
&lt;br /&gt;
==To be completed==&lt;br /&gt;
* dropIntoContext&lt;br /&gt;
* Channels&lt;br /&gt;
&lt;br /&gt;
=Material Changes=&lt;br /&gt;
&lt;br /&gt;
==lookup function simplification==&lt;br /&gt;
&lt;br /&gt;
Effective January 30, 2018, tables and columns can be referred to directly in lookup().  This is actually a &amp;quot;broad&amp;quot; change to how strings are interpreted.  The system - when possible - fully asserts a FORMAT, and first attempts to convert the given String per the rules of that FORMAT.  This also means an assignment of an ALIGNMENT, by key, will not require a &amp;quot;get&amp;quot;:&lt;br /&gt;
   MODIFY:Alignment|SET|&amp;quot;LE&amp;quot;&lt;br /&gt;
...will be fully legal.  (This assumes Alignment is FORMAT: of ALIGNMENT)&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Setting_up_the_new_Formula_System&amp;diff=4283</id>
		<title>Setting up the new Formula System</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Setting_up_the_new_Formula_System&amp;diff=4283"/>
		<updated>2018-03-09T15:18:36Z</updated>

		<summary type="html">&lt;p&gt;Nuance: Fix cut and paste error.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=The basics=&lt;br /&gt;
&lt;br /&gt;
The new formula system is designed to do a few things relative to data:&lt;br /&gt;
* Validate formulas at LST load instead of runtime&lt;br /&gt;
* Dramatically increase flexibility&lt;br /&gt;
* It will replace many tokens, including all the BONUS tokens&lt;br /&gt;
* It allows a sensible location for global modifications (things generally related to rule book type modifications that impact all objects of a given type)&lt;br /&gt;
&lt;br /&gt;
==Key concepts==&lt;br /&gt;
&lt;br /&gt;
To use the new system a few key things need to be remembered:&lt;br /&gt;
* It is possible to have local variables&lt;br /&gt;
* All variables must be defined prior to use&lt;br /&gt;
* Variables are not only numbers, but can be Strings, Dice, etc.&lt;br /&gt;
** We call this the variable FORMAT&lt;br /&gt;
&lt;br /&gt;
You will want to keep track of what these key terms mean as you learn the new formula system:&lt;br /&gt;
* FORMAT: The type of variable, e.g. NUMBER, BOOLEAN, ORDEREDPAIR.&lt;br /&gt;
* SCOPE: The part of the data in which a (local) variable is available&lt;br /&gt;
* MODIFIER: An argument to MODIFY* tokens, specifically the &amp;quot;command&amp;quot; of what the modification represents&lt;br /&gt;
* OPERATOR: A mathematical operator as you would see in a formula (&amp;quot;+&amp;quot;, &amp;quot;-&amp;quot;, etc.)&lt;br /&gt;
* GROUPING: A name for a set of objects in PCGen&lt;br /&gt;
* ASSOCIATION: An additional set of information attached to a MODIFY* token.  This is a key-value pair of information, e.g. PRIORITY=100&lt;br /&gt;
&lt;br /&gt;
=Creating and Using Variables=&lt;br /&gt;
&lt;br /&gt;
==Required Setup==&lt;br /&gt;
&lt;br /&gt;
Every format that needs to be used requires a default value. This value is shared throughout an entire system (it CANNOT be redefined to a different value).  This is placed into a file referred to in a PCC file from the DATACONTROL: token.&lt;br /&gt;
&lt;br /&gt;
===DATACONTROL (PCC File)===&lt;br /&gt;
&lt;br /&gt;
DATACONTROL: is a new Campaign file token (for PCC files).  It is treated &amp;quot;recursively&amp;quot; like other tokens, e.g. TEMPLATE.  &lt;br /&gt;
&lt;br /&gt;
   DATACONTROL:x&lt;br /&gt;
&lt;br /&gt;
* x is the file to be loaded as a DATACONTROL file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
===DEFAULTVARIABLEVALUE (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
The Format is:&lt;br /&gt;
   DEFAULTVARIABLEVALUE:X|Y&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the default value&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   DEFAULTVARIABLEVALUE:NUMBER|0&lt;br /&gt;
&lt;br /&gt;
It is a best practice to always define a DEFAULTVARIABLEVALUE for every FORMAT regardless of whether the data uses that FORMAT.  The internal parts of PCGen may use it, so a default value may be required.&lt;br /&gt;
&lt;br /&gt;
Note: it IS safe to &amp;quot;redefine&amp;quot; a DEFAULTVARIABLEVALUE to the same value.  So if multiple datasets are loaded and they all had DATACONTROL: and all defined the default value for NUMBER to be 0, they will all happily load as the system is capable of recognizing the defaults are the same&lt;br /&gt;
&lt;br /&gt;
==How to define a variable==&lt;br /&gt;
&lt;br /&gt;
===VARIABLE (PCC File)===&lt;br /&gt;
&lt;br /&gt;
To define a variable, you need to add an LST file that is referred to in a PCC file from the VARIABLE: token.  It is treated &amp;quot;recursively&amp;quot; like other tokens, e.g. TEMPLATE.  &lt;br /&gt;
&lt;br /&gt;
   VARIABLE:x&lt;br /&gt;
&lt;br /&gt;
* x is the file to be loaded as a VARIABLE file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
There are 2 basic tokens for the VARIABLE file: GLOBAL and LOCAL.&lt;br /&gt;
&lt;br /&gt;
===GLOBAL (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
* GLOBAL defines a global variable, usable from anywhere within the PlayerCharacter.&lt;br /&gt;
&lt;br /&gt;
The format is:&lt;br /&gt;
   GLOBAL:X=Y&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the variable name&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   GLOBAL:ORDEREDPAIR=Face&lt;br /&gt;
&lt;br /&gt;
A GLOBAL token can take additional token on the line called EXPLANATION, which it is advisable to use to communicate to other data monkeys (and it is likely any future editor will also draw on this information).&lt;br /&gt;
&lt;br /&gt;
===LOCAL (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
* LOCAL defines a local variable, usable only within the object on which the variable exists (or its children)&lt;br /&gt;
** The place where a local variable is usable is called the SCOPE.  This could include a STAT (such as the stat's SCORE or STATMOD) or EQUIPMENT.  The scopes possible in PCGen are hard-coded (see below for more info)&lt;br /&gt;
&lt;br /&gt;
The format is:&lt;br /&gt;
   LOCAL:W|X=Y&lt;br /&gt;
* W is the SCOPE of the variable&lt;br /&gt;
* X is the format name&lt;br /&gt;
* Y is the variable name&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
   LOCAL:STAT|NUMBER=Score&lt;br /&gt;
&lt;br /&gt;
A LOCAL token can take additional token on the line called EXPLANATION, which it is advisable to use to communicate to other data monkeys (and it is likely any future editor will also draw on this information).&lt;br /&gt;
&lt;br /&gt;
===EXPLANATION (VARIABLE File)===&lt;br /&gt;
&lt;br /&gt;
EXPLANATION: is a free-text token (no parsing is really done) that is designed to describe why a variable exists&lt;br /&gt;
&lt;br /&gt;
Format:&lt;br /&gt;
   EXPLANATION:x&lt;br /&gt;
&lt;br /&gt;
* x is the text of the Explanation&lt;br /&gt;
* Limitations: By Design: Must not appear as the first token on a line&lt;br /&gt;
* Behavior: Overwrites (as if someone would use it twice??)&lt;br /&gt;
&lt;br /&gt;
===Defaults in the VARIABLE file===&lt;br /&gt;
&lt;br /&gt;
A few notes about the VARIABLE files:&lt;br /&gt;
If you see an item without a leading token, e.g.:&lt;br /&gt;
   ORDEREDPAIR=Face&lt;br /&gt;
...then the system is using the default (GLOBAL).  For now, the data standard is to avoid using this shortcut (as far as I know)&lt;br /&gt;
&lt;br /&gt;
If you see an item without a leading format (&amp;quot;X&amp;quot; in both GLOBAL and LOCAL above), e.g.:&lt;br /&gt;
   LOCAL:STAT|Score&lt;br /&gt;
...then the format is a NUMBER.  For now, the data standard is to avoid using this shortcut (as far as I know)&lt;br /&gt;
&lt;br /&gt;
Note both defaults can be combined, so a variable name with no other information on that line is a Global NUMBER&lt;br /&gt;
&lt;br /&gt;
===No Overlapping===&lt;br /&gt;
&lt;br /&gt;
In most programming languages, it is legal to have local variable share the same name as the global variable and thus &amp;quot;override&amp;quot; it in that context (although it is considered less than ideal, and in some languages it will now produce a warning).  It is not legal in PCGen.&lt;br /&gt;
&lt;br /&gt;
If a Global variable called &amp;quot;Hands&amp;quot; exists, then NO local variable IN ANY SCOPE can be &amp;quot;Hands&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Similar restrictions exist for scopes and SubScopes.  If &amp;quot;CritMult&amp;quot; is an EQUIPMENT variable, then &amp;quot;CritMult&amp;quot; can't be an EQUIPMENT.PART variable.  &lt;br /&gt;
&lt;br /&gt;
Non-overlapping (when the Scopes do not interact) is legal.  &amp;quot;Score&amp;quot; can be a local STAT variable and a local CHECK variable, for example.&lt;br /&gt;
&lt;br /&gt;
For clarity: &lt;br /&gt;
* This occurs regardless of the FORMAT of the variables - tokens will infer the format from the variable name, so you can't have overlapping variables even of different FORMAT.&lt;br /&gt;
* Two variables of the same name but different FORMAT in the same SCOPE will cause an error as well, because that is effectively overlapping, and those variables can't be distinguished in most circumstances.&lt;br /&gt;
&lt;br /&gt;
===Identical Duplication Legal===&lt;br /&gt;
&lt;br /&gt;
It is legal for a load to include one or more PCC files that have one or more VARIABLE: files that redefine the same variables.  As long as they are the same format and scope, they are not considered an error.  If either the scope or format differs, then the &amp;quot;No Overlapping&amp;quot; rules above are applied.&lt;br /&gt;
&lt;br /&gt;
A difference in the &amp;quot;Explanation&amp;quot; text is not considered a difference in the variables significant enough to trigger an error. (In fact, the last loaded Explanation will &amp;quot;win&amp;quot; -&amp;gt; it is overwritten each time it is encountered for redefined but identical variables)&lt;br /&gt;
&lt;br /&gt;
==Setting and Modifying a variable==&lt;br /&gt;
&lt;br /&gt;
===MODIFY (LST files)===&lt;br /&gt;
&lt;br /&gt;
The MODIFY token is used to set a variable that is accessible in the current SCOPE.  (Note: It could be local to the current scope or any ancestor of the current scope... so modifying a global variable always just requires MODIFY)&lt;br /&gt;
&lt;br /&gt;
The format of the token is: &lt;br /&gt;
   MODIFY:V|W|X|Y=Z|Y=Z&lt;br /&gt;
* V is the Variable name for which the value will be modified&lt;br /&gt;
**  This variable MUST be visible in the current scope.  Therefore, it must be either a global variable or a local variable on the current object or its parents.&lt;br /&gt;
* W is the MODIFIER to be taken on the variable (e.g. SET)&lt;br /&gt;
** There can be multiple actions (more below), but SET will ALWAYS be available for any format.&lt;br /&gt;
* X is the value related to the action.  If the action is set, the variable will be set to the value in this part of the token.&lt;br /&gt;
** Note: The value CAN be a formula.  It is possible, for example, to SET a variable to OtherVar+4 ... the system will solve that formula.  For legal OPERATORS (e.g. &amp;quot;+&amp;quot;) , see below.&lt;br /&gt;
* Y is the name of an (optional) ASSOCIATION.  For now, PRIORITY (more below) is the only available association.&lt;br /&gt;
* Z is the value of the association.&lt;br /&gt;
&lt;br /&gt;
Note: If a PRIORITY is not set it is assumed to be ZERO.&lt;br /&gt;
&lt;br /&gt;
Example: Give a Player Character 2 hands:&lt;br /&gt;
   MODIFY:Hands|SET|2&lt;br /&gt;
&lt;br /&gt;
===MODIFYOTHER (LST files)===&lt;br /&gt;
&lt;br /&gt;
The MODIFYOTHER token is used to set a variable that is not accessible in the current SCOPE.  Beyond what is necessary in MODIFY, this token also requires the &amp;quot;address&amp;quot; of where to go before it runs the modification.  Think of it as the ability to remotely place a MODIFY on another object (but revoke that MODIFY if the current object is no longer granted to the PC)&lt;br /&gt;
&lt;br /&gt;
The format of the token is: &lt;br /&gt;
   MODIFYOTHER:T|U|V|W|X|Y=Z|Y=Z&lt;br /&gt;
* T is the FORMAT of the object on which the resulting MODIFY (as defined by V-Z) should occur&lt;br /&gt;
* U is the object or GROUPING of objects on which the MODIFY (as defined by V-Z) should occur&lt;br /&gt;
** Note that this does not and will not support TYPE.&lt;br /&gt;
* V is the Variable name for which the value will be modified&lt;br /&gt;
**  This variable MUST be visible in the scope of the addressed object.  Therefore, it is likely to be a local variable on the remote object or its parents.  &lt;br /&gt;
** In rare cases, a remote modification of a global variable is useful.  It effectively adds to that global variable only if both objects are granted to the PC.&lt;br /&gt;
* W is the MODIFIER to be taken on the variable (e.g. SET)&lt;br /&gt;
** There can be multiple actions (more below), but SET will ALWAYS be available for any format.&lt;br /&gt;
* X is the value related to the action.  If the action is set, the variable will be set to the value in this part of the token.&lt;br /&gt;
** Note: The value CAN be a formula.  It is possible, for example, to SET a variable to OtherVar+4 ... the system will solve that formula.  For legal OPERATORS (e.g. &amp;quot;+&amp;quot;) , see below.&lt;br /&gt;
* Y is the name of an (optional) ASSOCIATION.  For now, PRIORITY (more below) is the only available association.&lt;br /&gt;
* Z is the value of the association.&lt;br /&gt;
&lt;br /&gt;
Note: If a PRIORITY is not set it is assumed to be ZERO.&lt;br /&gt;
&lt;br /&gt;
Example: Reduce the HandsRequired on all Weapons by 1:&lt;br /&gt;
   MODIFYOTHER:EQUIPMENT|GROUP=Weapon|HandsRequired|ADD|-1&lt;br /&gt;
&lt;br /&gt;
Note this assumes GROUP:Weapon is in the LST line of every Weapon... PCGen can't guess or derive what a weapon is :)&lt;br /&gt;
&lt;br /&gt;
==Formulas==&lt;br /&gt;
&lt;br /&gt;
SET as a MODIFIER allows the use of a formula for the value.  This follows many mathematical systems of using parenthesis - &amp;quot;(&amp;quot; and &amp;quot;)&amp;quot; to be precise - to group (and thus prioritize parts of the calculation). &lt;br /&gt;
There are a number of build in OPERATORs (see below).  The system can also use functions, which use parenthesis to contain their arguments.  For example:&lt;br /&gt;
* min(this,that)&lt;br /&gt;
Would return the minimum of the two variables &amp;quot;this&amp;quot; and &amp;quot;that&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Built in Functions===&lt;br /&gt;
&lt;br /&gt;
The system also has a series of built-in functions that work with the NUMBER format:&lt;br /&gt;
* abs: calculates the absolute value of the one argument.&lt;br /&gt;
* ceil: calculates the next integer that is &amp;gt;= the value of the one argument.&lt;br /&gt;
* floor: calculates the next lower integer that is &amp;lt;= the value of the one argument&lt;br /&gt;
* if: conditionally performs an operation.  The first argument must resolve to a BOOLEAN.  If true, the second argument is evaluated; if false, the third argument is evaluated.&lt;br /&gt;
* max: calculates the maximum of the provided two or more comma-separated arguments&lt;br /&gt;
* min: calculates the minimum of the provided two or more comma-separated arguments&lt;br /&gt;
* round: calculates the closest integer to the value of the one argument.  Exactly 0.5 is rounded up.&lt;br /&gt;
* value: returns the value of the calculation before the current modification was started (no arguments)&lt;br /&gt;
&lt;br /&gt;
Additional functions specifically related to PCGen are available:&lt;br /&gt;
* get: This function takes two arguments.  The first is a Object type (like &amp;quot;SKILL&amp;quot;), the second is the key of a CDOMObject (like a Skill) (also in quotes)&lt;br /&gt;
**Example: get(&amp;quot;SKILL&amp;quot;,&amp;quot;Hide&amp;quot;)&lt;br /&gt;
* getFact: This function returns the value of a FACT.  The first two arguments are much like the two arguments of &amp;quot;get&amp;quot;, the third argument is the name of the FACT to be returned&lt;br /&gt;
&lt;br /&gt;
=Legal Values=&lt;br /&gt;
&lt;br /&gt;
==FORMATs==&lt;br /&gt;
&lt;br /&gt;
Currently, the following are built-in formats:&lt;br /&gt;
* NUMBER: This is a mathematical value.  Note that integer arithmetic is done if possible, so if you have an integer 6 and an integer 3, 6/3 will be an integer 2.  If the 6 or 3 is a decimal value (double), then integer arithmetic was not possible and thus rounding may occur.&lt;br /&gt;
* STRING: A String&lt;br /&gt;
* BOOLEAN: A True/False value&lt;br /&gt;
* ORDEREDPAIR: An ordered pair of numbers.  This could be an X,Y point (or in a game system more like a FACE)&lt;br /&gt;
* DICE: A value that takes the form AdB+C.  A is the number of rolls of the die, B is the number of sides on the die, and C is the value to be added afterwords&lt;br /&gt;
* ALIGNMENT: An alignment object (None is default typically)&lt;br /&gt;
&lt;br /&gt;
==OPERATORs==&lt;br /&gt;
&lt;br /&gt;
For NUMBER, the following modifiers are available:&lt;br /&gt;
* +: performs addition&lt;br /&gt;
* -: performs subtraction (or is the unary minus operator to make a value negative)&lt;br /&gt;
* *: performs multiplication&lt;br /&gt;
* /: performs division&lt;br /&gt;
* %: performs a remainder function&lt;br /&gt;
* ^: performs an exponential calculation&lt;br /&gt;
* ==: Checks for equality (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* !=: Checks for inequality (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;gt;: Checks for greater than (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;lt;: Checks for less than (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;gt;=: Checks for greater than or equal to (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
* &amp;lt;=: Checks for less than or equal to (NOTE: Returns a BOOLEAN, not a NUMBER)&lt;br /&gt;
&lt;br /&gt;
For BOOLEAN, the following modifiers are available:&lt;br /&gt;
* ==: Checks for equality&lt;br /&gt;
* !=: Checks for inequality&lt;br /&gt;
* &amp;amp;&amp;amp;: Performs a logical AND&lt;br /&gt;
* ||: Performs a logical OR&lt;br /&gt;
* !: Negates the value&lt;br /&gt;
&lt;br /&gt;
For other formats, the following operators are always available:&lt;br /&gt;
* ==: Checks for equality (NOTE: Returns a BOOLEAN, not the compared format)&lt;br /&gt;
* !=: Checks for inequality (NOTE: Returns a BOOLEAN, not the compared format)&lt;br /&gt;
&lt;br /&gt;
==MODIFIERs==&lt;br /&gt;
&lt;br /&gt;
For NUMBER, the following modifiers are available:&lt;br /&gt;
* SET: This sets the variable to the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* ADD: This adds the current value of the variable to the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* MAX: This takes the maximum value of the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter (i.e. min(current value, &amp;quot;X&amp;quot;))&lt;br /&gt;
* MIN: This takes the minimum value of the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter (i.e. max(current value, &amp;quot;X&amp;quot;))&lt;br /&gt;
* MULTIPLY: This multiplies the current value of the variable and the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
* DIVIDE: This divides the current value of the variable by the value provided in the &amp;quot;X&amp;quot; parameter&lt;br /&gt;
&lt;br /&gt;
For other Formats, the SET modifier will always be available&lt;br /&gt;
&lt;br /&gt;
==GROUPINGs==&lt;br /&gt;
&lt;br /&gt;
At present, the second argument of MODIFYOTHER supports 3 possible values:&lt;br /&gt;
* ALL&lt;br /&gt;
** This means the MODIFYOTHER will impact ALL objects of that type.  This is useful for setting a general default for that value (e.g. you could default &amp;quot;HandsRequired&amp;quot; on weapons to 1)&lt;br /&gt;
* GROUP=X&lt;br /&gt;
** This is set by the GROUP token in LST data&lt;br /&gt;
* A specific object KEY&lt;br /&gt;
&lt;br /&gt;
More will be added over time.&lt;br /&gt;
&lt;br /&gt;
==SCOPEs==&lt;br /&gt;
&lt;br /&gt;
The following are the legal scopes (not including GLOBAL):&lt;br /&gt;
* EQUIPMENT: This is a variable local to equipment&lt;br /&gt;
** EQUIPMENT.PART: This is a variable local to an equipment PART (or in older terms, an Equipment HEAD).  Note that due to double sided weapons, Damage, CritMult and other items are generally on an equipment PART, not on the Equipment itself.  Note also that this is a SUBSCOPE of the EQUIPMENT scope (so all variables in the EQUIPMENT scope can also be seen in the EQUIPMENT.PART scope)&lt;br /&gt;
* SAVE: This is a variable local to Save (or if you prefer, Check)&lt;br /&gt;
* SIZE: This is a variable local to the Size of a PC&lt;br /&gt;
* SKILL: This is a variable local to a Skill&lt;br /&gt;
* STAT: This is a variable local to a Stat&lt;br /&gt;
&lt;br /&gt;
More will be added over time.&lt;br /&gt;
&lt;br /&gt;
DYNAMIC can also be used to create a Scope and Object Type (see below)&lt;br /&gt;
&lt;br /&gt;
=Examples=&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScope in practice==&lt;br /&gt;
&lt;br /&gt;
To understand how local variables work in SubScopes, consider the following (note this is not all the variables we will use but a critical set to define the scope):&lt;br /&gt;
   GLOBAL:NUMBER=Hands&lt;br /&gt;
   LOCAL:EQUIPMENT|NUMBER=HandsRequired&lt;br /&gt;
   LOCAL:EQUIPMENT|BOOLEAN=Penalized&lt;br /&gt;
   LOCAL:EQUIPMENT.PART|NUMBER=CritMult&lt;br /&gt;
&lt;br /&gt;
The Equipment part is what the traditional system called a &amp;quot;head&amp;quot; (so a double headed axe has two &amp;quot;parts&amp;quot; in the new system - this was done since in some game systems, an item could have more than 2)&lt;br /&gt;
&lt;br /&gt;
To understand how variables are available and how they get modified consider this:&lt;br /&gt;
&lt;br /&gt;
Inside of a piece of equipment it could do something like:&lt;br /&gt;
   MODIFY:Penalized|SET|HandsRequired&amp;gt;Hands&lt;br /&gt;
&lt;br /&gt;
This would be &amp;quot;true&amp;quot; if HandsRequired on the Equipment were more than the Hands on the PC.  The &amp;quot;Hands&amp;quot; variable is Global, so it is available anywhere.  A Template of &amp;quot;Extra Hands&amp;quot; could do something like: &lt;br /&gt;
   MODIFY:Hands|ADD|2 &lt;br /&gt;
... and that adds to the Global variable &amp;quot;Hands&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now consider an Equipment Modifier that was something like &amp;quot;Lighter Than Normal&amp;quot;.  Assume the game benefit was one less hand is required.  This would look like:&lt;br /&gt;
   Lighter Than Normal   MODIFY:HandsRequired|ADD|-1&lt;br /&gt;
(This ignores for the moment any situation like &amp;quot;can't be reduced to below one&amp;quot;.)&lt;br /&gt;
&lt;br /&gt;
Note that the EquipmentModifier falls into EQUIPMENT.PART, so that it has access to the HandsRequired variable from the EQUIPMENT scope and can modify it.  Note that this change could then impact the result of the BOOLEAN variable Penalized, since HandsRequired changed.  Note also that &amp;quot;HandsRequired&amp;quot;, when evaluated anywhere in that Equipment is now 1 less.  Even if another EquipmentModifier evaluates HandsRequired, it is analyzing the variable from its parent scope, so that value on a variable from EQUIPMENT is the same in every EquipmentModifier (in the EQUIPMENT.PART scope) of that piece of Equipment.&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScope on Equipment==&lt;br /&gt;
&lt;br /&gt;
Since variables like CritMult and Damage would be on an Equipment &amp;quot;part&amp;quot; it is important to understand how to get access to that &amp;quot;part&amp;quot; from the LST code.  If a single-headed weapon wanted a larger CritMult, it would be silly to have to add a Dummy EquipmentModifier just to modify the CritMult on the part.  (Much of the point of the new system is to make things more direct)&lt;br /&gt;
&lt;br /&gt;
There is a token for Equipment called PART.  This effectively takes 2 arguments: A number (today 1 for the primary head, 2 for the secondary head) and a full token otherwise valid on a plain object.  MODIFY and MODIFYOTHER will both work in that situation, so for a piece of Equipment to set its own CritMult to 3 on its primary (and perhaps only) head, it would do:&lt;br /&gt;
   PART:1|MODIFY:CritMult|SET|3&lt;br /&gt;
&lt;br /&gt;
Note since the MODIFY is a &amp;quot;real&amp;quot; token call it uses &amp;quot;:&amp;quot; after the MODIFY which makes PART look slightly different to most tokens which use | as an internal separator.  Since PART is effectively calling a &amp;quot;real&amp;quot; token, we need to use the inner &amp;quot;:&amp;quot; in order to have it pass through the same code/parsing system.&lt;br /&gt;
&lt;br /&gt;
==Understanding SubScopes in relation to MODIFYOTHER==&lt;br /&gt;
&lt;br /&gt;
* Note Jan 29 2018: There is a possibility of a solution for this issue that would allow MODIFYOTHER to do direct addressing of sub-objects under certain conditions&lt;br /&gt;
&lt;br /&gt;
Normally MODIFYOTHER allows you to &amp;quot;address&amp;quot; another scope.  For example:&lt;br /&gt;
   MODIFYOTHER:EQUIPMENT|Bastard Sword|HandsRequired|ADD|-1&lt;br /&gt;
&lt;br /&gt;
However, since items like Damage and CritMult are actually on the EQUIPMENT.PART, that is different.  If you consider how you would have to &amp;quot;address&amp;quot; the first head on &amp;quot;Bastard Sword&amp;quot;, you would need something like:&lt;br /&gt;
   SOMEWEIRDTOKEN:EQUIPMENT|Bastard Sword|PART|1|CritMult|ADD|1&lt;br /&gt;
&lt;br /&gt;
Note that this requires both a primary and secondary address.  No token like this exists (at the moment).  To alter items in a SubScope, you need to pass them down to the SubScope.  An attempt to modify it at the Equipment level, such as:&lt;br /&gt;
   MyAbility   MODIFYOTHER:EQUIPMENT|ALL|CritMult|ADD|1&lt;br /&gt;
... will fail (at LST load) because CritMult was on EQUIPMENT.PART, so it is not visible to the EQUIPMENT scope.  Said another way, you can't universally modify all EQUIPMENT.PART variables by attempting to use that variable at a higher scope.&lt;br /&gt;
&lt;br /&gt;
A more appropriate method (since this is relevant to a Feat that might alter CritMult) is to add another variable at the EQUIPMENT level:&lt;br /&gt;
   LOCAL:EQUIPMENT|NUMBER=CritMultAdder&lt;br /&gt;
If all the heads then get&lt;br /&gt;
   MODIFY:CritMult|ADD|CritMultAdder&lt;br /&gt;
... you can have the Feat do a MODIFYOTHER to alter CritMultAdder and the MODIFY will &amp;quot;pull&amp;quot; that into each PART:&lt;br /&gt;
   SomeFeat   MODIFYOTHER:EQUIPMENT|ALL|CritMultAdd|ADD|1&lt;br /&gt;
So the data can be set up to only require one modification from a Feat and each Equipment Part can pull that modification down into the part.  (A tangential note for those objecting that the known modifiers of CritMult select a specific weapon type: Yep, got it.  That's not possible yet, so not documented yet.  Suspend disbelief on the examples - Imagine a more powerful Feat for now)&lt;br /&gt;
&lt;br /&gt;
==Understanding PRIORITY and processing of MODIFY and MODIFYOTHER==&lt;br /&gt;
&lt;br /&gt;
When a PlayerCharacter has multiple items that attempt to modify a variable, they are sorted by two systems:&lt;br /&gt;
* First, they are sorted by their user priority.  This is provided in the PRIORITY=Z association.  Lower PRIORITY will be processed first.&lt;br /&gt;
* Second, they are sorted by their inherent priority.  This is a built-in system that approximates mathematical priority rules. It ensures, for example, that a SET will occur before ADD if they both have a matching user priority.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
Assume we had the following items:&lt;br /&gt;
   MODIFY:Hands|MULTIPLY|2|PRIORITY=100&lt;br /&gt;
   MODIFY:Hands|SET|2|PRIORITY=50&lt;br /&gt;
   MODIFY:Hands|ADD|1|PRIORITY=50&lt;br /&gt;
&lt;br /&gt;
The first thing is that we can tell from the PRIORITY items that the SET and ADD will both occur BEFORE the multiply (because 50 &amp;lt; 100).  For the SET and ADD, we would need to know the inherent priority (For what it's worth, SET is 0, ADD is 3, MULTIPLY and DIVIDE are 1 and 2 since they are higher priority than ADD in traditional math).  This means the SET will happen first.  So the result is Hands is SET to 2, then ADD 1 to get 3, then MULTIPLY by 2 to get 6.&lt;br /&gt;
&lt;br /&gt;
By controlling the PRIORITY, the data team can reorder any calculation and perform much more complicated calculations than was possible with BONUS (where movement, for example, had multiple different BONUS tokens to try to do adding before and after a multiply).  This is much the same as using parenthesis in a formula in normal math, but this allows you trigger any required ordering even if the MODIFY statements are in different objects.&lt;br /&gt;
&lt;br /&gt;
==Using the previous value in a more complex calculation==&lt;br /&gt;
&lt;br /&gt;
Take a modification that, for example, wishes to perform a calculation such as: &amp;quot;Reduce the value by 1, but to no less than 1&amp;quot;.  We could write this as two MODIFY statements, but that is probably undesirable for a few reasons: &lt;br /&gt;
* If the book states it as one sentence, it would be preferable to write it as one MODIFY&lt;br /&gt;
* It makes the calculation a bit harder to follow as to what is going on&lt;br /&gt;
* If the items are different PRIORITY, there is a risk of another dataset attempting to (or accidentally) putting something in between those two steps, resulting in an incorrect calculation.  &lt;br /&gt;
&lt;br /&gt;
Therefore, we need a method of drawing on the current value in a formula.  To do that we use the value() function.  The calculation above then becomes:&lt;br /&gt;
   max(value()-1,1)&lt;br /&gt;
...and we can use it in a MODIFY as such:&lt;br /&gt;
   MODIFY:HandsRequired|SET|max(value()-1,1)&lt;br /&gt;
&lt;br /&gt;
Note that we are using SET here - if a formula is used, it is likely to be best done as a SET, since that will be much more clear than calculating a formula and then immediately applying another MODIFICATION.  Note that some modifications may also prohibit a formula depending on their underlying behavior.&lt;br /&gt;
&lt;br /&gt;
=Global Modifier File=&lt;br /&gt;
&lt;br /&gt;
There is a new file type that is defined in the PCC files with GLOBALMODIFIER.&lt;br /&gt;
&lt;br /&gt;
This file allows for a centralized (and clear to the data user) location for global modifications (don't hide things on stats or elsewhere anymore).  This supports MODIFY for global variables (if you want to start all PCs with 2 hands for example) or MODIFYOTHER for local variables.&lt;br /&gt;
&lt;br /&gt;
==GLOBALMODIFIER (PCC File)==&lt;br /&gt;
&lt;br /&gt;
Format:&lt;br /&gt;
   GLOBALMODIFIER:x&lt;br /&gt;
* x is the file to be loaded as a GLOBALMODIFIER file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
=Advanced Topics=&lt;br /&gt;
&lt;br /&gt;
==Dynamic Objects and Scope==&lt;br /&gt;
&lt;br /&gt;
This set of features allows the data to supplement the defined SCOPEs with new object types not originally comprehended in PCGen. Within a Dynamic Scope, the data can produce objects.  &lt;br /&gt;
&lt;br /&gt;
Warning: Attempts to define a SCOPE that overlaps with existing objects (e.g. LANGUAGE) will not produce a warning today but will get you in trouble long term.  It won't work in the way you would like it to work (it won't attach a SCOPE to that object type), so just avoid those overlapping names.  Basically if you can CHOOSE it, or use it with FACT, don't DYMAMICSCOPE it.&lt;br /&gt;
&lt;br /&gt;
===DYNAMICSCOPE (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
The DYNAMICSCOPE token (used in files referred to by the DATACONTROL: token in PCC files) can define a Dynamic Scope.&lt;br /&gt;
&lt;br /&gt;
   DYNAMICSCOPE:x&lt;br /&gt;
&lt;br /&gt;
*x is the new scope&lt;br /&gt;
**Any argument to DYNAMICSCOPE becomes a legal &amp;quot;scope&amp;quot; in LOCAL: in the variable definition file&lt;br /&gt;
**Limit of one new scope per line.  (No delimiter on this token)&lt;br /&gt;
*Like other LST tokens, this is case insensitive, but usage in later tokens is always capitalized, so I suspect the data standard should be ALL CAPS&lt;br /&gt;
&lt;br /&gt;
===DYNAMIC (PCC File)=== &lt;br /&gt;
&lt;br /&gt;
In order to create objects within the defined DYNAMICSCOPE, DYNAMIC: becomes a new token legal in PCC files. It's format is:&lt;br /&gt;
&lt;br /&gt;
   DYNAMIC:x&lt;br /&gt;
&lt;br /&gt;
* x is the file just as in tokens like DEITY or DOMAIN&lt;br /&gt;
* INCLUDE/EXCLUDE on the line are are legal.&lt;br /&gt;
&lt;br /&gt;
Within the Dynamic file, the Scope of the new objects being created MUST appear as a prefix token on the line.  For example, if there was a DYNAMICSCOPE:VISION, then the following would be legal in a DYNAMIC file:&lt;br /&gt;
   VISION:Darkvision&lt;br /&gt;
   VISION:Low-Light Vision&lt;br /&gt;
&lt;br /&gt;
* The &amp;quot;Token Name&amp;quot; (what appears before the ':') is the DYNAMICSCOPE name.&lt;br /&gt;
* These are created as basically hollow, simple objects.  &lt;br /&gt;
* These objects CAN contain variables.&lt;br /&gt;
(It is the intent to allow these at some point to also have MODIFY* tokens, but that is not currently supported)&lt;br /&gt;
&lt;br /&gt;
===GRANT (LST files)===&lt;br /&gt;
&lt;br /&gt;
A Dynamic object MUST be granted in order to have its local variables modified or to have its modifiers have an impact (just like any other object) &lt;br /&gt;
&lt;br /&gt;
    GRANT:x|y&lt;br /&gt;
&lt;br /&gt;
* x is a DYNAMICSCOPE&lt;br /&gt;
* y is the name of the dynamic object.&lt;br /&gt;
&lt;br /&gt;
===Export===&lt;br /&gt;
&lt;br /&gt;
Dynamic items can be exported in Freemarker using the &lt;br /&gt;
&lt;br /&gt;
   &amp;lt;#list pc.dynamic.x as y&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* x is the name of the DYNAMICSCOPE&lt;br /&gt;
* y is the local variable within the #list that the output team wants to use to access the dynamic object&lt;br /&gt;
* It is likely for ease of use by the output team, x and y will be identical&lt;br /&gt;
&lt;br /&gt;
For a complete example using output, see below&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
DATACONTROL: file:&lt;br /&gt;
   DYNAMICSCOPE:VISION&lt;br /&gt;
&lt;br /&gt;
DYNAMIC: file:&lt;br /&gt;
   VISION:Normal&lt;br /&gt;
   VISION:Darkvision&lt;br /&gt;
   VISION:Low-Light Vision&lt;br /&gt;
&lt;br /&gt;
VARIABLE: File:&lt;br /&gt;
   LOCAL:VISION|NUMBER=Range&lt;br /&gt;
&lt;br /&gt;
GLOBALMODIFIERFILE:&lt;br /&gt;
    MODIFYOTHER:VISION|ALL|Range|Set|60&lt;br /&gt;
&lt;br /&gt;
Sets a &amp;quot;default&amp;quot; range for any VISION, to avoid setting on each VISION object&lt;br /&gt;
&lt;br /&gt;
RACE LST file:&lt;br /&gt;
   Human &amp;lt;&amp;gt; GRANT:VISION|Normal&lt;br /&gt;
&lt;br /&gt;
Export:&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;#list pc.dynamic.vision as vision&amp;gt;&lt;br /&gt;
    ${vision.name} ${vision.val.range}&lt;br /&gt;
   &amp;lt;/#list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this ignores converting the range to local units and all that, but you get the idea)&lt;br /&gt;
&lt;br /&gt;
==ARRAY Format==&lt;br /&gt;
&lt;br /&gt;
In addition to the base formats, there is an ARRAY[x] format:&lt;br /&gt;
   ARRAY[x]&lt;br /&gt;
* x is an existing valid Format&lt;br /&gt;
** x CANNOT be ARRAY (multi-dimensional arrays not supported&lt;br /&gt;
** Just to be precise, yes DYNAMIC formats are legal&lt;br /&gt;
&lt;br /&gt;
(Note: This may get renamed - we need to decide on a few things for how this will work vs other types of collections)&lt;br /&gt;
&lt;br /&gt;
===Modifiers===&lt;br /&gt;
&lt;br /&gt;
There are two valid MODIFIERs for ARRAY:&lt;br /&gt;
* ADD: This adds a value to the ARRAY&lt;br /&gt;
** Mathematically, ARRAY acts as an ordered set of objects.  Therefore, if you add an item to an array more than once it is ignored.&lt;br /&gt;
* SET: This sets the contents of the ARRAY&lt;br /&gt;
&lt;br /&gt;
==Custom Functions==&lt;br /&gt;
&lt;br /&gt;
Within certain game systems, there are calculations that are likely to be repeated.  In order to simplify the calculation of these items, there is an ability to create custom functions.&lt;br /&gt;
&lt;br /&gt;
A function can have zero or more arguments.  The number is defined by what appears in the VALUE token (see below).&lt;br /&gt;
&lt;br /&gt;
Note that the function actually has to be *used in the data* (not just defined) for most errors to be caught (since the system can't guess at overall context before a function is used and it would be possible to write a function that would work in more than one FORMAT).&lt;br /&gt;
&lt;br /&gt;
===Function (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
   FUNCTION:x&lt;br /&gt;
* This token must appear as the first token on a line in a DATACONTROL file.&lt;br /&gt;
* x is the name of the function.  This name must starts with a letter, e.g. A-Z, additional legal characters are 0-9 and _ (none of those additional legal characters as the first character)&lt;br /&gt;
** x must not contain spaces, no other special characters.&lt;br /&gt;
** Function names are case insensitive (as many other things in LST files) &lt;br /&gt;
&lt;br /&gt;
A Function MUST also contain a VALUE, which defines how the function is calculated.&lt;br /&gt;
&lt;br /&gt;
If a FUNCTION appears more than once, the other characteristics (VALUE) must be identical. &lt;br /&gt;
&lt;br /&gt;
===Value (DATACONTROL LST)===&lt;br /&gt;
&lt;br /&gt;
   VALUE:x&lt;br /&gt;
* Must appear as an additional token on the line of a FUNCTION: in the data control file&lt;br /&gt;
* x is a valid formula.  &lt;br /&gt;
** This means it must have valid variable names, valid function names, matching parenthesis, etc. &lt;br /&gt;
&lt;br /&gt;
In addition to all of the build-in functions (e.g. if, ceil, round), two additional items can be used:&lt;br /&gt;
* the arg(n) function (see below).&lt;br /&gt;
* Any previously defined FUNCTION. This MUST appear in the file before the current Function or in a file processed before the current file.&lt;br /&gt;
&lt;br /&gt;
===arg (Function)===&lt;br /&gt;
&lt;br /&gt;
The arg function is a &amp;quot;local&amp;quot; function to the VALUE: part of a FUNCTION (it can not generally be used in LST files). The arg function takes one argument. It MUST be a Integer &amp;gt;= 0.&lt;br /&gt;
&lt;br /&gt;
   arg(x)&lt;br /&gt;
* x is an integer number (zero-indexed)&lt;br /&gt;
&lt;br /&gt;
When arg(x) is used in value, the function pulls from the arguments that were provided to the original function in the data.  &lt;br /&gt;
&lt;br /&gt;
===Using a Function===&lt;br /&gt;
&lt;br /&gt;
When a function is used in LST data, it is called by the name provided in the FUNCTION token. It requires a certain number of arguments. This exactly matches the integer one greater than the highest number of the arg(n) function provided in the VALUE part of a FUNCTION (In computer science terms, the arg(n) function is zero-indexed). The provided arguments can be any legal formula, so:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(INT)&lt;br /&gt;
   d20Mod(INT+4)&lt;br /&gt;
&lt;br /&gt;
...are both perfectly legal.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
The modification calculation in most d20 games is fairly easy to calculate, but is repeated very often.  It basically takes (ability score - 10)/2.&lt;br /&gt;
&lt;br /&gt;
Here is how we would define a new function d20Mod in the DATACONTROL file:&lt;br /&gt;
   FUNCTION:d20Mod    VALUE:floor((arg(0)-10)/2)&lt;br /&gt;
&lt;br /&gt;
This would then be used in LST data as:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(n)&lt;br /&gt;
&lt;br /&gt;
The system will catch both of these as errors:&lt;br /&gt;
&lt;br /&gt;
   d20Mod()&lt;br /&gt;
   d20Mod(14,5) &lt;br /&gt;
&lt;br /&gt;
These have too few or too many arguments, respectively. It would also catch:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(&amp;quot;mystring&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
...as an error (wrong format - requires a Number, found a String). &lt;br /&gt;
&lt;br /&gt;
The n is substituted where &amp;quot;arg(0)&amp;quot; appears in the &amp;quot;VALUE&amp;quot;... so a statmod would be as easy as:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(INT)&lt;br /&gt;
&lt;br /&gt;
or some such... Direct values can also be used, e.g.:&lt;br /&gt;
&lt;br /&gt;
   d20Mod(10)&lt;br /&gt;
&lt;br /&gt;
...would return 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Performance Considerations==&lt;br /&gt;
&lt;br /&gt;
It is possible to write two identical modifiers that perform the same net calculation on a PC.  For example:&lt;br /&gt;
   MODIFY:Age|ADD|2&lt;br /&gt;
   MODIFY:Age|SET|value()+2&lt;br /&gt;
&lt;br /&gt;
...perform the same calculation (adding 2 to Age).&lt;br /&gt;
&lt;br /&gt;
Why have ADD at all?  Answer: These are NOT AT ALL equivalent in memory use or speed/performance.&lt;br /&gt;
&lt;br /&gt;
The ADD (Since it's adding an integer) occupies approximately 40 bytes of memory and is an extremely rapid calculation: If it took 200 nanoseconds I'd be surprised. This is because ADD is using a number. If it was a formula, even 1+2, it would load the formula parser. This special case on constants allows the modification system to modify a value without loading a much larger infrastructure, and this is valuable as a large majority of our calculations are simple modifications of values.&lt;br /&gt;
&lt;br /&gt;
The SET shown above (since it has an operator) loads the formula system, and thus may occupy 500 (or more) bytes of memory (&amp;gt;10x), so it could take 100 times as long to process as the ADD (it also took longer during LST load).&lt;br /&gt;
&lt;br /&gt;
Thus: When possible the data standards should be written to use numeric modifiers and no operator.  (Think &amp;quot;static&amp;quot; modifiers ... that only use numbers) rather than a formula.&lt;br /&gt;
&lt;br /&gt;
==Lookup and Tables==&lt;br /&gt;
&lt;br /&gt;
For some situations, it makes more sense to have a lookup table rather than attempting to have a set of tokens or calculations perform processing.  This also allows for much cleaner translation from books when the books are using tables to organize information.&lt;br /&gt;
&lt;br /&gt;
The Table file format is designed to allow you to use a spreadsheet program to modify the tables and export the table in CSV format.  While we don't strictly follow full CSV rules, as long as you avoid embedded quotes and embedded return carriage/line feed, it should be safe.&lt;br /&gt;
&lt;br /&gt;
More than one table is allowed per file (to avoid sprawl and help simplify modification/management of tables).&lt;br /&gt;
&lt;br /&gt;
===TABLE (PCC File)===&lt;br /&gt;
&lt;br /&gt;
   TABLE:x&lt;br /&gt;
* x is the file to be loaded as a TABLE file&lt;br /&gt;
* Limitations: It does not support PRExxx or INCLUDE/EXCLUDE.&lt;br /&gt;
&lt;br /&gt;
====Table LST file format====&lt;br /&gt;
&lt;br /&gt;
File formatting considerations:&lt;br /&gt;
* Trailing commas will not impact any TABLE, and will be ignored&lt;br /&gt;
* Blank lines will be ignored.  This includes lines with commas but without content. (allows tables to be separated by blank lines or lines of all commas)&lt;br /&gt;
* Attempts to use embedded line breaks or embedded quotes may or may not be supported by the parsing system, but certainly aren't supported for purposes of PCGen.&lt;br /&gt;
* Lines that have the first cell starting with &amp;quot;#&amp;quot; are considered comment lines and will be ignored.  This will likely need to include if the first cell is escaped in quotes, just for protection from any tools that quote by default.&lt;br /&gt;
* Since the CSV format ignores leading/trailing spaces, one can easily have a spaced out version that is a table in a text editor if folks don't want to edit in a spreadsheet.  (Having someone write a &amp;quot;PrettyTable&amp;quot; ... a trivial perl or python program to do that for the data team seems fairly easy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A TABLE starts with STARTTABLE:&lt;br /&gt;
   STARTTABLE:x&lt;br /&gt;
* x is the name of the Table.  Most characters are allowed, avoiding quotes is advisable.&lt;br /&gt;
* Allowing Trailing commas allows the STARTTABLE lines to have blank cells where the rest are the table contents... we don't want to complain on minor things that may tools will do.&lt;br /&gt;
&lt;br /&gt;
If a STARTTABLE is encountered when another Table is active, an LST load error will occur.&lt;br /&gt;
&lt;br /&gt;
A TABLE ends with ENDTABLE:&lt;br /&gt;
   ENDTABLE:x&lt;br /&gt;
* x is the name of the Table.  Most characters are allowed, avoiding quotes is advisable.&lt;br /&gt;
* Allowing Trailing commas allows the ENDTABLE lines to have blank cells where the rest are the table contents... we don't want to complain on minor things that may tools will do.&lt;br /&gt;
&lt;br /&gt;
If an ENDTABLE is encountered without a STARTTABLE, an LST load error will occur.&lt;br /&gt;
&lt;br /&gt;
A Table must have a minimum of 3 rows, NOT counting the STARTTABLE and ENDTABLE tokens.&lt;br /&gt;
&lt;br /&gt;
The First row:&lt;br /&gt;
   x,x&lt;br /&gt;
* x is the column name.  These are always the first line of the table after STARTTABLE:&lt;br /&gt;
&lt;br /&gt;
Any column which has data MUST have a name.&lt;br /&gt;
&lt;br /&gt;
The Second row:&lt;br /&gt;
   y,y&lt;br /&gt;
* y is the format for the column.  Any column that was named must have a FORMAT.&lt;br /&gt;
&lt;br /&gt;
Additional rows:&lt;br /&gt;
   z,z&lt;br /&gt;
* z represents contents of the table.  These must be in the FORMAT provided for the appropriate column.&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
&lt;br /&gt;
   STARTTABLE:Carrying Capacity,&lt;br /&gt;
   Strength,Capacity&lt;br /&gt;
   NUMBER,NUMBER&lt;br /&gt;
   1,10&lt;br /&gt;
   2,20&lt;br /&gt;
   ...&lt;br /&gt;
   29,1400&lt;br /&gt;
   ENDTABLE:Carrying Capacity,&lt;br /&gt;
&lt;br /&gt;
===TABLE[x] Format===&lt;br /&gt;
&lt;br /&gt;
When a TABLE is created, it implicitly picks up a FORMAT based on the FORMAT of the first column of the Table.  &lt;br /&gt;
Unlike basic FORMATs shown above, TABLE has a SUBFORMAT (in brackets).&lt;br /&gt;
&lt;br /&gt;
   TABLE[x]&lt;br /&gt;
* x is the SUB-FORMAT of the TABLE (this is the format of the first column of the Table)&lt;br /&gt;
** x must be an otherwise valid FORMAT, and it is advised to avoid any FORMAT that has a SUB-FORMAT&lt;br /&gt;
*** This limitation may be inconsistently enforced.  It certainly is prohibited to create a TABLE[TABLE[x]], but other situations the behavior may not be prohibited by the code (but the behavior is also not guaranteed)&lt;br /&gt;
&lt;br /&gt;
===COLUMN[x] Format===&lt;br /&gt;
&lt;br /&gt;
When a Column needs to be referred to in the data, it has a special format as well:&lt;br /&gt;
&lt;br /&gt;
Unlike basic FORMATs shown above, COLUMN has a SUBFORMAT (in brackets).&lt;br /&gt;
   COLUMN[x]&lt;br /&gt;
* x is the SUB-FORMAT of the COLUMN (this is the format of the data that appears in that column in a Table)&lt;br /&gt;
** x must be an otherwise valid FORMAT, and it is advised to avoid any FORMAT that has a SUB-FORMAT&lt;br /&gt;
*** This limitation may be inconsistently enforced.  Such behavior may not be prohibited by the code (but avoiding bad behavior is also not guaranteed in a situation where embedded brackets occur)&lt;br /&gt;
&lt;br /&gt;
===Using Tables===&lt;br /&gt;
&lt;br /&gt;
With MODIFY, a TABLE[x] variable doesn't look any different.  It's still:&lt;br /&gt;
   MODIFY:TableNameVar|SET|&amp;quot;SomeTable&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SomeTable&amp;quot; is still a string to a naive reader, but what the system will do at that point is make sure that SomeTable can actually be interpreted as a TABLE[x]... rather than just treating it as a String.  Similar for column names when they are encountered (see below).&lt;br /&gt;
&lt;br /&gt;
In that way, the sub variable will allow multiple tables to be swapped in, AS LONG AS they are the right format.  If the format is not compatible, then all bets are off and you'll get an error.&lt;br /&gt;
&lt;br /&gt;
===lookup() Function===&lt;br /&gt;
&lt;br /&gt;
The major consideration is how to do the lookup in data.  We can borrow some inspiration from things like Excel and Google Docs:&lt;br /&gt;
&lt;br /&gt;
   lookup(X,Y,Z)&lt;br /&gt;
&lt;br /&gt;
* X is a table.  This must resolve in the formula system to a valid table.  For now, a get(...) function may be required.&lt;br /&gt;
* Y is the lookup value in the table.  It must match the format of the first column in the table.  At this time, it does an EXACT match.&lt;br /&gt;
* Z is the target column.  This must resolve in the formula system to a valid table column. It must appear in the table named by the contents of the first argument of lookup.&lt;br /&gt;
&lt;br /&gt;
Example: Max load calculation would be something like:&lt;br /&gt;
   lookup(&amp;quot;Carrying Capacity&amp;quot;,floor(StrScore),&amp;quot;Capacity&amp;quot;)*SizeMult&lt;br /&gt;
We have to do the floor due to the exact name of the lookup&lt;br /&gt;
&lt;br /&gt;
Note: The format of both TABLE &amp;quot;Carrying Capacity&amp;quot; and COLUMN &amp;quot;Capacity&amp;quot; can be derived by PCGen internally and thus are no longer required to have a get (current as of Jan 30, 2018)&lt;br /&gt;
&lt;br /&gt;
Note that this function allows some runtime errors, but catches a lot of possible issues.  It is still possible to do a lookup on a Table that doesn't contain a specific column of the given name or format, simply because those items can be variables resolved at runtime.  For example, if the third variable is COLUMN[NUMBER], we can check at load that the TABLEFORMAT has columns of FORMAT=NUMBER, but we can't guarantee the variable will resolve to a name actually in that table... that will have to wait for a runtime error.  That's life, but it does allow us to know the formats at load time, so we do get a lot of error checking in the context of the usage, if not the exact table and column names.&lt;br /&gt;
&lt;br /&gt;
Note you can do some really dynamic behaviors to have folks override game mode behaviors.  For example, one neat item would be that we could alter a query for dice steps to extract the table name into the Global Modifier file:&lt;br /&gt;
   MODIFY:DiceStepTable|SET|&amp;quot;Dice Step&amp;quot;&lt;br /&gt;
   lookup(get(&amp;quot;TABLE[NUMBER]&amp;quot;,DiceStepTable),BaseDamage,get(&amp;quot;COLUMN[NUMBER]&amp;quot;,lookup(&amp;quot;Step Column&amp;quot;,CurrentSize-BaseSize,&amp;quot;Name&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
Note: In both cases here, the &amp;quot;get&amp;quot; is shown for completeness.  In the case of DiceStepTable - it MAY be required or prohibited - it depends on what the Format is of the &amp;quot;DiceStepTable&amp;quot; variable.  If it's TABLE, then the get is not necessary (and is actually prohibited).  The example shown above assumes DiceStepTable is a String.  The better design would be for it to be a TABLE (specifically TABLE[NUMBER]).  For the &amp;quot;get&amp;quot; after the lookup, that is required - the lookup value will return a STRING, and as such, will needs to be converted to a COLUMN.&lt;br /&gt;
&lt;br /&gt;
Now, if someone needs different dice steps for some reason... they can override the DiceStepTable variable and it will look up in a different table... so expansions could truly be expansions and not have to reach back into core PCC files in order to change key behaviors.&lt;br /&gt;
&lt;br /&gt;
Consider also that spell tables can be shared across classes, or if a subclass alters the default, just create a new table rather than having to BONUS/MODIFY all the numbers in a table with adding and subtracting...&lt;br /&gt;
&lt;br /&gt;
==To be completed==&lt;br /&gt;
* dropIntoContext&lt;br /&gt;
* Channels&lt;br /&gt;
&lt;br /&gt;
=Material Changes=&lt;br /&gt;
&lt;br /&gt;
==lookup function simplification==&lt;br /&gt;
&lt;br /&gt;
Effective January 30, 2018, tables and columns can be referred to directly in lookup().  This is actually a &amp;quot;broad&amp;quot; change to how strings are interpreted.  The system - when possible - fully asserts a FORMAT, and first attempts to convert the given String per the rules of that FORMAT.  This also means an assignment of an ALIGNMENT, by key, will not require a &amp;quot;get&amp;quot;:&lt;br /&gt;
   MODIFY:Alignment|SET|&amp;quot;LE&amp;quot;&lt;br /&gt;
...will be fully legal.  (This assumes Alignment is FORMAT: of ALIGNMENT)&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=INFO_and_INFOVARS&amp;diff=4044</id>
		<title>INFO and INFOVARS</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=INFO_and_INFOVARS&amp;diff=4044"/>
		<updated>2017-01-05T13:01:06Z</updated>

		<summary type="html">&lt;p&gt;Nuance: Wrapped the overly long line (it was off the page on my 4k monitor).&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The proposal involves two LST tokens:&lt;br /&gt;
&lt;br /&gt;
INFO:x|y&lt;br /&gt;
*  x is an &amp;quot;info name&amp;quot;. This is data defined&lt;br /&gt;
*  y is the message format. It matches the format required by java.text.MessageFormat, which can be found, among many other places, here: http://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html#getFormatsByArgumentIndex%28%29&lt;br /&gt;
*  This token overwrites (if the &amp;quot;info name&amp;quot; matches)&lt;br /&gt;
&lt;br /&gt;
INFOVARS:x|y=z|y=z&lt;br /&gt;
*  x is an &amp;quot;info name&amp;quot;. This is data defined&lt;br /&gt;
*  y is a scope from the new Formula System (e.g. AREA). The y= is optional if y is &amp;quot;VAR&amp;quot; (the default numeric variable scope)&lt;br /&gt;
*  z is a variable from the new Formula System (e.g. Face)&lt;br /&gt;
*  This token overwrites (if the &amp;quot;info name&amp;quot; matches)&lt;br /&gt;
&lt;br /&gt;
Some notes:&lt;br /&gt;
&lt;br /&gt;
    The &amp;quot;info name&amp;quot; is dynamic. It is NOT under the control of something like the data control file (it is NOT like FACT names or Variables). It is more similar to today's Aspect names.&lt;br /&gt;
    There are rules for the &amp;quot;info name&amp;quot; regarding use in INFO and INFOVARS. Specifically:&lt;br /&gt;
            If an info name is used in INFOVARS but never in INFO on that object, it is an LST load error&lt;br /&gt;
            If an info name is used in INFO and the Message Format requires variables and no INFOVARS is provided, it is an LST load error&lt;br /&gt;
            If an info name is used in INFO and the Message Format requires N variables and the number provided to INFOVARS does not match N, then it is an LST load error.&lt;br /&gt;
&lt;br /&gt;
            Note: The &amp;quot;info name&amp;quot; is only so flexible, but the code will not restrict it at this time. I would advise the data standard be all letters&lt;br /&gt;
                  and numbers (no spaces, no special characters), and if we can get to a standard the data team wants strongly enforced, that can be done.&lt;br /&gt;
&lt;br /&gt;
Output in the new Freemarker system is implied. Any INFO token will be available under *.info . For example:&lt;br /&gt;
*  Race LST file&lt;br /&gt;
*  Monkey &amp;lt;&amp;gt; INFO:Wildness|Monkeys are usually found in the wild&lt;br /&gt;
*  can be accessed under the following:&lt;br /&gt;
*  pc.race.info.wildness&lt;br /&gt;
&lt;br /&gt;
*  https://groups.yahoo.com/neo/groups/pcgen_experimental/conversations/messages/19346&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=User:Nuance&amp;diff=4000</id>
		<title>User:Nuance</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=User:Nuance&amp;diff=4000"/>
		<updated>2016-03-06T18:53:30Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a page about [[User:Nuance|andrew]] also [[Andrew Wilson]].  There are many like it, but this one is mine.&lt;br /&gt;
&lt;br /&gt;
I'm the data Gibbon; code Tamarin version of andrew.  Not to be confused with Messrs [[User:LegacyKing|Maitlaind]] or [[User:Tir_Gwaith|McDougal]].&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3999</id>
		<title>Andrew Wilson</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3999"/>
		<updated>2016-03-06T18:52:13Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
I'm a software developer based in the UK; my GitHub id is ampersandrew.&lt;br /&gt;
&lt;br /&gt;
In March 2016, I moved to a java coding role. My previous day job was safety critical software, mostly in Ada. Before that, I worked on a website in Linux, Apache, MySQL &amp;amp; Perl.&lt;br /&gt;
&lt;br /&gt;
I joined the PCGen code team on the 19th April 2001, which seems like a very long time ago now. These days I mostly do data work for the project.&lt;br /&gt;
&lt;br /&gt;
I became a data Tamarin in December 2011, and a data Gibbon in November 2012.&lt;br /&gt;
&lt;br /&gt;
=Teams I belong to=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Team !! Rank&lt;br /&gt;
|-&lt;br /&gt;
| [[Data|Content - Data]] || [[Explanation_of_Teams#Gibbon|Gibbon]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Code]] || [[Explanation_of_Teams#Tamarin|Tamarin]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Contact Details=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
| Timezone || GMT&lt;br /&gt;
|-&lt;br /&gt;
| e-mail || ampersandrewATliveDOTcom&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3998</id>
		<title>Andrew Wilson</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3998"/>
		<updated>2016-03-06T18:42:46Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Contact Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
I'm based in the UK, my sourceforge id is nuance.  Day job is safety critical software, mostly ada these days. I Joined the PCGen team on the 19th April 2001, which seems like a very long time ago now.&lt;br /&gt;
&lt;br /&gt;
=Teams I belong to=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Team !! Rank&lt;br /&gt;
|-&lt;br /&gt;
| [[Data|Content - Data]] || [[Explanation_of_Teams#Gibbon|Gibbon]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Code]] || [[Explanation_of_Teams#Tamarin|Tamarin]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Contact Details=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
| Timezone || GMT&lt;br /&gt;
|-&lt;br /&gt;
| e-mail || ampersandrewATliveDOTcom&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3997</id>
		<title>Andrew Wilson</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3997"/>
		<updated>2016-03-06T18:42:00Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Teams I belong to */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
I'm based in the UK, my sourceforge id is nuance.  Day job is safety critical software, mostly ada these days. I Joined the PCGen team on the 19th April 2001, which seems like a very long time ago now.&lt;br /&gt;
&lt;br /&gt;
=Teams I belong to=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Team !! Rank&lt;br /&gt;
|-&lt;br /&gt;
| [[Data|Content - Data]] || [[Explanation_of_Teams#Gibbon|Gibbon]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Code]] || [[Explanation_of_Teams#Tamarin|Tamarin]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Contact Details=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
| Timezone || GMT&lt;br /&gt;
|-&lt;br /&gt;
| e-mail || andrewATrivendaleDOTnet&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Data&amp;diff=3996</id>
		<title>Data</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Data&amp;diff=3996"/>
		<updated>2016-03-06T18:41:09Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Gibbon */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
Welcome to the Wiki section of the Data team! The data team is a sub team under the umbrella of the [[Content]] team.&lt;br /&gt;
&lt;br /&gt;
=Mission Statement=&lt;br /&gt;
To create data (books) for PCGen that encompasses all aspects of character creation, is true to the publisher's intent and results in output that is correct and complete for the end-user.&lt;br /&gt;
&lt;br /&gt;
=Data Meetings=&lt;br /&gt;
* [[Data Meeting Availability]]&lt;br /&gt;
* [[Data Meeting Logs]]&lt;br /&gt;
&lt;br /&gt;
=Books Requested by Users=&lt;br /&gt;
* [[Content Requests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Conversion Logs for 6.0=&lt;br /&gt;
* [[GameMode35e]]&lt;br /&gt;
* [[GameMode_3e]]&lt;br /&gt;
* [[GameMode_Pathfinder]]&lt;br /&gt;
* [[GameMode_deadlands]]&lt;br /&gt;
&lt;br /&gt;
=Active Proposals=&lt;br /&gt;
* [[Redesigning COMPANIONLIST and Companion Leveladjustment]]&lt;br /&gt;
* [[COMPANIONTYPE| COMPANIONTYPE a new token to make grouping companions together]]&lt;br /&gt;
* [[Dragons redesigned]]&lt;br /&gt;
* [[NATURALATTACK the new system]]&lt;br /&gt;
&lt;br /&gt;
* [[Formula Parser Conversion - Data]]&lt;br /&gt;
* [[Magic Item Cost issue]]&lt;br /&gt;
&lt;br /&gt;
=Resources=&lt;br /&gt;
* [[Joining the Data Team]]&lt;br /&gt;
&lt;br /&gt;
* [[Video Lessons]]&lt;br /&gt;
&lt;br /&gt;
* [[Data Team Tools]]&lt;br /&gt;
* [[Dataset Creation/Maintenance]]&lt;br /&gt;
* [[Dataset Testing]]&lt;br /&gt;
* [[PCGen Data Team Processes (JIRA)]]&lt;br /&gt;
* [[PCGen Data Team FAQ]]&lt;br /&gt;
* [[PCGen Data Team Useful Links]]&lt;br /&gt;
&lt;br /&gt;
* [[Lst File How To]]&lt;br /&gt;
&lt;br /&gt;
* [[Data Team Resource Page]]&lt;br /&gt;
&lt;br /&gt;
* [[Quality Assurance Team]]&lt;br /&gt;
&lt;br /&gt;
* [[Challenging Data Issues and Proposed Solutions]]&lt;br /&gt;
&lt;br /&gt;
=Active Team Members=&lt;br /&gt;
Members of this team (and areas of specialty/responsibility) are:&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Silverback|Silverback]]===&lt;br /&gt;
* [[LegacyKing|Andrew Maitland]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Second|2nd]]===&lt;br /&gt;
* [[Distant_Scholar|Doug Limmer]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Chimp|Chimp]]===&lt;br /&gt;
* [[Chris Chandler|Barak]]  - Tag design, consulting (CMP datasets)&lt;br /&gt;
* [[User:Nylanfs|Paul Grosse]]&lt;br /&gt;
* [[LegacyKing|Andrew Maitland]]&lt;br /&gt;
* [[Stefan Radermacher]]&lt;br /&gt;
* [[Eric C Smith|Maredudd]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Gibbon|Gibbon]]===&lt;br /&gt;
* [[David R. Bender]]&lt;br /&gt;
* [[Distant_Scholar|Doug Limmer]]&lt;br /&gt;
* [[Andrew Wilson]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Tamarin|Tamarin]]===&lt;br /&gt;
* [[Paul Shipley (elro the onk)]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Lemur|Lemur]]===&lt;br /&gt;
* Henk Slaaf - Q&amp;amp;A, Patches&lt;br /&gt;
* Anestis Kozakis&lt;br /&gt;
* Swiftbrook - Pathfinder&lt;br /&gt;
&lt;br /&gt;
===Special Titles===&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Inactive Team Members=&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Silverback|Silverback]]===&lt;br /&gt;
* [[Eddy Anthony]]&lt;br /&gt;
* [[Frank Kliewe]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Chimp|Chimp]]===&lt;br /&gt;
* [[Tir Gwaith]] - 3e, 3.5e, Races, Classes, Prettylst&lt;br /&gt;
* Michael Gray (taluroniscandar) - 3e and 3.5e Psionics&lt;br /&gt;
* Aaron Divinsky, Default Monster Kits, [[Internationalization]]&lt;br /&gt;
* [[Eddy Anthony]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Gibbon|Gibbon]]===&lt;br /&gt;
* [[Paul W. King|Paul King]]&lt;br /&gt;
* Phantom of Krankor - Need real name&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Tamarin|Tamarin]]===&lt;br /&gt;
* Ratheof Blithwyn&lt;br /&gt;
* [[Shelley Stephen]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Lemur|Lemur]]===&lt;br /&gt;
* [[Andargor]]&lt;br /&gt;
* David Saulnier&lt;br /&gt;
* Dennis Baker &lt;br /&gt;
* Eric Jarman&lt;br /&gt;
* [[Jason Horner]]&lt;br /&gt;
* Phillip Ryan - PrettyLst&lt;br /&gt;
* Fluxxdog&lt;br /&gt;
* [[Martijn Verburg]]&lt;br /&gt;
* Ainvar Garrettson&lt;br /&gt;
* John Bauldree&lt;br /&gt;
* Monty, aka Fabio Montanari - 3.5e&lt;br /&gt;
* Jonathan A. Arnold - Homebrew Help&lt;br /&gt;
* Peter Yovich&lt;br /&gt;
* [[Terry FitzSimons]]&lt;br /&gt;
* Arjan van Ginneken&lt;br /&gt;
* Thomas Cooper &lt;br /&gt;
* [[Tod Milam]]&lt;br /&gt;
* Harvey Howell&lt;br /&gt;
* Terry Milnes&lt;br /&gt;
* [[Allen Cohn]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Special Titles===&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
| [[Andargor]] || Amoeba&lt;br /&gt;
|-&lt;br /&gt;
| [[Shelley Stephen]] || 1st flunky in charge of finding weird bugs&lt;br /&gt;
|-&lt;br /&gt;
| [[Tir Gwaith]] || [[Strange Monkey]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Meeting_2013_01_04&amp;diff=3315</id>
		<title>Meeting 2013 01 04</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Meeting_2013_01_04&amp;diff=3315"/>
		<updated>2013-01-05T00:06:38Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Log */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
[[http://wiki.pcgen.org/Meeting_Logs PCGen BoD Meeting Minutes Home]]&lt;br /&gt;
&lt;br /&gt;
=Attendance=&lt;br /&gt;
* Chair - David (Adv 2nd)&lt;br /&gt;
* Admin - Anestis (Website 2nd)&lt;br /&gt;
* Architecture - Tom (Arch SB)&lt;br /&gt;
* Code - James (Code SB)&lt;br /&gt;
* Content - Eric (Docs 2nd)&lt;br /&gt;
* Pub. Relations - David (Adv 2nd)&lt;br /&gt;
&lt;br /&gt;
=Summary=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Log=&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; According to Kar, the agenda is: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Agenda:  * 6.0.1 release * 6.0.x data upgrade path progress * 6.1.0 progress/blockers * Finances &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Tom, James. Will one of you comment on 6.0.1 (or is it 6.1.0). &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; 6.0.1 would be James to comment on that &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; ok &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Right so lets gets some confusion sorted out first :) &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; LOL &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; 6.0.1 is a patch for production &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; 6.1.1 is the first alpha for the next dev cycle &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Gotcha. &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; So the current plan is to hold off on 6.0.1 until we have socialised the bug data changes in the alpha release &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; From the code side we have 15 fixes in for 6.0.1 with abotu 6 more to come that Tom wants to put across &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; I'm trying to get to those this evening &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Cool &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; I'll push the source selection improvements into 6.0.1 as well, but would appreciate feedback if anyone wants to kick the tyres &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Andrew's plan for data is to bulk copy all of the data changes in trunk back t the 6.0 branch once they have beenput put out in the 6.1.1 alpha release &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; That'll be a big change but includes a lot of small fixes and some tidy up/standardisation &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; So overall I wouldn't expect 6.0.1 RC1 to come out until late Jan. &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Ok. Are the source selection improvements in the nightly autobuilds yet? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; yep they are there &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; However now is a good time to sing out if anyone has anything they weant included in the production patch &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; That's probably it for the 6.0.1 prod fix progress - any questions or comments? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; not here &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; not here, either. &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; afk for 3 min &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Can anyone else add any further detail on the &amp;quot;6.0.x data upgrade path progress&amp;quot; item? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Sorry, no. That really is Andrew's baby with some help from others. &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; He did ask me to hold off on the 6.1.1 alpha to allow a few more issues to be addressed - that's the last I have heard &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; back &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; So we might move on to the 6.1.1 alpha progress then &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Ok, go for it. &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; On the code side we have around 35 items included already &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; I am continuing the expuingin of the old UI code and have converted all choosers to the new chooser disalog apart from sub-class/specialty and aubstitution class selection &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; My plan for those is to go back to a single column with the name in available but provide a full info panel at the bottom of the dialog allowing rich info for the currently highlighed choice, much like any other avaiolable/selected pair in the system &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; I've also addressed the feedback on source selection  that RobertD provided &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; So that will be in the alpha &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Tom, how about you? &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; Have worked a few different things. &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; Driving toward more facets, and have done most of the work to get rid of associations created in Playercharacter&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; By having those in facets, we can directly trigger behaviors from one location and know it will add/remove safely&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; there are 2 major things left, one of which is the CHOOSE system&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; that is tied into other work I'm doing&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; Which is on abilities and making it so we no longer clone abilities&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; Making all selections type safe (And some additional checking we get from that) is also tied into the same project&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; investigation has shown that I think I'll need to go off to a branch&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; We have like 4 methods of getting Abilities into a Character and each has quirks where I'm not sure I can write unit tests against them like I want.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; I want to ensure we can test both add/remove and persistence to PCG, and all of them have something that is .... challenging&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; (or in some cases downright bugs)&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; So I'll push as far as I can in trunk and then go off to a branch for a bit on that one&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; that way I can break things temporarily, knowing I also have unit tests that will show when they are fixed, and when it's all happy , can bring it all back to trunk&amp;lt;br /&amp;gt;&lt;br /&gt;
*** jujutsunerd has quit IRC: Read error: Connection reset by peer&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Sounds like a good plan&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Yup.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; Overall, good progress recently toward getting things into facets&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Did you want CI activated on the branch? We could make the emails not go to the dev list&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; Next up will probably be Spells, as that right now is very passive&amp;lt;br /&amp;gt;&lt;br /&gt;
*** Maredudd has joined #pcgen&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; CI would be awesome on the branch&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; k, I'll configure it once you make the branch&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Hi Eric&amp;lt;br /&amp;gt;&lt;br /&gt;
*** Maredudd is now known as [DOC]Maredudd&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; cool, thanks&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; Hi James&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; @Eric, we are just discussing the upcoming 6.1.1 alpha release - anything to add there?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; 6.1.1?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; Nothing for either 6.1.0 or 6.0.1 . . .&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Yeah renaming the first alpha to try and reduce confusion&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; Ah! Makes sense! :-)&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; I have nothing for the alpha. I am interested to see how the data changes work out so we can determine what gets ported to 6.0.1.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Likewise&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; What is the tie frame for 6.1.1?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; time frame . . .&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Code is ready (Tom - you happy wiht that) so just waiting on the word from Andrew&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; I am guessing next weekend (12/13)&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; Next weekend is good for me. I'll be nusy on the 12th, but the 14th I'll be available to do the Mac file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; 13th . . . :-)&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Excellent&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Ok. Anything else for 6.0.1 or 6.1.1 ?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; How long after 6.1.1 before we do 6.0.1?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; I reckon late Jan for 6.0.1 RC1&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; Cool.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; code ready whenever&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Excellent&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; I guess technically that's arch ready whenever ;)&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; :) A healthy mix&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Ok. Anestis, anything for web or your projects?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; Jami has done a great job with the Wordpress site.  Just a few tweaks I think, and our FB/Twitter integration.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; I want to have the ability to comment on the Donate page removed.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; Has everyone seen the site yet?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; I'm not sure I have&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; I haven't. Can you send me a link?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Same for me. Send a link please&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; http://pcgen.org/wordpress&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; If it is close we should set a schedule for release&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; It's fairly close, yeah&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; Probably equivalent to beta&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; Kar, Drew and Eric are actually setup as Editors so that they can post articles/updates&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Could you propose a schedule at the next BoD meeting please?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; I guess.  Depends if I can make the next meeting, as well as as if I can get Jami to do the required changes&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Well, it is not so much needing to get changes done, but to set a target&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; Even if that is a few months away&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; OK&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; Not so much as a web issue, and maybe not a discussion for now, but as I mentioned on the mailing list, maybe look at setting up a Google+ community.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; What is a google+ community? Is it like yahoo groups? or something else entirely&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; It's more like a Facebook group&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; but on google+&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; The link I posted on the BOD Mailing list has information on it&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Ok, what is a facebook group?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Oh, ok. I'll chedk that out&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; anyone else have anything?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Arch_SB]thpr&amp;gt; nope&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[Web_2nd]Anestis&amp;gt; That's really all from me&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Eric, James ?&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;James[Code_SB]&amp;gt; All good here&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;PapaDRB[Ad_2nd]&amp;gt; Ok, *bangs* gavel down. Meeting adjourned. I'll post it on the web site. Thank you all for coming.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;[DOC]Maredudd&amp;gt; I have nothing for now.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=User:Nuance&amp;diff=3207</id>
		<title>User:Nuance</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=User:Nuance&amp;diff=3207"/>
		<updated>2012-11-09T21:52:27Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a page about [[User:Nuance|andrew]] also [[Andrew Wilson]].  There are many like it, but this one is mine.&lt;br /&gt;
&lt;br /&gt;
I'm the code Tamarin version of andrew.  Not to be confused with Messrs [[User:LegacyKing|Maitlaind]] or [[User:Tir_Gwaith|McDougal]].&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3206</id>
		<title>Andrew Wilson</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=3206"/>
		<updated>2012-11-09T21:50:15Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Teams I belong to */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
I'm based in the UK, my sourceforge id is nuance.  Day job is safety critical software, mostly ada these days. I Joined the PCGen team on the 19th April 2001, which seems like a very long time ago now.&lt;br /&gt;
&lt;br /&gt;
=Teams I belong to=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Team !! Rank&lt;br /&gt;
|-&lt;br /&gt;
| [[Data|Content - Data]] || [[Explanation_of_Teams#Tamarin|Tamarin]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Code]] || [[Explanation_of_Teams#Tamarin|Tamarin]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Contact Details=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
| Timezone || GMT&lt;br /&gt;
|-&lt;br /&gt;
| e-mail || andrewATrivendaleDOTnet&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Code&amp;diff=3205</id>
		<title>Code</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Code&amp;diff=3205"/>
		<updated>2012-11-09T21:49:00Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Tamarin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Welcome to the Wiki section for the Code Monkey team!&lt;br /&gt;
&lt;br /&gt;
=Mission Statement=&lt;br /&gt;
'''TBA'''&lt;br /&gt;
&lt;br /&gt;
=Resources=&lt;br /&gt;
* [[Developers Meeting]]&lt;br /&gt;
* [[Dev Meeting Log 20120309]]&lt;br /&gt;
* [[Dev Meeting Log 20120429]]&lt;br /&gt;
* [[Dev Meeting Log 20121103]]&lt;br /&gt;
&lt;br /&gt;
==For New Starters==&lt;br /&gt;
* [[Joining the Code Team]] General steps to take to prepare yourself&lt;br /&gt;
* [[Code Monkey Introduction]]&lt;br /&gt;
&lt;br /&gt;
==Developer Environment==&lt;br /&gt;
* [[Basic Developer Setup]]&lt;br /&gt;
* [[Subversion Setup]]&lt;br /&gt;
* [[Merging]] with SVN&lt;br /&gt;
* [[Building PCGen]], also see [[ANT]] and [[MAVEN]]&lt;br /&gt;
* [[Continuous Integration]]&lt;br /&gt;
&lt;br /&gt;
==Coding==&lt;br /&gt;
* [[Coding Standards]]&lt;br /&gt;
* [[Deprecating a Token]]&lt;br /&gt;
* [[Explanation of the Code Base]]&lt;br /&gt;
* [[Graph Theory]]&lt;br /&gt;
* [[Logging in the Code Base]]&lt;br /&gt;
* [[Unit Testing]]&lt;br /&gt;
* [[Removing Libraries]]&lt;br /&gt;
* [[Unnecessary Code Detector]]&lt;br /&gt;
&lt;br /&gt;
=Completed Sub Projects=&lt;br /&gt;
* [[Ability Object TODO List]]&lt;br /&gt;
* [[LST_Editor_Verification]]&lt;br /&gt;
&lt;br /&gt;
=Open Sub Projects=&lt;br /&gt;
* [[Internationalization]]&lt;br /&gt;
* [[CDOM]]&lt;br /&gt;
* [[UI Overhaul]]&lt;br /&gt;
* [[LST_Editor]]&lt;br /&gt;
* [[Major Code Projects]]&lt;br /&gt;
* [[Template Engine]]&lt;br /&gt;
&lt;br /&gt;
=Active Team Members=&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Silverback|Silverback]]===&lt;br /&gt;
* [[James Dempsey]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Second|2nd]]===&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Chimp|Chimp]]===&lt;br /&gt;
* [[Tom Parker]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Gibbon|Gibbon]]===&lt;br /&gt;
* Jayme Cox&lt;br /&gt;
* [[Stefan Radermacher]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Tamarin|Tamarin]]===&lt;br /&gt;
* [[Andrew Wilson]]&lt;br /&gt;
* [[Martijn Verburg]]&lt;br /&gt;
* [[Connor Petty]]&lt;br /&gt;
&lt;br /&gt;
===[[Explanation of Teams#Lemur|Lemur]]===&lt;br /&gt;
* [[Eddy Anthony]]&lt;br /&gt;
* Per Christian Henden&lt;br /&gt;
* Thomas Cooper &lt;br /&gt;
* [[Tod Milam]] - Mac Developer&lt;br /&gt;
&lt;br /&gt;
===[[X-Terminator Mark II]]===&lt;br /&gt;
* [[Greg Bingleman]] - [http://www.codemonkeypublishing.com Code Monkey Publishing]&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
* Brad Stiles, SVN advice&lt;br /&gt;
* Jason Buchanan, Advice on old code&lt;br /&gt;
* [[Jonas Karlson]], Advice on old code&lt;br /&gt;
&lt;br /&gt;
=Passive Team Members=&lt;br /&gt;
&lt;br /&gt;
* B. K. Oxley (Provides IntelliJ licenses)&lt;br /&gt;
&lt;br /&gt;
=Inactive Team Members=&lt;br /&gt;
&lt;br /&gt;
===[[Explanation_of_Teams#2nd|2nd]]===&lt;br /&gt;
* Devon Jones&lt;br /&gt;
&lt;br /&gt;
===[[Explanation_of_Teams#Chimp|Chimp]]===&lt;br /&gt;
* Aaron Divinsky&lt;br /&gt;
&lt;br /&gt;
===[[Explanation_of_Teams#Tamarin|Tamarin]]===&lt;br /&gt;
* Andriy Sen&lt;br /&gt;
* [[Kevin Fernandes]]&lt;br /&gt;
* [[Koen Van Daele]]&lt;br /&gt;
* [[Joe Frazier, Jr.]]&lt;br /&gt;
* Per Christian Henden&lt;br /&gt;
&lt;br /&gt;
===[[Explanation_of_Teams#Lemur|Lemur]]===&lt;br /&gt;
* Bill Neumann&lt;br /&gt;
* Dan Parks&lt;br /&gt;
* [[Eduard Martinescu]]&lt;br /&gt;
* Eric Jarman&lt;br /&gt;
* Jasper Spaans&lt;br /&gt;
* Julio Esslinger Viegas&lt;br /&gt;
* Peter Barker&lt;br /&gt;
* [[Rick Ryker]]&lt;br /&gt;
* Thomas Clegg&lt;br /&gt;
* Tony Lavalle&lt;br /&gt;
* Hades Lucifer [7/20/10]&lt;br /&gt;
* Josh Johnston [7/20/10]&lt;br /&gt;
* MotorViper    [7/20/10]&lt;br /&gt;
* [[Steven West]] [7/20/10]&lt;br /&gt;
* [[Alec Ross]] [7/20/10]&lt;br /&gt;
* [[Tir Gwaith]] [7/20/10]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
* [[Andargor]], Suggestions&lt;br /&gt;
* [[Bryan McRoberts]], Advice on old code&lt;br /&gt;
* Kurt Wimmer, Suggestions&lt;br /&gt;
* Walter Duncan, Held the old pcgen_autobuild user&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Coding_Standards&amp;diff=2860</id>
		<title>Coding Standards</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Coding_Standards&amp;diff=2860"/>
		<updated>2011-05-07T13:29:43Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* General Coding guidelines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
Releases typically happen every second Sunday Canberra, Australia (UTC+11) time. There may be code freezes on release days, but these will be announced in advance on the developers and experimental lists. There are 2 taboos:&lt;br /&gt;
&lt;br /&gt;
# Checking in code that breaks the build.&lt;br /&gt;
# Checking in code that obviously wasn't tested.&lt;br /&gt;
&lt;br /&gt;
We have a couple of code monkeys who make sweeps through the code to make sure it's all in the proper format, and we have others who go through looking to optimize code. Everyone has their role and things have gone very smoothly. If you are not certain about something, ask! Nobody is here to bite your head off (unless they are role-playing a troll). Try the developer's mailing list or any of the Yahoo! Groups or the Silverbacks.&lt;br /&gt;
&lt;br /&gt;
=Code Style=&lt;br /&gt;
&lt;br /&gt;
Coding styles can be assisted by your IDE, see the standards folder in the SVN repository.&lt;br /&gt;
&lt;br /&gt;
* For Eclipse you can use [http://pcgen.svn.sourceforge.net/viewvc/*checkout*/pcgen/Trunk/pcgen/code/standards/eclipse32_pcgen.xml 3.2 Formatter Rules]&lt;br /&gt;
&lt;br /&gt;
Voting for the code conventions is currently restricted to active code monkeys (have checked in in the last 6 months), the current votes (and therefore standard) is below.&lt;br /&gt;
&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Rule !! For !! Against&lt;br /&gt;
|-&lt;br /&gt;
| Use Tabs || 4 || 4&lt;br /&gt;
|-&lt;br /&gt;
| Use Spaces || 4 || 4&lt;br /&gt;
|-&lt;br /&gt;
| Have braces around 1 line control statements || 8 || 0&lt;br /&gt;
|-&lt;br /&gt;
| Open and close braces on their own line || 5 || 3&lt;br /&gt;
|-&lt;br /&gt;
| 1 space padding inside parenthesis when calling a method || 0 || 8&lt;br /&gt;
|-&lt;br /&gt;
| 1 space padding inside parenthesis when declaring a method || 0 || 8&lt;br /&gt;
|-&lt;br /&gt;
| Space after a comma || 8 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Who Has Voted''' (simply link in your name when you have done so)&lt;br /&gt;
# [[Martijn Verburg]]&lt;br /&gt;
# Aaron Divinsky&lt;br /&gt;
# [[Andrew Wilson]]&lt;br /&gt;
# Brian (telechus)&lt;br /&gt;
# [[Devon Jones]]&lt;br /&gt;
# [[Greg Bingleman]]&lt;br /&gt;
# [[James Dempsey]]&lt;br /&gt;
# [[Jonas Karlson]]&lt;br /&gt;
# Stefan Radermacher&lt;br /&gt;
# [[Tir Gwaith]]&lt;br /&gt;
# [[Tod Milam]]&lt;br /&gt;
&lt;br /&gt;
=Code Warnings and Errors=&lt;br /&gt;
&lt;br /&gt;
Code Warnings and Errors may vary by tool.&lt;br /&gt;
&lt;br /&gt;
'''Please note that IDEA 9.01 can utilise Eclipse formatting rule exports, so we no longer need to cover that case'''&lt;br /&gt;
&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Rule !! Eclipse 3.5.1 !! IDEA 9.01 !! NetBeans !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Non-static Access to a static member || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Indirect access to a static member || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Unqualified access to an instance field || Y || ? || Probably Y || Referencing instance fields with ''this'' keyword&lt;br /&gt;
|-&lt;br /&gt;
| Undocumented Empty block || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Access to a non-accessible member of an enclosing type || Y || ? || Probably Y || - &lt;br /&gt;
|-&lt;br /&gt;
| Method with a constructor name || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Parameter Assignment || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Non-externalized Strings (missing/unused $NON-NLS$tag) || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Serializable class without serialVersionUID || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Assignment has no effect (''x = x;'') || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Possible accidental boolean assignment ''if (a = b)'' || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| ''finally'' does not complete normally || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Empty Statement || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Using a char array in String concatenation || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Hidden catch block || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Inexact type match for vararg arguments || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Boxing and unboxing conversions || Y || ? || ? || Basically wants you to explicitly box and unbox basic types&lt;br /&gt;
|-&lt;br /&gt;
| Enum type constant not covered in switch statement || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| switch case falls through || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Null pointer access || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Potential null pointer access || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Comparing identical values ('x' == 'x') || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Missing synchronized modifier on inherited method || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Class overrides equals() but not hashCode() || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Dead code (e.g. 'if (false)') || Y || ? || Y* || Netbeans is covered by 'Unreachable Statement' option&lt;br /&gt;
|-&lt;br /&gt;
| Field declaration hides another field or variable || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Local declaration hides another field or variable (General) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Local declaration hides another field or variable (Constructors and Gettors/Setters) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Type parameter hides another type || Y || ? || Probably Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Method does not override package visible method || Y || ? || Probably Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Interface method conflicts with protected method in Object || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Deprecated API || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Deprecated API (signal use of deprecated api inside deprecated code) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Deprecated API (signal overriding or implementing method) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Forbidden Reference (access rules) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Discouraged Reference (access rules) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Local variable is never read || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Parameter is never read (non overriding methods) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Parameter is never read (overriding methods) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Parameter is never read (even if documented with @param tag) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Unused import || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Unused local or private member || Y || ? || Y || Includes unused private methods&lt;br /&gt;
|-&lt;br /&gt;
| Unused method || Y* || ? || Y || Eclipse is covered by 'Unused local or private member' option&lt;br /&gt;
|-&lt;br /&gt;
| Unreachable statement || Y* || ? || Y || Eclipse is covered by 'Dead code' option&lt;br /&gt;
|-&lt;br /&gt;
| .equals on Array || N || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| .equals on Incompatible Types || N || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Comparing Strings using == or != || N || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Synchronization on non-final field || N || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Redundant null check || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary else || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary cast or instanceof || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary declaration of thrown checked exception (non overriding methods) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary declaration of thrown checked exception (overriding methods) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary declaration of thrown checked exception (ignore exceptions declared with @throws or @exception) || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary declaration of thrown checked exception (ignore Exception and Throwable) || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Unused break/continue label || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Redundant super interface || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Unchecked generic type operation (JDK1.5) || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Usage of a raw type (JDK1.5) || Y || ? || Y || i.e. Using List instead of List&amp;lt;String&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Generic type parameter declared with a final type bound (JDK1.5) || Y || ? || ? || -&lt;br /&gt;
|-&lt;br /&gt;
| Missing Override annotation || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Missing Deprecated annotation || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Annotation is used as a super interface || Y || ? || Y || -&lt;br /&gt;
|-&lt;br /&gt;
| Unhandled token in SupressWarnings token || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Unused SupressWarnings token || Y || ? || N || -&lt;br /&gt;
|-&lt;br /&gt;
| Enable SupressWarnings annotations || Y || ? || Y || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Standard 2004-Present==&lt;br /&gt;
Coding warnings and errors can be highlighted for correction by your IDE, see the standards folder in the SVN repository.&lt;br /&gt;
&lt;br /&gt;
Voting for the code warnings is currently restricted to active code monkeys (have checked in in the last 6 months), the current votes (and therefore standard) is below.&lt;br /&gt;
&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Rule !! For !! Against !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Non-static Access to a static member || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Indirect access to a static member || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unqualified access to an instance field || 0 || 3 || Referencing instance fields with ''this'' keyword&lt;br /&gt;
|-&lt;br /&gt;
| Undocumented Empty block || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Access to a non-accessible member of an enclosing type || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Method with a constructor name || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Parameter Assignment || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Non-externalized Strings (missing/unused $NON-NLS$tag) || 2 || 1 || Basically [[Internationalization]] will need this&lt;br /&gt;
|-&lt;br /&gt;
| Serializable class without serialVersionUID || 0 || 3 || -&lt;br /&gt;
|-&lt;br /&gt;
| Assignment has no effect (''x = x;'') || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Possible accidental boolean assignment ''if (a = b)'' || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| ''finally'' does not complete normally || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Empty Statement || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Using a char array in String concatenation || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Hidden catch block || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Boxing and unboxing conversions || 0 || 3 || Basically wants you to explicitly box and unbox basic types&lt;br /&gt;
|-&lt;br /&gt;
| Inexact type match for vararg arguments || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Enum type constant not covered in switch statement || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| switch case falls through || 1 || 2 || -&lt;br /&gt;
|-&lt;br /&gt;
| Null reference || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Field declaration hides another field or variable || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Local declaration hides another field or variable (General) || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Local declaration hides another field or variable (Constructors and Gettors/Setters) || 1 || 2 || -&lt;br /&gt;
|-&lt;br /&gt;
| Type parameter hides another type || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Method overridden but not package visible || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Interface method conflicts with protected method in Object || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Deprecated API || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Forbidden Reference (access rules) || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Discouraged Reference (access rules) || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Local variable is never read || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Parameter is never read (non overriding methods) || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Parameter is never read (overriding methods) || 0 || 3 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unused import || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unused local or private member || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary cast or instanceof || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary else || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary declaration of thrown checked exception (non overriding methods) || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unnecessary declaration of thrown checked exception (overriding methods) || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unused break/continue label || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unchecked generic type operation (JDK1.5) || 3 || 0 || -&lt;br /&gt;
|-&lt;br /&gt;
| Usage of a raw type (JDK1.5) || 3 || 0 || i.e. Using List instead of List&amp;lt;String&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Generic type parameter declared with a final type bound (JDK1.5) || 0 || 3 || -&lt;br /&gt;
|-&lt;br /&gt;
| Missing Override annotation || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Missing Deprecated annotation || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Annotation is used as a super interface || 2 || 1 || -&lt;br /&gt;
|-&lt;br /&gt;
| Unhandled token in SupressWarnings token || 3 || 0 || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Who Has Voted''' (simply link in your name when you have done so)&lt;br /&gt;
# [[Martijn Verburg]]&lt;br /&gt;
# Aaron Divinsky&lt;br /&gt;
# [[Andrew Wilson]]&lt;br /&gt;
# Brian (telechus)&lt;br /&gt;
# Devon Jones&lt;br /&gt;
# Greg Bingleman&lt;br /&gt;
# [[James Dempsey]]&lt;br /&gt;
# Jonas Karlson&lt;br /&gt;
# Stefan Radermacher&lt;br /&gt;
# Tir Gwaith&lt;br /&gt;
# Tod Milam&lt;br /&gt;
&lt;br /&gt;
=General Coding guidelines=&lt;br /&gt;
&lt;br /&gt;
# Arguments should have meaningful names, even if that makes them really long. variables that are temporary and throwaway you can name something inane - I like to name temporary strings aString for lack of any additional creative effort on my part :) (But for some of us, plain old s is just fine.) You will see aPC almost everywhere for PlayerCharacter instances, regardless of other conventions.&lt;br /&gt;
# Name arguments to methods something reasonable so IDE's that display the argument names can give a guide as to what is expected. If the method is something like setVision(String arg) it's pretty clear what's expected, but for methods which take multiple arguments it's especially important to name the arguments well.&lt;br /&gt;
# Always keep optimization in mind. Avoid creating unnecessary variables. But don't go out of your of your way to optimize if it clouds the meaning of the code or makes it harder to maintain. When in doubt, correctness trumps performance.&lt;br /&gt;
# Keep scope in mind — if a variable or method can be made private, protected or final, do so. If you're not sure what the difference is in these, don't be afraid to ask. This gets into the minutest of Java and we're glad to educate you so we can all make the best code possible.&lt;br /&gt;
# Write unit tests for new code, see [[Unit Testing]].&lt;br /&gt;
# Add comments and Javadoc.&lt;br /&gt;
# If you change the syntax of a lst tag or output sheet token or modify the GUI or anything else that needs to be reflected in the Documentation, post a note here with Doc Monkeys! in the title so it gets their attention. If you can type up your notes so it fits with the format used in the actual documentation, the Doc Monkeys will love you. If you're not able to do that, give them at least something to work with and they'll make the rest up. :)&lt;br /&gt;
# Be friendly and courteous. If someone checks in code that annoys you — e-mail them. If you can't reach them or get no response, e-mail me. Slamming here shouldn't be necessary.&lt;br /&gt;
# Don't break the build. I've broken the build myself, so I don't hold it against anyone if they break it (though I don't expect anyone to make a habit of it!). Running ''ant complete'' pretty much saves you from this embarrassment.&lt;br /&gt;
# Make sure the JUnit tests pass before checking in your code. Running ''ant test'' is the answer here. (The &amp;quot;complete&amp;quot; target for ant includes &amp;quot;test&amp;quot;, by the way.) Keep an eye on the autobuilds. If the software is presently failing for the auto-builds, it might be a good time to focus on build-fixing changes.&lt;br /&gt;
&lt;br /&gt;
Remember we're all doing this for fun and because we want to produce something that can support character creation/maintenance for all our favorite books (and our own creations!).&lt;br /&gt;
&lt;br /&gt;
If anyone wants to tackle a bug or feature but doesn't know where the code they should focus on is located, feel free to ask. I'm more than happy to point out where I think the related code would be located if that means its another bug or feature I don't have to worry about! PCGen has a fairly large code base so new developers will need some time to get used to how everything is organized. I don't mind helping to speed that process along, and I'm sure others would be willing to answer questions if they're posted here as well.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=2859</id>
		<title>Andrew Wilson</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Andrew_Wilson&amp;diff=2859"/>
		<updated>2011-05-07T13:24:57Z</updated>

		<summary type="html">&lt;p&gt;Nuance: Created page with &amp;quot;{| align=&amp;quot;right&amp;quot;   | __TOC__   |}  =Introduction= I'm based in the UK, my sourceforge id is nuance.  Day job is safety critical software, mostly ada these days. I Joined the PCGe...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
I'm based in the UK, my sourceforge id is nuance.  Day job is safety critical software, mostly ada these days. I Joined the PCGen team on the 19th April 2001, which seems like a very long time ago now.&lt;br /&gt;
&lt;br /&gt;
=Teams I belong to=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
! Team !! Rank&lt;br /&gt;
|-&lt;br /&gt;
| [[Code]] || [[Can't remember (don't pay much attention to it)]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Contact Details=&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
| Timezone || GMT&lt;br /&gt;
|-&lt;br /&gt;
| e-mail || andrewATrivendaleDOTnet&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=User:Nuance&amp;diff=1481</id>
		<title>User:Nuance</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=User:Nuance&amp;diff=1481"/>
		<updated>2009-04-08T22:42:10Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a page about [[User:Nuance|andrew]].  There are many like it, but this one is mine.&lt;br /&gt;
&lt;br /&gt;
I'm the code Lemur version of andrew.  Not to be confused with Messrs [[User:LegacyKing|Maitlaind]] or [[User:Tir_Gwaith|McDougal]].&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1480</id>
		<title>Separator Characters</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1480"/>
		<updated>2009-04-08T21:55:53Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
There is an issue as far as long-term consistency for the use of characters to represent logical &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This document uses CHOOSE:TEMPLATE (since it doesn't exist) as an example.  For additional CHOOSE tokens and proposals, you can see [[Architecture Changes 5.17]]&lt;br /&gt;
&lt;br /&gt;
To readers: Please add additional options if you have additional ideas.  You may find the [[Data LST Standards]] useful to look at reserved characters.&lt;br /&gt;
&lt;br /&gt;
==Option #1, Using Pipe as an OR separator, Using Comma as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1|Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo|!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]|QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]|QUALIFIED,!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* Note that this is the existing syntax used in the CHOOSE proposals as they are shown on the Wiki. [TRP]&lt;br /&gt;
* Showing this syntax to a few non coders it definitely wasn't instinctively clear that ',' was an AND symbol.  However, '|' was instinctively picked up as an OR symbol [[User:Karianna|karianna]] 18:59, 1 April 2009 (CEST)&lt;br /&gt;
* Part of that is that the pipe '|' just seems to break that attention naturally, which is why it works so well as a subtoken separator.  But I think we should move away from giving two jobs to the same thing.--[[User:Michael W. Fender|Fluxxdog]] 01:12, 2 April 2009 (CEST)&lt;br /&gt;
Insert comments on option #1 here.&lt;br /&gt;
&lt;br /&gt;
==Option #2, Using Comma as an OR separator, Using Ampersand as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1,Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;amp;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&amp;amp;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo],QUALIFIED&amp;amp;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
*I think this is a problem, as ampersand is not a reserved character in PCGen. This is used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  Therefore, in order to implement this properly, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16).  While I think this is a nice idea, I think the hurdle is too large to do this quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
Insert other comments on option #2 here.  &lt;br /&gt;
&lt;br /&gt;
==Option #3, Using &amp;lt;OR&amp;gt; as an OR separator, Using &amp;lt;AND&amp;gt; as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1&amp;lt;OR&amp;gt;Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&amp;lt;OR&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&amp;lt;AND&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&amp;lt;OR&amp;gt;QUALIFIED&amp;lt;AND&amp;gt;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* Note that the unicode discussion here was broken out into option #4. - thpr Apr 4&lt;br /&gt;
&lt;br /&gt;
*I Have a similar concern here to option #2, as we have not reserved &amp;lt; or &amp;gt; as restricted characters. &amp;lt; and &amp;gt; are used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  There is less risk of using (literally) &amp;lt;OR&amp;gt; or &amp;lt;AND&amp;gt;, which makes this somewhat safer than option #2.  However, this does introduce restrictions on data naming.  In order to implement this without risk, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16). I think the hurdle is too large to do the FREQ converter quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
*Do the characters '&amp;lt;' and '&amp;gt;' matter?  Are there other characters that can't be used in a key name that can be used for identifying a logical operator?  What about '$'?  Are there any characters that we cannot use whatsoever for this? --[[User:Michael W. Fender|Fluxxdog]] 04:03, 1 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
:* You may find the [[Data LST Standards]] useful to find reserved characters. &lt;br /&gt;
::*Not as helpful as you think.  This just lists what should and shouldn't be used in our releases, not what actually can and can't be used.  &lt;br /&gt;
::::*Not True: Characters which should never be used in object names are Commas (,), Pipes (|), Backslashes (\), Colons (:), Semicolons (;), Periods (.), Brackets ([]), Percent (%), Asterisk (*) and Equals (=).  Perhaps we should change the language to &amp;quot;must not be used&amp;quot; to be more RFC 2119-like and avoid confusion. [TRP]&lt;br /&gt;
:::For example, we shouldn't use a backslash '\' but we can.&lt;br /&gt;
::::*I'm not convinced.  Legality isn't defined by what parses cleanly.  There are specific reasons each of those characters is prohibited.  Try using backslash in a name inside a count() inside a Formula and see if it works.  If that does work, I'd have to go code hunting to figure out what the case is that prohibits backslash, but it's on that list for a reason. [TRP]&lt;br /&gt;
:::::*...You don't know why?  OK&amp;lt; just to test your challenge, I tried making a feat and having something else count() that number of times I took that feat.  Problem is, it won't even let me take the feat.  Possible safeguard? - Fluxxdog&lt;br /&gt;
:::DEFINE:Spaced\Variable|0	BONUS:VAR|Spaced\Variable|3	DESC:Here's the value: %1|Spaced\Variable&lt;br /&gt;
:::...still spits out &amp;quot;''Here's the value: 3''&amp;quot;--[[User:Michael W. Fender|Fluxxdog]] 23:35, 4 April 2009 (CEST)&lt;br /&gt;
:::I'll double back a bit.  If we go the route of using our &amp;quot;shouldn't use&amp;quot; characters, what options do we have?&lt;br /&gt;
::::(snip - please read [[Data LST Standards]])&lt;br /&gt;
::::* The issue here is that the items prohibited from names are the ONLY characters we can use without writing a converter. [TRP]&lt;br /&gt;
:::None of these should be used as they already have other functions already.&lt;br /&gt;
::::*This is where the problem lies.&lt;br /&gt;
:::::* Depends on your definition of problem, but the point I have is that we either make sacrifices from the ideal, or we delay the conversion to these tokens until we can reach the ideal, which may be years away.  I'd rather make sacrifices, which means using the characters on the prohibited list or getting REALLY wide agreement and community input that we can break datasets. [TRP]&lt;br /&gt;
::::::*That's my point.  Who uses a backslash in their data sets?  And the backslash isn't used anywhere else in LST files already.  I'd say it's the ideal nominee for such an operation. - Fluxxdog&lt;br /&gt;
:::*Backslashes (\)&lt;br /&gt;
:::Curious thought, does anything actually use this?  I don't think I've seen anything other than file names, which aren't used in LST files.&lt;br /&gt;
::::CHOOSE:TEMPLATE|Extra Weaponry\OR\Extra Appendage\OR\Extra Flavor\OR\Candle Power\OR\Super Eyesight&lt;br /&gt;
:::Unless a backslash is already being used, that doesn't look too bad itself.  And it's highly unlikely, even more so than &amp;lt; and &amp;gt;, that it's used in LST files for even homebrews.  It certainly isn't in our LST files now.--[[User:Michael W. Fender|Fluxxdog]] 02:32, 5 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
* [nuance] I think the lower case version stands out better.&lt;br /&gt;
&lt;br /&gt;
:* I'll definitely agree with nuance on using lowercase for 'and' and 'or'.  Makes it so much more obvious.--[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
::* I happen to prefer the uppercase versions.  - thpr&amp;lt;br&amp;gt;&lt;br /&gt;
:::One needs to consider also that these will often be used with Primitive objects, e.g.:&amp;lt;br&amp;gt;&lt;br /&gt;
:::CHOOSE:TEMPLATE|Extra Weaponry&amp;lt;or&amp;gt;Extra Appendage&amp;lt;or&amp;gt;Extra Flavor&amp;lt;or&amp;gt;Candle Power&amp;lt;or&amp;gt;Super Eyesight&amp;lt;br&amp;gt;&lt;br /&gt;
:::CHOOSE:TEMPLATE|Extra Weaponry&amp;lt;OR&amp;gt;Extra Appendage&amp;lt;OR&amp;gt;Extra Flavor&amp;lt;OR&amp;gt;Candle Power&amp;lt;OR&amp;gt;Super Eyesight&amp;lt;br&amp;gt;&lt;br /&gt;
:::... so I feel that the upper case keyword is far more consistent with our tokens (where the keywords like TEMPLATE, TYPE, etc. are all upper case) and also stand out more.&lt;br /&gt;
:::*How dare you use logic!  ^^  But yeah, when you put it that way, we should stick to the standard of using CAPS for hardcoded words.--[[User:Michael W. Fender|Fluxxdog]] 23:35, 4 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
*Just a tad bit of a summation here:  If we use a character to denote the logical operators, the backslash '\' would seem the ideal choice as it's already restricted from being used in key names, so \AND\ and \OR\?  Unless I'm misunderstanding you, Tom, out of the &amp;quot;don't use&amp;quot; list, this is the only one that's both&lt;br /&gt;
::A) not in use for some other purpose&lt;br /&gt;
::B) not in use for data sets&lt;br /&gt;
:If I'm wrong, please say so.--[[User:Michael W. Fender|Fluxxdog]] 16:26, 5 April 2009 (CEST)&lt;br /&gt;
::* If the path is to follow the spelled-out separators, then of the reserved characters (,|\:.[]%*=), .[]%= are already in the syntax and can't be used due to parsing problems.  : is our main token/value separator, and I'd really like to avoid that (though we can use it if necessary).  That leaves ,|\* of which only | is used elsewhere in the token (as a separator).  ,*\ all remain unused in the context of CHOOSE.  , is used elsewhere, but if we convert the other tokens, it would otherwise be unused. [TRP]&lt;br /&gt;
:::*Here's what I'm getting at:  Backslash is not used anywhere else.  I've searched all the LST files in the data sets we publish (and just to be sure, I checked the alpha sets too) and nothing uses it.  I don't even recall coming across a token that does use it.  I'd rather leave the comma free, just in case and to avoid any confusion, and using a mathematical operator '*' just seems to ask for trouble somewhere.&lt;br /&gt;
:::If we go this route, is there any reason not to use the backslash for this?  I.E. \AND\ \OR\ --[[User:Michael W. Fender|Fluxxdog]] 01:14, 6 April 2009 (CEST)&lt;br /&gt;
::::* From a programming perspective, \AND\ is just as easy as a comma.  However, just to be clear, this process is to gather opinions, and we are missing some key players so far.  If the backslash is considered unclear, then that will be a major reason for it not to be used, and it will not be used.  You seem to have a strong opinion about this, but you need to give other people a chance to express their opinion as well.  Just because it is not used elsewhere, doesn't mean it is inevitable under this option. [TRP]&lt;br /&gt;
:::::*Heh, not trying to dominate here, but yeah, I think this is the better way.  I dislike option 1 and 2 as symbolism in a LST file is pretty aggravating on its own.  (I'm pretty familiar with wild cards, so using '%' wasn't a big leap for me.)  Using the words AND and OR would make it so much clearer.  I dislike option 4 because it would require us to train people how to use such non-standard characters.  Option 3 seems to be dependent on which character(s) we use to mark the logical operators, so I'd like to narrow it down to a best choice to get behind.&lt;br /&gt;
::::::In the end, I won't be the one to make the final call.  But when that call is made, I'll have contributed something to the process, which is why I've joined with the team in the first place.&lt;br /&gt;
::::::And the rest of you just watching form the side lines, chime in!  Tom's right, 3 people can't haggle about this by themselves! :p --[[User:Michael W. Fender|Fluxxdog]] 02:26, 6 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
* [[User:Nuance|nuance]] Backslashes—I hate this option.  It's hard to say how much I hate it.&lt;br /&gt;
&lt;br /&gt;
* [[User:Nuance|nuance]] Can I point out I'm also convinced we shouldn't use / or - in things like class names.  is CL=Funky-Gibbon asking for how many levels in class &amp;quot;Funky-Gibbon&amp;quot; or is it asking for how many levels in class &amp;quot;Funky&amp;quot; less the variable &amp;quot;Gibbon&amp;quot;.  If I defined the variable Gibbon would it change the answer, what if I has class Funky and Variable Gibbon already defined and then defined class Funky-Gibbon?  Same argument with /  what does CL=Funky/Gibbon mean?&lt;br /&gt;
&lt;br /&gt;
Insert comments on option #3 here.&lt;br /&gt;
&lt;br /&gt;
==Option #4, Leverage Unicode to use other separators, e.g. «OR» as an OR separator, Using «AND» as an AND separator==&lt;br /&gt;
&lt;br /&gt;
Examples use lowercase&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1«or»Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo«or»!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo«and»!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«or»!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar«or»TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«or»!TYPE=Bar]«or»QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar]«and»QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar«or»TYPE=Goo]«or»QUALIFIED«and»!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* [nuance] LST files are UTF8, so theoretically we can use any unicode character.  The problem with that is editor support—which it has to be said is getting better all the time.  Since full unicde may be a bit of a shock , iso-8859-1 (latin 1) has « and » (alt0171 and alt0187 respectively).  It also has ¿ (alt0191) which ties up nicely with ? if was want to wrap words.&lt;br /&gt;
&lt;br /&gt;
:Of course, fully in the realm of unicode madness, we could always use &amp;amp;#8743; for and, and &amp;amp;#8744; for or, but the data folk might shoot us :-).  Actually we could consider ^ to mean and, paired with | &lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC[TYPE=Foo^!TYPE=Bar|TYPE=Goo]|QUALIFIED^!PC&lt;br /&gt;
&lt;br /&gt;
::...allows a choice of:&lt;br /&gt;
::(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
::OR&lt;br /&gt;
::(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
:I think I prefer the last one, but I don't like the way | looks against ].  On this wiki ! is hard to distinguish from |, ¬ (shift ` on my keyboard) actually means not.  I think using « and » in place of [ and ], and ¬ for not&lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC«TYPE=Foo^¬TYPE=Bar|TYPE=Goo»|QUALIFIED^¬PC&lt;br /&gt;
&lt;br /&gt;
:is easier to read but that might be a bit radical.  Perhaps it's time we has that full reserved characters discussion.&lt;br /&gt;
:*Very true since we don't seem to have a full list (see above in option 3 about standards vs. actually allowed)--[[User:Michael W. Fender|Fluxxdog]] 23:58, 4 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
*I'd like to move away from symbolism for words and actually use the words themselves.  It makes it a lot easier for new people to read.--[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Using '«' and '»' is a good idea, but how exactly do you type that in?  I think we should stick closer to what's available on the common keyboards without having to dig through a font list.  Although, that gives me an idea...  What about a character combinations?&lt;br /&gt;
&lt;br /&gt;
:* [[User:Nuance|nuance]] Sorry if it was a bit opaque, but I gave instructions for how to type it (on a windows machine at least).  Press and hold the &amp;quot;alt&amp;quot; key to the left of your space bar.  Now, using the numeric keypad, type the numbers 0171, realease the &amp;quot;alt&amp;quot; key.  Et viola «.  » is similarly produced with the numbers 0187.  Once you have one of them cut and paste is also an option.  Since we aren't fully in the unicode realm here, most OSes have some way to type characters in the ios-8859-1 range.&lt;br /&gt;
::*I'm not saying it's a bad idea, I'm saying it's not a good idea.  People will have to look into some kind of &amp;quot;tips and tricks&amp;quot; for their keyboard AND OS AND language AND font, since not every combination will work like that.  Heck, tested it on 3 different programs on my system and it doesn't work at all.  I think this is definitely a case of &amp;quot;the simpler the better&amp;quot;.--[[User:Michael W. Fender|Fluxxdog]] 23:58, 4 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
::: [http://en.wikipedia.org/wiki/Guillemets#Typing_.22.C2.AB.22_and_.22.C2.BB.22_on_computers| Typing the Guilemets « »]&lt;br /&gt;
:::*We'd have to include that link everytime «AND» or «OR» is included or put the information in the docs just to ensure everyone has that info when coding LST files.  I'd say, at the very least, let's stick with characters that can't or shouldn't be used in Key names.--[[User:Michael W. Fender|Fluxxdog]] 02:19, 5 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
::::[[User:Nuance|nuance]] I disagree, we would need to include the info in our Docs, but that's it.  People already need to read the docs to code in LST.  We have mailing lists where people can ask questions.  I think « and » are infinitely better than \ in this context.  \and\ is horrendously ugly and IMO hard to read.  Point is « and » are easy to type on the vast majority of keyboards/OSes.  Most poeple who can't figure out how to do something in lst ask or look at the distributed sets.  If they're looking at distributed data then—at the very least—they can cut and paste «AND» and «OR» into their own code.&lt;br /&gt;
&lt;br /&gt;
:Hey coders!  Could we do something along the lines of &amp;lt;&amp;lt;and&amp;gt;&amp;gt;?  Using 2 '&amp;lt;' to signify a logical operator?  Surely that must make things easier. -[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
:* Really doesn't make a huge difference.  The &amp;lt; and &amp;gt; still aren't identified as reserved characters.  It reduces the risk slightly, but it's probably small with &amp;lt;AND&amp;gt; and &amp;lt;OR&amp;gt; anyway. - thpr&lt;br /&gt;
&lt;br /&gt;
Insert comments on option #4 here.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1429</id>
		<title>Separator Characters</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1429"/>
		<updated>2009-04-04T23:58:32Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
There is an issue as far as long-term consistency for the use of characters to represent logical &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This document uses CHOOSE:TEMPLATE (since it doesn't exist) as an example.  For additional CHOOSE tokens and proposals, you can see [[Architecture Changes 5.17]]&lt;br /&gt;
&lt;br /&gt;
To readers: Please add additional options if you have additional ideas.  You may find the [[Data LST Standards]] useful to look at reserved characters.&lt;br /&gt;
&lt;br /&gt;
==Option #1, Using Pipe as an OR separator, Using Comma as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1|Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo|!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]|QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]|QUALIFIED,!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* Note that this is the existing syntax used in the CHOOSE proposals as they are shown on the Wiki. [TRP]&lt;br /&gt;
* Showing this syntax to a few non coders it definitely wasn't instinctively clear that ',' was an AND symbol.  However, '|' was instinctively picked up as an OR symbol [[User:Karianna|karianna]] 18:59, 1 April 2009 (CEST)&lt;br /&gt;
* Part of that is that the pipe '|' just seems to break that attention naturally, which is why it works so well as a subtoken separator.  But I think we should move away from giving two jobs to the same thing.--[[User:Michael W. Fender|Fluxxdog]] 01:12, 2 April 2009 (CEST)&lt;br /&gt;
Insert comments on option #1 here.&lt;br /&gt;
&lt;br /&gt;
==Option #2, Using Comma as an OR separator, Using Ampersand as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1,Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;amp;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&amp;amp;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo],QUALIFIED&amp;amp;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
*I think this is a problem, as ampersand is not a reserved character in PCGen. This is used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  Therefore, in order to implement this properly, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16).  While I think this is a nice idea, I think the hurdle is too large to do this quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
Insert other comments on option #2 here.  &lt;br /&gt;
&lt;br /&gt;
==Option #3, Using &amp;lt;OR&amp;gt; as an OR separator, Using &amp;lt;AND&amp;gt; as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1&amp;lt;OR&amp;gt;Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&amp;lt;OR&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&amp;lt;AND&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&amp;lt;OR&amp;gt;QUALIFIED&amp;lt;AND&amp;gt;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* Note that the unicode discussion here was broken out into option #4. - thpr Apr 4&lt;br /&gt;
&lt;br /&gt;
*I Have a similar concern here to option #2, as we have not reserved &amp;lt; or &amp;gt; as restricted characters. &amp;lt; and &amp;gt; are used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  There is less risk of using (literally) &amp;lt;OR&amp;gt; or &amp;lt;AND&amp;gt;, which makes this somewhat safer than option #2.  However, this does introduce restrictions on data naming.  In order to implement this without risk, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16). I think the hurdle is too large to do the FREQ converter quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
*Do the characters '&amp;lt;' and '&amp;gt;' matter?  Are there other characters that can't be used in a key name that can be used for identifying a logical operator?  What about '$'?  Are there any characters that we cannot use whatsoever for this? --[[User:Michael W. Fender|Fluxxdog]] 04:03, 1 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
:* You may find the [[Data LST Standards]] useful to find reserved characters. &lt;br /&gt;
::*Not as helpful as you think.  This just lists what should and shouldn't be used in our releases, not what actually can and can't be used.  For example, we shouldn't use a backslash '\' but we can.&lt;br /&gt;
:::DEFINE:Spaced\Variable|0	BONUS:VAR|Spaced\Variable|3	DESC:Here's the value: %1|Spaced\Variable&lt;br /&gt;
:::...still spits out &amp;quot;''Here's the value: 3''&amp;quot;--[[User:Michael W. Fender|Fluxxdog]] 23:35, 4 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
* [nuance] I think the lower case version stands out better.&lt;br /&gt;
&lt;br /&gt;
:* I'll definitely agree with nuance on using lowercase for 'and' and 'or'.  Makes it so much more obvious.--[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
::* I happen to prefer the uppercase versions.  - thpr&amp;lt;br&amp;gt;&lt;br /&gt;
:::One needs to consider also that these will often be used with Primitive objects, e.g.:&amp;lt;br&amp;gt;&lt;br /&gt;
:::CHOOSE:TEMPLATE|Extra Weaponry&amp;lt;or&amp;gt;Extra Appendage&amp;lt;or&amp;gt;Extra Flavor&amp;lt;or&amp;gt;Candle Power&amp;lt;or&amp;gt;Super Eyesight&amp;lt;br&amp;gt;&lt;br /&gt;
:::CHOOSE:TEMPLATE|Extra Weaponry&amp;lt;OR&amp;gt;Extra Appendage&amp;lt;OR&amp;gt;Extra Flavor&amp;lt;OR&amp;gt;Candle Power&amp;lt;OR&amp;gt;Super Eyesight&amp;lt;br&amp;gt;&lt;br /&gt;
:::... so I feel that the upper case keyword is far more consistent with our tokens (where the keywords like TEMPLATE, TYPE, etc. are all upper case) and also stand out more.&lt;br /&gt;
:::*How dare you use logic!  ^^  But yeah, when you put it that way, we should stick to the standard of using CAPS for hardcoded words.--[[User:Michael W. Fender|Fluxxdog]] 23:35, 4 April 2009 (CEST)&lt;br /&gt;
Insert comments on option #3 here.&lt;br /&gt;
&lt;br /&gt;
==Option #4, Leverage Unicode to use other separators, e.g. «OR» as an OR separator, Using «AND» as an AND separator==&lt;br /&gt;
&lt;br /&gt;
Examples use lowercase&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1«or»Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo«or»!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo«and»!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«or»!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar«or»TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«or»!TYPE=Bar]«or»QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar]«and»QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar«or»TYPE=Goo]«or»QUALIFIED«and»!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* [nuance] LST files are UTF8, so theoretically we can use any unicode character.  The problem with that is editor support—which it has to be said is getting better all the time.  Since full unicde may be a bit of a shock , iso-8859-1 (latin 1) has « and » (alt0171 and alt0187 respectively).  It also has ¿ (alt0191) which ties up nicely with ? if was want to wrap words.&lt;br /&gt;
&lt;br /&gt;
:Of course, fully in the realm of unicode madness, we could always use &amp;amp;#8743; for and, and &amp;amp;#8744; for or, but the data folk might shoot us :-).  Actually we could consider ^ to mean and, paired with | &lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC[TYPE=Foo^!TYPE=Bar|TYPE=Goo]|QUALIFIED^!PC&lt;br /&gt;
&lt;br /&gt;
::...allows a choice of:&lt;br /&gt;
::(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
::OR&lt;br /&gt;
::(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
:I think I prefer the last one, but I don't like the way | looks against ].  On this wiki ! is hard to distinguish from |, ¬ (shift ` on my keyboard) actually means not.  I think using « and » in place of [ and ], and ¬ for not&lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC«TYPE=Foo^¬TYPE=Bar|TYPE=Goo»|QUALIFIED^¬PC&lt;br /&gt;
&lt;br /&gt;
:is easier to read but that might be a bit radical.  Perhaps it's time we has that full reserved characters discussion.&lt;br /&gt;
:*Very true since we don't seem to have a full list (see above in option 3 about standards vs. actually allowed)--[[User:Michael W. Fender|Fluxxdog]] 23:58, 4 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
*I'd like to move away from symbolism for words and actually use the words themselves.  It makes it a lot easier for new people to read.--[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Using '«' and '»' is a good idea, but how exactly do you type that in?  I think we should stick closer to what's available on the common keyboards without having to dig through a font list.  Although, that gives me an idea...  What about a character combinations?&lt;br /&gt;
&lt;br /&gt;
:* [[User:Nuance|nuance]] Sorry if it was a bit opaque, but I gave instructions for how to type it (on a windows machine at least).  Press and hold the &amp;quot;alt&amp;quot; key to the left of your space bar.  Now, using the numeric keypad, type the numbers 0171, realease the &amp;quot;alt&amp;quot; key.  Et viola «.  » is similarly produced with the numbers 0187.  Once you have one of them cut and paste is also an option.  Since we aren't fully in the unicode realm here, most OSes have some way to type characters in the ios-8859-1 range.&lt;br /&gt;
::*I'm not saying it's a bad idea, I'm saying it's not a good idea.  People will have to look into some kind of &amp;quot;tips and tricks&amp;quot; for their keyboard AND OS AND language AND font, since not every combination will work like that.  Heck, tested it on 3 different programs on my system and it doesn't work at all.  I think this is definitely a case of &amp;quot;the simpler the better&amp;quot;.--[[User:Michael W. Fender|Fluxxdog]] 23:58, 4 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
::: [http://en.wikipedia.org/wiki/Guillemets#Typing_.22.C2.AB.22_and_.22.C2.BB.22_on_computers| Typing the Guilemets « »]&lt;br /&gt;
&lt;br /&gt;
:Hey coders!  Could we do something along the lines of &amp;lt;&amp;lt;and&amp;gt;&amp;gt;?  Using 2 '&amp;lt;' to signify a logical operator?  Surely that must make things easier. -[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
:* Really doesn't make a huge difference.  The &amp;lt; and &amp;gt; still aren't identified as reserved characters.  It reduces the risk slightly, but it's probably small with &amp;lt;AND&amp;gt; and &amp;lt;OR&amp;gt; anyway. - thpr&lt;br /&gt;
&lt;br /&gt;
Insert comments on option #4 here.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1427</id>
		<title>Separator Characters</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1427"/>
		<updated>2009-04-04T21:36:56Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
There is an issue as far as long-term consistency for the use of characters to represent logical &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This document uses CHOOSE:TEMPLATE (since it doesn't exist) as an example.  For additional CHOOSE tokens and proposals, you can see [[Architecture Changes 5.17]]&lt;br /&gt;
&lt;br /&gt;
To readers: Please add additional options if you have additional ideas.  You may find the [[Data LST Standards]] useful to look at reserved characters.&lt;br /&gt;
&lt;br /&gt;
==Option #1, Using Pipe as an OR separator, Using Comma as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1|Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo|!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]|QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]|QUALIFIED,!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* Note that this is the existing syntax used in the CHOOSE proposals as they are shown on the Wiki. [TRP]&lt;br /&gt;
* Showing this syntax to a few non coders it definitely wasn't instinctively clear that ',' was an AND symbol.  However, '|' was instinctively picked up as an OR symbol [[User:Karianna|karianna]] 18:59, 1 April 2009 (CEST)&lt;br /&gt;
* Part of that is that the pipe '|' just seems to break that attention naturally, which is why it works so well as a subtoken separator.  But I think we should move away from giving two jobs to the same thing.--[[User:Michael W. Fender|Fluxxdog]] 01:12, 2 April 2009 (CEST)&lt;br /&gt;
Insert comments on option #1 here.&lt;br /&gt;
&lt;br /&gt;
==Option #2, Using Comma as an OR separator, Using Ampersand as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1,Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;amp;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&amp;amp;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo],QUALIFIED&amp;amp;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
*I think this is a problem, as ampersand is not a reserved character in PCGen. This is used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  Therefore, in order to implement this properly, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16).  While I think this is a nice idea, I think the hurdle is too large to do this quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
Insert other comments on option #2 here.  &lt;br /&gt;
&lt;br /&gt;
==Option #3, Using &amp;lt;OR&amp;gt; as an OR separator, Using &amp;lt;AND&amp;gt; as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1&amp;lt;OR&amp;gt;Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&amp;lt;OR&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&amp;lt;AND&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&amp;lt;OR&amp;gt;QUALIFIED&amp;lt;AND&amp;gt;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* Note that the unicode discussion here was broken out into option #4. - thpr Apr 4&lt;br /&gt;
&lt;br /&gt;
*I Have a similar concern here to option #2, as we have not reserved &amp;lt; or &amp;gt; as restricted characters. &amp;lt; and &amp;gt; are used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  There is less risk of using (literally) &amp;lt;OR&amp;gt; or &amp;lt;AND&amp;gt;, which makes this somewhat safer than option #2.  However, this does introduce restrictions on data naming.  In order to implement this without risk, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16). I think the hurdle is too large to do the FREQ converter quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
*Do the characters '&amp;lt;' and '&amp;gt;' matter?  Are there other characters that can't be used in a key name that can be used for identifying a logical operator?  What about '$'?  Are there any characters that we cannot use whatsoever for this? --[[User:Michael W. Fender|Fluxxdog]] 04:03, 1 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
:* You may find the [[Data LST Standards]] useful to find reserved characters. &lt;br /&gt;
::*Not as helpful as you think.  This just lists what should and shouldn't be used in our releases, not what actually can and can't be used.  For example, we shouldn't use a backslash '\' but we can.&lt;br /&gt;
:::DEFINE:Spaced\Variable|0	BONUS:VAR|Spaced\Variable|3	DESC:Here's the value: %1|Spaced\Variable&lt;br /&gt;
:::...still spits out &amp;quot;''Here's the value: 3''&amp;quot;--[[User:Michael W. Fender|Fluxxdog]] 23:35, 4 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
* [nuance] I think the lower case version stands out better.&lt;br /&gt;
&lt;br /&gt;
:* I'll definitely agree with nuance on using lowercase for 'and' and 'or'.  Makes it so much more obvious.--[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
::* I happen to prefer the uppercase versions.  - thpr&amp;lt;br&amp;gt;&lt;br /&gt;
:::One needs to consider also that these will often be used with Primitive objects, e.g.:&amp;lt;br&amp;gt;&lt;br /&gt;
:::CHOOSE:TEMPLATE|Extra Weaponry&amp;lt;or&amp;gt;Extra Appendage&amp;lt;or&amp;gt;Extra Flavor&amp;lt;or&amp;gt;Candle Power&amp;lt;or&amp;gt;Super Eyesight&amp;lt;br&amp;gt;&lt;br /&gt;
:::CHOOSE:TEMPLATE|Extra Weaponry&amp;lt;OR&amp;gt;Extra Appendage&amp;lt;OR&amp;gt;Extra Flavor&amp;lt;OR&amp;gt;Candle Power&amp;lt;OR&amp;gt;Super Eyesight&amp;lt;br&amp;gt;&lt;br /&gt;
:::... so I feel that the upper case keyword is far more consistent with our tokens (where the keywords like TEMPLATE, TYPE, etc. are all upper case) and also stand out more.&lt;br /&gt;
:::*How dare you use logic!  ^^  But yeah, when you put it that way, we should stick to the standard of using CAPS for hardcoded words.--[[User:Michael W. Fender|Fluxxdog]] 23:35, 4 April 2009 (CEST)&lt;br /&gt;
Insert comments on option #3 here.&lt;br /&gt;
&lt;br /&gt;
==Option #4, Leverage Unicode to use other separators, e.g. «OR» as an OR separator, Using «AND» as an AND separator==&lt;br /&gt;
&lt;br /&gt;
Examples use lowercase&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1«or»Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo«or»!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo«and»!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«or»!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar«or»TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«or»!TYPE=Bar]«or»QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar]«and»QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar«or»TYPE=Goo]«or»QUALIFIED«and»!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* [nuance] LST files are UTF8, so theoretically we can use any unicode character.  The problem with that is editor support—which it has to be said is getting better all the time.  Since full unicde may be a bit of a shock , iso-8859-1 (latin 1) has « and » (alt0171 and alt0187 respectively).  It also has ¿ (alt0191) which ties up nicely with ? if was want to wrap words.&lt;br /&gt;
&lt;br /&gt;
:Of course, fully in the realm of unicode madness, we could always use &amp;amp;#8743; for and, and &amp;amp;#8744; for or, but the data folk might shoot us :-).  Actually we could consider ^ to mean and, paired with | &lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC[TYPE=Foo^!TYPE=Bar|TYPE=Goo]|QUALIFIED^!PC&lt;br /&gt;
&lt;br /&gt;
::...allows a choice of:&lt;br /&gt;
::(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
::OR&lt;br /&gt;
::(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
:I think I prefer the last one, but I don't like the way | looks against ].  On this wiki ! is hard to distinguish from |, ¬ (shift ` on my keyboard) actually means not.  I think using « and » in place of [ and ], and ¬ for not&lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC«TYPE=Foo^¬TYPE=Bar|TYPE=Goo»|QUALIFIED^¬PC&lt;br /&gt;
&lt;br /&gt;
:is easier to read but that might be a bit radical.  Perhaps it's time we has that full reserved characters discussion.&lt;br /&gt;
&lt;br /&gt;
*I'd like to move away from symbolism for words and actually use the words themselves.  It makes it a lot easier for new people to read.--[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Using '«' and '»' is a good idea, but how exactly do you type that in?  I think we should stick closer to what's available on the common keyboards without having to dig through a font list.  Although, that gives me an idea...  What about a character combinations?&lt;br /&gt;
&lt;br /&gt;
:: [[User:Nuance|nuance]] Sorry if it was a bit opaque, but I gave instructions for how to type it (on a windows machine at least).  Press and hold the &amp;quot;alt&amp;quot; key to the left of your space bar.  Now, using the numeric keypad, type the numbers 0171, realease the &amp;quot;alt&amp;quot; key.  Et viola «.  » is similarly produced with the numbers 0187.  Once you have one of them cut and paste is also an option.  Since we aren't fully in the unicode realm here, most OSes have some way to type characters in the ios-8859-1 range.&lt;br /&gt;
&lt;br /&gt;
:Hey coders!  Could we do something along the lines of &amp;lt;&amp;lt;and&amp;gt;&amp;gt;?  Using 2 '&amp;lt;' to signify a logical operator?  Surely that must make things easier. -[[User:Michael W. Fender|Fluxxdog]] 01:08, 2 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
:* Really doesn't make a huge difference.  The &amp;lt; and &amp;gt; still aren't identified as reserved characters.  It reduces the risk slightly, but it's probably small with &amp;lt;AND&amp;gt; and &amp;lt;OR&amp;gt; anyway. - thpr&lt;br /&gt;
&lt;br /&gt;
Insert comments on option #4 here.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1388</id>
		<title>Separator Characters</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Separator_Characters&amp;diff=1388"/>
		<updated>2009-04-01T18:18:39Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
There is an issue as far as long-term consistency for the use of characters to represent logical &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This document uses CHOOSE:TEMPLATE (since it doesn't exist) as an example.  For additional CHOOSE tokens and proposals, you can see [[Architecture Changes 5.17]]&lt;br /&gt;
&lt;br /&gt;
To readers: Please add additional options if you have additional ideas.  You may find the [[Data LST Standards]] useful to look at reserved characters.&lt;br /&gt;
&lt;br /&gt;
==Option #1, Using Pipe as an OR separator, Using Comma as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1|Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo|!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo|!TYPE=Bar]|QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar|TYPE=Goo]|QUALIFIED,!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
* Note that this is the existing syntax used in the CHOOSE proposals as they are shown on the Wiki. [TRP]&lt;br /&gt;
* Showing this syntax to a few non coders it definitely wasn't instinctively clear that ',' was an AND symbol.  However, '|' was instinctively picked up as an OR symbol [[User:Karianna|karianna]] 18:59, 1 April 2009 (CEST)&lt;br /&gt;
Insert comments on option #1 here.&lt;br /&gt;
&lt;br /&gt;
==Option #2, Using Comma as an OR separator, Using Ampersand as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1,Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo,!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;amp;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo,!TYPE=Bar],QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar]&amp;amp;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;amp;!TYPE=Bar,TYPE=Goo],QUALIFIED&amp;amp;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
*I think this is a problem, as ampersand is not a reserved character in PCGen. This is used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  Therefore, in order to implement this properly, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16).  While I think this is a nice idea, I think the hurdle is too large to do this quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
Insert other comments on option #2 here.  &lt;br /&gt;
&lt;br /&gt;
==Option #3, Using &amp;lt;OR&amp;gt; as an OR separator, Using &amp;lt;AND&amp;gt; as an AND separator==&lt;br /&gt;
&lt;br /&gt;
===Using Primitives===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|Template1&amp;lt;OR&amp;gt;Template2&lt;br /&gt;
&lt;br /&gt;
...allows a choice of Template1 or Template2&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
===Using Single a Qualifier===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of any Template that the character already has, where the Template is (a) both TYPE=Foo and not TYPE=Bar OR (b) TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
===Using Multiple Qualifiers===&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;OR&amp;gt;!TYPE=Bar]&amp;lt;OR&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of&lt;br /&gt;
(a) Any Template that the character already has, where the Template is either TYPE=Foo or not TYPE=Bar&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar]&amp;lt;AND&amp;gt;QUALIFIED[TYPE=Goo]&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is both TYPE=Foo and not TYPE=Bar&lt;br /&gt;
AND&lt;br /&gt;
(b) Any Template the PC is qualified to take that is TYPE=Goo&lt;br /&gt;
&lt;br /&gt;
CHOOSE:TEMPLATE|PC[TYPE=Foo&amp;lt;AND&amp;gt;!TYPE=Bar&amp;lt;OR&amp;gt;TYPE=Goo]&amp;lt;OR&amp;gt;QUALIFIED&amp;lt;AND&amp;gt;!PC&lt;br /&gt;
&lt;br /&gt;
...allows a choice of:&lt;br /&gt;
(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
OR&lt;br /&gt;
(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
===Discussion===&lt;br /&gt;
&lt;br /&gt;
*I Have a similar concern here to option #2, as we have not reserved &amp;lt; or &amp;gt; as restricted characters. &amp;lt; and &amp;gt; are used in actual data that we ship, and thus we would expect homebrews to feel this character is also legal.  There is less risk of using (literally) &amp;lt;OR&amp;gt; or &amp;lt;AND&amp;gt;, which makes this somewhat safer than option #2.  However, this does introduce restrictions on data naming.  In order to implement this without risk, we end up having to have a Data Converter, as this will break existing PCs. (which is the open FREQ, not the item completed for 5.16). I think the hurdle is too large to do the FREQ converter quickly. [TRP]&lt;br /&gt;
&lt;br /&gt;
*Do the characters '&amp;lt;' and '&amp;gt;' matter?  Are there other characters that can't be used in a key name that can be used for identifying a logical operator?  What about '$'?  Are there any characters that we cannot use whatsoever for this? --[[User:Michael W. Fender|Fluxxdog]] 04:03, 1 April 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
* [nuance] LST files are UTF8, so theoretically we can use any unicode character.  The problem with that is editor support—which it has to be said is getting better all the time.  Since full unicde may be a bit of a shock , iso-8859-1 (latin 1) has « and » (alt0171 and alt0187 respectively).  It also has ¿ (alt0191) which ties up nicely with ? if was want to wrap words.&lt;br /&gt;
&lt;br /&gt;
:grabbing a random example:&lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC[TYPE=Foo«AND»!TYPE=Bar«OR»TYPE=Goo]«OR»QUALIFIED«AND»!PC&lt;br /&gt;
&lt;br /&gt;
:I think the lower case version stands out better.&lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC[TYPE=Foo«and»!TYPE=Bar«or»TYPE=Goo]«or»QUALIFIED«and»!PC&lt;br /&gt;
&lt;br /&gt;
:Of course, fully in the realm of unicode madness, we could always use &amp;amp;#8743; for and, and &amp;amp;#8744; for or, but the data folk might shoot us :-).  Actually we could consider ^ to mean and, paired with | &lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC[TYPE=Foo^!TYPE=Bar|TYPE=Goo]|QUALIFIED^!PC&lt;br /&gt;
&lt;br /&gt;
::...allows a choice of:&lt;br /&gt;
::(a) Any Template that the character already has, where the Template is (a1) both TYPE=Foo and not TYPE=Bar OR (a2) TYPE=Goo&lt;br /&gt;
::OR&lt;br /&gt;
::(b) Any Template that the PC is qualified to take, but has not yet taken.&lt;br /&gt;
&lt;br /&gt;
:I think I prefer the last one, but I don't like the way | looks aginst ].  On this wiki ! is hard to distimguish from |, ¬ (shift ` on my keyboard) actually means not.  I think using « and » in place of [ and ], and ¬ for not&lt;br /&gt;
&lt;br /&gt;
::CHOOSE:TEMPLATE|PC«TYPE=Foo^¬TYPE=Bar|TYPE=Goo»|QUALIFIED^¬PC&lt;br /&gt;
&lt;br /&gt;
:is easier to read but that might be a bit radical.  Perhaps it's time we has that full reserved characters discussion.&lt;br /&gt;
&lt;br /&gt;
Insert comments on option #3 here.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=CDOM_References_Concept_Document&amp;diff=1387</id>
		<title>CDOM References Concept Document</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=CDOM_References_Concept_Document&amp;diff=1387"/>
		<updated>2009-04-01T17:16:26Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
CDOM References are effectively pointers to CDOM Objects.  A Single reference directly refers to a single object (something like referring to the Feat Dodge), and it follows very closely the pointer analogy. Group references, which can be refer to multiple objects (something like TYPE=Foo) effectively serve as a pointer to a group of one or more objects.&lt;br /&gt;
&lt;br /&gt;
CDOM References are created and are aware of their underlying contents during the load of PCC/LST files, and with some minor exceptions, are not dynamic (meaning they do not change at runtime).&lt;br /&gt;
&lt;br /&gt;
CDOM Reference objects can be found in the pcgen.cdom.reference package.&lt;br /&gt;
&lt;br /&gt;
==Types of References==&lt;br /&gt;
&lt;br /&gt;
===Simple References===&lt;br /&gt;
&lt;br /&gt;
Simple References are references that refer to non-categorized objects.  This includes most CDOM Objects within PCGen; the major exception is Ability objects, which are Categorized.  A Simple Reference cannot refer to a Categorized CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Categorized References===&lt;br /&gt;
&lt;br /&gt;
Categorized References are references that refer to categorized objects.  This includes Ability objects.  A Categorized CDOM Object cannot refer to a Simple CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Single References===&lt;br /&gt;
&lt;br /&gt;
Simple references refer to a single object.  These can be resolved during runtime to return the underlying CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Group References===&lt;br /&gt;
&lt;br /&gt;
Group referenfes refer to one or more objects.  These can share various characteristics, such as a TYPE, or be universal for a given type of object by using the ANY reference.  In limited cases, pattern matching references are also available.&lt;br /&gt;
&lt;br /&gt;
===Transparent References===&lt;br /&gt;
&lt;br /&gt;
Game Mode and PCC files are loaded when PCGen is launched.  When these files refer to objects that would be loaded with future data, a Transparent Reference is created.  These are special references that can be loaded multiple times (vs. other References that cannot be loaded more than once).&lt;br /&gt;
&lt;br /&gt;
===Direct References===&lt;br /&gt;
&lt;br /&gt;
References are used in multiple ways:&lt;br /&gt;
&lt;br /&gt;
# A Reference can be used directly: References can be stored in ListKey or ObjectKey locations within a CDOM Object.&lt;br /&gt;
# A Reference can be used as an index: i.e. referring to a list of objects, such as the reference constructed from the CLASSES token in the Spell LST file referring to ClassSpellLists.&lt;br /&gt;
&lt;br /&gt;
However, there is one infrastructure to support lists, and those lists may be either static or unconstructed at LST load.  The static references are known lists, yet in order to share infrastructure with unknown lists, even the known lists have to be wrapped in a CDOM Reference. For this reason, there is the ability to create Direct References. These CDOM References do not require resolution, as they are passed the single CDOM Object they will contain at the time the Direct Reference is constructed.&lt;br /&gt;
&lt;br /&gt;
==Lifecycle of a Reference==&lt;br /&gt;
&lt;br /&gt;
# Transparent Reference Creation: Game Mode and PCC files are loaded when PCGen is launched.  When these files refer to objects that would be loaded with future data, a Transparent Reference is created.  References are constructed by a Game Mode-based LoadContext, so that multiple references to an object of the same Class and Key will use the same Reference.&lt;br /&gt;
# Reference Creation: When LST files are loaded, and CDOM Objects are referred to in the data, a CDOM Reference is created.  References are constructed by the LoadContext, so that multiple references to an object of the same Class and Key will use the same Reference.&lt;br /&gt;
# Disposal on FORGET: LST files allow certain objects to be &amp;quot;forgotten&amp;quot;, meaning they are disposed of from the loaded data, and cannot be used at runtime.  However, given that the LST load process is single-pass, the FORGET is encountered well after References have been created for objects that were referred to by the forgotten object.  Since the object is not loaded, it is appropriate to ignore any of those references, so the Token/Loader system includes a mechanism to dispose of those CDOM References when a FORGET is encountered.&lt;br /&gt;
# Loading of References (Runtime): If the LST load occurred in support of runtime processing of characters, loading is performed.  This is not done if the LST load was performed in support of the editor system (not yet performed in PCGen 5.16). Once load of the data is complete, References are resolved.  For Single References, this involves loading the Reference with the object it refers to.  For deterministic Group References, this also involves loading with References.  Some Group References are processed dynamically, meaning their contents are determined at runtime.&lt;br /&gt;
# Resolution (Runtime):  If the LST load occurred in support of runtime processing of characters, loading is performed.  This is not done if the LST load was performed in support of the editor system (not yet performed in PCGen 5.16). When a PlayerCharacter is being processed, the various CDOM References are resolved to determine the objects underlying the CDOM Reference.&lt;br /&gt;
# Write: Objects may be written back to an LST file from a CDOM References, and each CDOMReference has a getLSTformat() method that provides the unique method of identifying the reference that can be stored in a persistent state (in an LST file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The Origin of References==&lt;br /&gt;
&lt;br /&gt;
===Background Concepts===&lt;br /&gt;
&lt;br /&gt;
Keys: Objects (such as Races, Languages, etc.) which are loaded from LST files need to have a unique identifier so that relationships between objects can be created without ambiguity.&lt;br /&gt;
&lt;br /&gt;
Category: In addition to a Key, Ability objects also have another part of their unique identifier, called a Category.  This is usage #1 of Ability Categories, see the [[Ability Category]] explanation.&lt;br /&gt;
&lt;br /&gt;
===The Challenge===&lt;br /&gt;
&lt;br /&gt;
When data is loaded from PCC/LST files, there is an order of operations challenge.  (For any developers, this is similar to challenges that a compiler faces when compiling source code).  &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
# Objects can reference each other (e.g. a Race settings available starting Languages).  This is a challenge because circular references are likely (such as a restriction on the language to limit it to the particular Race that allows it as a starting Language)&lt;br /&gt;
# Objects can use KEY and CATEGORY anywhere on a given line.  This creates an (intra-line) indexing challenge that exacerbates the circular reference problem and increases the difficulty of resolving that issue.&lt;br /&gt;
&lt;br /&gt;
Additionally, since the purpose with the transition to the CDOM design is to support an integrated LST Editor that shares a load framework with the runtime environment&lt;br /&gt;
&lt;br /&gt;
# CDOM References must support a round-robin to LST files.  This means that group references (e.g. TYPE=Foo) must know the reference name and not universally expand to their contained components (yet must be able to return the contained components at runtime).  &lt;br /&gt;
# Sorting of CDOMReferences must be deterministic (PCGen 5.16 solves this by alphabetizing the lists of CDOMReferences in the tokens)&lt;br /&gt;
&lt;br /&gt;
===The Solution in PCGen 5.16===&lt;br /&gt;
&lt;br /&gt;
In order to keep the data structured in a way that keeps information stored in a location close to where it is addressed in the rules, addressing the order of operations challenges is a code issue, not a data structure issue.&lt;br /&gt;
&lt;br /&gt;
In PCGen 5.14 and earlier, this problem was solved by storing information within PCGen as Strings, and then resolving those Strings against unique identifiers for each object (generally the Key).  This led to a number of issues, including performance issues due to String parsing, as well as failure to catch some errors until runtime.&lt;br /&gt;
&lt;br /&gt;
There are various potential solutions to such problems, and some of these are covered in [[Rebuild of the Token/Loader System]]. These were addressed in PCGen with the integration of a new Token/Loader system during the PCGen 5.16 cycle.  While there are solutions that would drive a two-pass parse of the data, the solution implemented in PCGen 5.16 limits the load of data to a single pass on the LST files.  Thus PCGen uses a series of references to allow the data at LST load to refer to objects which have not been encountered within the data.  After the load is complete, the references are resolved to their underlying objects.&lt;br /&gt;
&lt;br /&gt;
===Benefits of the defined solution===&lt;br /&gt;
&lt;br /&gt;
# Duplicate keys are detected at load, regardless of their source file, thus no references should be ambiguous&lt;br /&gt;
# Empty Group references can flag a warning if they do not contain any contents.  This serves as LST error checking to catch accidental typos in a group identifier&lt;br /&gt;
# Since References can be constructed well before they are resolved, references allow Game Mode information to be loaded once, thus preventing re-parsing of those files when a different set of sources is loaded.&lt;br /&gt;
&lt;br /&gt;
===Characteristics/Weaknesses of the defined solution===&lt;br /&gt;
&lt;br /&gt;
This section refers to PCGen 5.16&lt;br /&gt;
&lt;br /&gt;
# Currently, the LoadContext system uses WeakReferences to control the Disposal of CDOM Reference objects when FORGET is encountered.  In theory this does not guarantee that irrelevant CDOM Reference objects do not produce load errors due to missing information.  In practice, this error is unlikely to be encountered.  However, an ideal structure would design around this problem.  This issue is partially a function of the method of storage used in PCGen 5.16 (the Graph structure envisioned for CDOM is not in place), and partially a function of using a one-pass load.  There are multiple solutions to this problem, but since it's mostly a theoretical issue, it is not being addressed as a critical issue.&lt;br /&gt;
# Currently, BONUS, CHOOSE, and the PRExxx tokens have not been converted to the new Token/Loader system and do not yet provide all of the benefits outlined above.  A CHOOSE rebuild has been proposed as part of the PCGen 5.17 cycle (which leads to the next stable release, either 5.18 or 6.0).&lt;br /&gt;
# Currently CDOM References are classes and are not provided into CDOM Objects as an Interface.  In order to reduce potential for corruption of CDOMReferences, the single references are controlled to allow them to only be resolved once.  This is done without providing a method for resetting a CDOM Reference.  This is done to provide a strict mechanism to prevent errors and abuse of the CDOM Reference objects during runtime (this can be thought of as a short-term overly strict system to train developers and force separation between load and runtime).  Once we have a more stable and modular core in place, this strict mechanism may be relaxed and/or exchanged for interfaces.  Currently, this strict mechanism makes Game Mode references slightly more complex than other references.&lt;br /&gt;
# Some References are resolved at runtime.  Theoretically, this is a performance issue, but practically, the dynamic references are rare enough that this is not an issue.  The core of PCGen has much larger performance issues that should be addressed first before this is addressed as a performance issue.  It may turn out to be unnecessary optimization, so addressing this weakness is currently not scheduled for any release.&lt;br /&gt;
# Resolution may be an issue.  This is mostly a theoretical issue at this point, but the dereferencing driven by the use of CDOM Reference objects is slightly slower than direct objects.  This is considered a minor performance issue, and unless demonstrated as a performance issue, will not be addressed.  There are some concerns about references in relation to lists (such as adding Spells to a ClassSpellList) and the complexity required to access the underlying information.  While this is a recognized issue, this pain point will be addressed in a near-future release as the PlayerCharacter data structure is changed to a Graph-based structure.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=CDOM_References_Concept_Document&amp;diff=1386</id>
		<title>CDOM References Concept Document</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=CDOM_References_Concept_Document&amp;diff=1386"/>
		<updated>2009-04-01T17:12:03Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
CDOM References are effectively pointers to CDOM Objects.  A Single reference directly refers to a single object (something like referring to the Feat Dodge), and it follows very closely the pointer analogy. Group references, which can be refer to multiple objects (something like TYPE=Foo) effectively serve as a pointer to a group of one or more objects.&lt;br /&gt;
&lt;br /&gt;
CDOM References are created and are aware of their underlying contents during the load of PCC/LST files, and with some minor exceptions, are not dynamic (meaning they do not change at runtime).&lt;br /&gt;
&lt;br /&gt;
CDOM Reference objects can be found in the pcgen.cdom.reference package.&lt;br /&gt;
&lt;br /&gt;
==Types of References==&lt;br /&gt;
&lt;br /&gt;
===Simple References===&lt;br /&gt;
&lt;br /&gt;
Simple References are references that refer to non-categorized objects.  This includes most CDOM Objects within PCGen; the major exception is Ability objects, which are Categorized.  A Simple Reference cannot refer to a Categorized CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Categorized References===&lt;br /&gt;
&lt;br /&gt;
Categorized References are references that refer to categorized objects.  This includes Ability objects.  A Categorized CDOM Object cannot refer to a Simple CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Single References===&lt;br /&gt;
&lt;br /&gt;
Simple references refer to a single object.  These can be resolved during runtime to return the underlying CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Group References===&lt;br /&gt;
&lt;br /&gt;
Group referenfes refer to one or more objects.  These can share various characteristics, such as a TYPE, or be universal for a given type of object by using the ANY reference.  In limited cases, pattern matching references are also available.&lt;br /&gt;
&lt;br /&gt;
===Transparent References===&lt;br /&gt;
&lt;br /&gt;
Game Mode and PCC files are loaded when PCGen is launched.  When these files refer to objects that would be loaded with future data, a Transparent Reference is created.  These are special references that can be loaded multiple times (vs. other References that cannot be loaded more than once).&lt;br /&gt;
&lt;br /&gt;
===Direct References===&lt;br /&gt;
&lt;br /&gt;
References are used in multiple ways:&lt;br /&gt;
&lt;br /&gt;
# A Reference can be used directly: References can be stored in ListKey or ObjectKey locations within a CDOM Object.&lt;br /&gt;
# A Reference can be used as an index: i.e. referring to a list of objects, such as the reference constructed from the CLASSES token in the Spell LST file referring to ClassSpellLists.&lt;br /&gt;
&lt;br /&gt;
However, there is one infrastructure to support lists, and those lists may be either static or unconstructed at LST load.  The static references are known lists, yet in order to share infrastructure with unknown lists, even the known lists have to be wrapped in a CDOM Reference. For this reason, there is the ability to create Direct References. These CDOM References do not require resolution, as they are passed the single CDOM Object they will contain at the time the Direct Reference is constructed.&lt;br /&gt;
&lt;br /&gt;
==Lifecycle of a Reference==&lt;br /&gt;
&lt;br /&gt;
# Transparent Reference Creation: Game Mode and PCC files are loaded when PCGen is launched.  When these files refer to objects that would be loaded with future data, a Transparent Reference is created.  References are constructed by a Game Mode-based LoadContext, so that multiple references to an object of the same Class and Key will use the same Reference.&lt;br /&gt;
# Reference Creation: When LST files are loaded, and CDOM Objects are referred to in the data, a CDOM Reference is created.  References are constructed by the LoadContext, so that multiple references to an object of the same Class and Key will use the same Reference.&lt;br /&gt;
# Disposal on FORGET: LST files allow certain objects to be &amp;quot;forgotten&amp;quot;, meaning they are disposed of from the loaded data, and cannot be used at runtime.  However, given that the LST load process is single-pass, the FORGET is encountered well after References have been created for objects that were referred to by the forgotten object.  Since the object is not loaded, it is appropriate to ignore any of those references, so the Token/Loader system includes a mechanism to dispose of those CDOM References when a FORGET is encountered.&lt;br /&gt;
# Loading of References (Runtime): If the LST load occurred in support of runtime processing of characters, loading is performed.  This is not done if the LST load was performed in support of the editor system (not yet performed in PCGen 5.16). Once load of the data is complete, References are resolved.  For Single References, this involves loading the Reference with the object it refers to.  For deterministic Group References, this also involves loading with References.  Some Group References are processed dynamically, meaning their contents are determined at runtime.&lt;br /&gt;
# Resolution (Runtime):  If the LST load occurred in support of runtime processing of characters, loading is performed.  This is not done if the LST load was performed in support of the editor system (not yet performed in PCGen 5.16). When a PlayerCharacter is being processed, the various CDOM References are resolved to determine the objects underlying the CDOM Reference.&lt;br /&gt;
# Write: Objects may be written back to an LST file from a CDOM References, and each CDOMReference has a getLSTformat() method that provides the unique method of identifying the reference that can be stored in a persistent state (in an LST file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The Origin of References==&lt;br /&gt;
&lt;br /&gt;
===Background Concepts===&lt;br /&gt;
&lt;br /&gt;
Keys: Objects (such as Races, Languages, etc.) which are loaded from LST files need to have a unique identifier so that relationships between objects can be created without ambiguity.&lt;br /&gt;
&lt;br /&gt;
Category: In addition to a Key, Ability objects also have another part of their unique identifier, called a Category.  This is usage #1 of Ability Categories, see the [[Ability Category]] explanation.&lt;br /&gt;
&lt;br /&gt;
===The Challenge===&lt;br /&gt;
&lt;br /&gt;
When data is loaded from PCC/LST files, there is an order of operations challenge.  (For any developers, this is similar to challenges that a compiler faces when compiling source code).  &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
# Objects can reference each other (e.g. a Race settings available starting Languages).  This is a challenge because circular references are likely (such as a restriction on the language to limit it to the particular Race that allows it as a starting Language)&lt;br /&gt;
# Objects can use KEY and CATEGORY anywhere on a given line.  This creates an (intra-line) indexing challenge that exacerbates the circular reference problem and increases the difficulty of resolving that issue.&lt;br /&gt;
&lt;br /&gt;
Additionally, since the purpose with the transition to the CDOM design is to support an integrated LST Editor that shares a load framework with the runtime environment&lt;br /&gt;
&lt;br /&gt;
# CDOM References must support a round-robin to LST files.  This means that group references (e.g. TYPE=Foo) must know the reference name and not universally expand to their contained components (yet must be able to return the contained components at runtime).  &lt;br /&gt;
# Sorting of CDOMReferences must be deterministic (PCGen 5.16 solves this by alphabetizing the lists of CDOMReferences in the tokens)&lt;br /&gt;
&lt;br /&gt;
===The Solution in PCGen 5.16===&lt;br /&gt;
&lt;br /&gt;
In order to keep the data structured in a way that keeps information stored in a location close to where it is addressed in the rules, addressing the order of operations challenges is a code issue, not a data structure issue.&lt;br /&gt;
&lt;br /&gt;
In PCGen 5.14 and earlier, this problem was solved by storing information within PCGen as Strings, and then resolving those Strings against unique identifiers for each object (generally the Key).  This led to a number of issues, including performance issues due to String parsing, as well as failure to catch some errors until runtime.&lt;br /&gt;
&lt;br /&gt;
There are various potential solutions to such problems, and some of these are covered in [[Rebuild of the Token/Loader System]]. These were addressed in PCGen with the integration of a new Token/Loader system during the PCGen 5.16 cycle.  While there are solutions that would drive a two-pass parse of the data, the solution implemented in PCGen 5.16 limits the load of data to a single pass on the LST files.  Thus PCGen uses a series of references to allow the data at LST load to refer to objects which have not been encountered within the data.  After the load is complete, the references are resolved to their underlying objects.&lt;br /&gt;
&lt;br /&gt;
===Benefits of the defined solution===&lt;br /&gt;
&lt;br /&gt;
# Duplicate keys are detected at load, regardless of their source file, thus no references should be ambiguous&lt;br /&gt;
# Empty Group references can flag a warning if they do not contain any contents.  This serves as LST error checking to catch accidental typos in a group identifier&lt;br /&gt;
# Since References can be constructed well before they are resolved, references allow Game Mode information to be loaded once, thus preventing re-parsing of those files when a different set of sources is loaded.&lt;br /&gt;
&lt;br /&gt;
===Characteristics/Weaknesses of the defined solution===&lt;br /&gt;
&lt;br /&gt;
This section refers to PCGen 5.16&lt;br /&gt;
&lt;br /&gt;
# Currently, the LoadContext system uses WeakReferences to control the Disposal of CDOM Reference objects when FORGET is encountered.  In theory this does not guarantee that irrelevant CDOM Reference objects do not produce load errors due to missing information.  In practice, this error is unlikely to be encountered.  However, an ideal structure would design around this problem.  This issue is partially a function of the method of storage used in PCGen 5.16 (the Graph structure envisioned for CDOM is not in place), and partially a function of using a one-pass load.  There are multiple solutions to this problem, but since it's mostly a theoretical issue, it is not being addressed as a critical issue.&lt;br /&gt;
# Currently, BONUS, CHOOSE, and the PRExxx tokens have not been converted to the new Token/Loader system and do not yet provide all of the benefits outlined above.  A CHOOSE rebuild has been proposed as part of the PCGen 5.17 cycle (which leads to the next stable release, either 5.18 or 6.0).&lt;br /&gt;
# Currently CDOM References are classes and are not provided into CDOM Objects as an Interface.  In order to reduce potential for corruption of CDOMReferences, the single references are controlled to allow them to only be resolved once.  This is done without providing a method for resetting a CDOM Reference.  This is done to provide a strict mechanism to prevent errors and abuse of the CDOM Reference objects during runtime (this can be thought of as a short-term overly strict system to train developers and force separation between load and runtime).  Once we have a more stable and modular core in place, this strict mechanism may be relaxed and/or exchanged for interfaces.  Currently, this strict mechanism makes Game Mode references slightly more complex than other references.&lt;br /&gt;
# Some References are resolved at runtime.  Theoretically, this is a performance issue, but practically, the dynamic references are rare enough that this is not an issue.  The core of PCGen has much larger performance issues that should be addressed first before this is addressed as a performance issue.  It may turn out to be unnecessary optimization, so addressing this weakness is currently not scheduled for any release.&lt;br /&gt;
# Resolution may be an issue.  This mostly a theoretical issue at this point, but the dereferencing driven by the use of CDOM Reference objects is slightly slower than direct objects.  This is considered a minor performance issue, and unless demonstrated as a performance issue, will not be addressed.  There are some concerns about references in relation to lists (such as adding Spells to a ClassSpellList) and the complexity required to access the underlying information.  While this is a recognized issue, this pain point will be addressed in a near-future release as the PlayerCharacter data structure is changed to a Graph-based structure.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=CDOM_References_Concept_Document&amp;diff=1384</id>
		<title>CDOM References Concept Document</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=CDOM_References_Concept_Document&amp;diff=1384"/>
		<updated>2009-04-01T16:38:11Z</updated>

		<summary type="html">&lt;p&gt;Nuance: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
CDOM References are effectively pointers to CDOM Objects.  A Single reference directly refers to a single object (something like referring to the Feat Dodge), and it follows very closely the pointer analogy. Group references, which can be refer to multiple objects (something like TYPE=Foo) effectively serve as a pointer to a group of one or more objects.&lt;br /&gt;
&lt;br /&gt;
CDOM References are created and are aware of their underlying contents during the load of PCC/LST files, and with some minor exceptions, are not dynamic (meaning they do not change at runtime).&lt;br /&gt;
&lt;br /&gt;
CDOM Reference objects can be found in the pcgen.cdom.reference package.&lt;br /&gt;
&lt;br /&gt;
==Types of References==&lt;br /&gt;
&lt;br /&gt;
===Simple References===&lt;br /&gt;
&lt;br /&gt;
Simple References are references that refer to non-categorized objects.  This includes most CDOM Objects within PCGen; the major exception is Ability objects, which are Categorized.  A Simple Reference cannot refer to a Categorized CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Categorized References===&lt;br /&gt;
&lt;br /&gt;
Categorized References are references that refer to categorized objects.  This includes Ability objects.  A Categorized CDOM Object cannot refer to a Simple CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Single References===&lt;br /&gt;
&lt;br /&gt;
Simple references refer to a single object.  These can be resolved during runtime to return the underlying CDOM Object.&lt;br /&gt;
&lt;br /&gt;
===Group References===&lt;br /&gt;
&lt;br /&gt;
Group referenfes refer to one or more objects.  These can share various characteristics, such as a TYPE, or be universal for a given type of object by using the ANY reference.  In limited cases, pattern matching references are also available.&lt;br /&gt;
&lt;br /&gt;
===Transparent References===&lt;br /&gt;
&lt;br /&gt;
Game Mode and PCC files are loaded when PCGen is launched.  When these files refer to objects that would be loaded with future data, a Transparent Reference is created.  These are special references that can be loaded multiple times (vs. other References that cannot be loaded more than once).&lt;br /&gt;
&lt;br /&gt;
===Direct References===&lt;br /&gt;
&lt;br /&gt;
References are used in multiple ways:&lt;br /&gt;
&lt;br /&gt;
# Reference can be directly used: References can be stored in ListKey or ObjectKey locations within a CDOM Object.&lt;br /&gt;
# References are used as an index: This is referring to a list of objects, such as the CLASSES token in the Spell LST file referring to ClassSpellLists.&lt;br /&gt;
&lt;br /&gt;
However, there is one infrastructure to support lists, and those lists may be either static or unconstructed at LST load.  The static references are known lists, yet in order to share infrastructure with unknown lists, even the known lists have to be wrapped in a CDOM Reference. For this reason, there is the ability to create Direct References. These CDOM References do not require resolution, as they are passed the single CDOM Object they will contain at the time the Direct Reference is constructed.&lt;br /&gt;
&lt;br /&gt;
==Lifecycle of a Reference==&lt;br /&gt;
&lt;br /&gt;
# Transparent Reference Creation: Game Mode and PCC files are loaded when PCGen is launched.  When these files refer to objects that would be loaded with future data, a Transparent Reference is created.  References are constructed by a Game Mode-based LoadContext, so that multiple references to an object of the same Class and Key will use the same Reference.&lt;br /&gt;
# Reference Creation: When LST files are loaded, and CDOM Objects are referred to in the data, a CDOM Reference is created.  References are constructed by the LoadContext, so that multiple references to an object of the same Class and Key will use the same Reference.&lt;br /&gt;
# Disposal on FORGET: LST files allow certain objects to be &amp;quot;forgotten&amp;quot;, meaning they are disposed of from the loaded data, and cannot be used at runtime.  However, given that the LST load process is single-pass, the FORGET is encountered well after References have been created for objects that were referred to by the forgotten object.  Since the object is not loaded, it is appropriate to ignore any of those references, so the Token/Loader system includes a mechanism to dispose of those CDOM References when a FORGET is encountered.&lt;br /&gt;
# Loading of References (Runtime): If the LST load occurred in support of runtime processing of characters, loading is performed.  This is not done if the LST load was performed in support of the editor system (not yet performed in PCGen 5.16). Once load of the data is complete, References are resolved.  For Single References, this involves loading the Reference with the object it refers to.  For deterministic Group References, this also involves loading with References.  Some Group References are processed dynamically, meaning their contents are determined at runtime.&lt;br /&gt;
# Resolution (Runtime):  If the LST load occurred in support of runtime processing of characters, loading is performed.  This is not done if the LST load was performed in support of the editor system (not yet performed in PCGen 5.16). When a PlayerCharacter is being processed, the various CDOM References are resolved to determine the objects underlying the CDOM Reference.&lt;br /&gt;
# Write: Objects may be written back to an LST file from a CDOM References, and each CDOMReference has a getLSTformat() method that provides the unique method of identifying the reference that can be stored in a persistent state (in an LST file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The Origin of References==&lt;br /&gt;
&lt;br /&gt;
===Background Concepts===&lt;br /&gt;
&lt;br /&gt;
Keys: Objects (such as Races, Languages, etc.) which are loaded from LST files need to have a unique identifier so that relationships between objects can be created without ambiguity.&lt;br /&gt;
&lt;br /&gt;
Category: In addition to a Key, Ability objects also have another part of their unique identifier, called a Category.  This is usage #1 of Ability Categories, see the [[Ability Category]] explanation.&lt;br /&gt;
&lt;br /&gt;
===The Challenge===&lt;br /&gt;
&lt;br /&gt;
When data is loaded from PCC/LST files, there is an order of operations challenge.  (For any developers, this is similar to challenges that a compiler faces when compiling source code).  &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
# Objects can reference each other (e.g. a Race settings available starting Languages).  This is a challenge because circular references are likely (such as a restriction on the language to limit it to the particular Race that allows it as a starting Language)&lt;br /&gt;
# Objects can use KEY and CATEGORY anywhere on a given line.  This creates an (intra-line) indexing challenge that exacerbates the circular reference problem and increases the difficulty of resolving that issue.&lt;br /&gt;
&lt;br /&gt;
Additionally, since the purpose with the transition to the CDOM design is to support an integrated LST Editor that shares a load framework with the runtime environment&lt;br /&gt;
&lt;br /&gt;
# CDOM References must support a round-robin to LST files.  This means that group references (e.g. TYPE=Foo) must know the reference name and not universally expand to their contained components (yet must be able to return the contained components at runtime).  &lt;br /&gt;
# Sorting of CDOMReferences must be deterministic (PCGen 5.16 solves this by alphabetizing the lists of CDOMReferences in the tokens)&lt;br /&gt;
&lt;br /&gt;
===The Solution in PCGen 5.16===&lt;br /&gt;
&lt;br /&gt;
In order to keep the data structured in a way that keeps information stored in a location close to where it is addressed in the rules, addressing the order of operations challenges is a code issue, not a data structure issue.&lt;br /&gt;
&lt;br /&gt;
In PCGen 5.14 and earlier, this problem was solved by storing information within PCGen as Strings, and then resolving those Strings against unique identifiers for each object (generally the Key).  This led to a number of issues, including performance issues due to String parsing, as well as failure to catch some errors until runtime.&lt;br /&gt;
&lt;br /&gt;
There are various potential solutions to such problems, and some of these are covered in [[Rebuild of the Token/Loader System]]. These were addressed in PCGen with the integration of a new Token/Loader system during the PCGen 5.16 cycle.  While there are solutions that would drive a two-pass parse of the data, the solution implemented in PCGen 5.16 limits the load of data to a single pass on the LST files.  Thus PCGen uses a series of references to allow the data at LST load to refer to objects which have not been encountered within the data.  After the load is complete, the references are resolved to their underlying objects.&lt;br /&gt;
&lt;br /&gt;
===Benefits of the defined solution===&lt;br /&gt;
&lt;br /&gt;
# Duplicate keys are detected at load, regardless of their source file, thus no references should be ambiguous&lt;br /&gt;
# Empty Group references can flag a warning if they do not contain any contents.  This serves as LST error checking to catch accidental typos in a group identifier&lt;br /&gt;
# Since References can be constructed well before they are resolved, references allow Game Mode information to be loaded once, thus preventing re-parsing of those files when a different set of sources is loaded.&lt;br /&gt;
&lt;br /&gt;
===Characteristics/Weaknesses of the defined solution===&lt;br /&gt;
&lt;br /&gt;
This section refers to PCGen 5.16&lt;br /&gt;
&lt;br /&gt;
# Currently, the LoadContext system uses WeakReferences to control the Disposal of CDOM Reference objects when FORGET is encountered.  In theory this does not guarantee that irrelevant CDOM Reference objects do not produce load errors due to missing information.  In practice, this error is unlikely to be encountered.  However, an ideal structure would design around this problem.  This issue is partially a function of the method of storage used in PCGen 5.16 (the Graph structure envisioned for CDOM is not in place), and partially a function of using a one-pass load.  There are multiple solutions to this problem, but since it's mostly a theoretical issue, it is not being addressed as a critical issue.&lt;br /&gt;
# Currently, BONUS, CHOOSE, and the PRExxx tokens have not been converted to the new Token/Loader system and do not yet provide all of the benefits outlined above.  A CHOOSE rebuild has been proposed as part of the PCGen 5.17 cycle (which leads to the next stable release, either 5.18 or 6.0).&lt;br /&gt;
# Currently CDOM References are classes and are not provided into CDOM Objects as an Interface.  In order to reduce potential for corruption of CDOMReferences, the single references are controlled to allow them to only be resolved once.  This is done without providing a method for resetting a CDOM Reference.  This is done to provide a strict mechanism to prevent errors and abuse of the CDOM Reference objects during runtime (this can be thought of as a short-term overly strict system to train developers and force separation between load and runtime).  Once we have a more stable and modular core in place, this strict mechanism may be relaxed and/or exchanged for interfaces.  Currently, this strict mechanism makes Game Mode references slightly more complex than other references.&lt;br /&gt;
# Some References are resolved at runtime.  Theoretically, this is a performance issue, but practically, the dynamic references are rare enough that this is not an issue.  The core of PCGen has much larger performance issues that should be addressed first before this is addressed as a performance issue.  It may turn out to be unnecessary optimization, so addressing this weakness is currently not scheduled for any release.&lt;br /&gt;
# Resolution may be an issue.  This mostly a theoretical issue at this point, but the dereferencing driven by the use of CDOM Reference objects is slightly slower than direct objects.  This is considered a minor performance issue, and unless demonstrated as a performance issue, will not be addressed.  There are some concerns about references in relation to lists (such as adding Spells to a ClassSpellList) and the complexity required to access the underlying information.  While this is a recognized issue, this pain point will be addressed in a near-future release as the PlayerCharacter data structure is changed to a Graph-based structure.&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Developers_Meeting&amp;diff=1059</id>
		<title>Developers Meeting</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Developers_Meeting&amp;diff=1059"/>
		<updated>2008-10-22T13:23:22Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Availability */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It would be good to get a meeting of the Code Monkeys going. Please fill in your available times below:&lt;br /&gt;
&lt;br /&gt;
=Timezones=&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Name !! Current Timezone !! Offset from GMT/UTC&lt;br /&gt;
|-&lt;br /&gt;
| [[Tom Parker]] || EDT || -4&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || AEDT || +11&lt;br /&gt;
|-&lt;br /&gt;
| [[nuance]] || GMT (currently BST) || +0 (currentlt +1)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Availability=&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Name !! Mon !! Tue !! Wed !! Thu !! Fri !! Sat !! Sun&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || 6pm-11pm AEDT || 6pm-11pm AEDT|| 6pm-11pm AEDT|| 6pm-11pm AEDT||6pm-11pm AEDT  || 7am-11pm AEDT|| 7am-4pm AEDT&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || 12am-5am UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC 8pm-12am UTC || 12am-12pm UTC 8pm-12am UTC&lt;br /&gt;
|-&lt;br /&gt;
| [[Tom Parker]] || 12am-3am UTC 10pm-12am UTC || 12am-3am UTC ''10pm-12am UTC'' || ''12am-3am UTC'' || none || 1am-3am UTC  10pm-12am UTC || 12am-1am UTC ''1am-3am UTC'' 11am-2pm UTC ''2pm-9pm UTC'' 9pm-12am UTC || 12am-3am UTC 11am-3pm UTC ''3pm-7pm UTC'' 7pm-12am UTC &lt;br /&gt;
|-&lt;br /&gt;
| [[Andrew Wilson]] (nuance) || none || ''8pm–1am'' || none || none || 7pm-12am UTC || 12am-3am UTC 9am-12am UTC || 12am-3am UTC 1pm-12am UTC &lt;br /&gt;
|-&lt;br /&gt;
| Common Time (James + Tom) || 12am-3am UTC || none || none || none || none || 11am-12pm UTC ''8pm-9pm UTC'' 9pm-12am UTC || 12am-3am UTC 11am-12pm UTC 8pm-12am UTC &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
PST is GMT -8&amp;lt;br&amp;gt;&lt;br /&gt;
MST is GMT -7&amp;lt;br&amp;gt;&lt;br /&gt;
EST is GMT -5&lt;br /&gt;
&lt;br /&gt;
''italicized items'' are limited availability: means availability needs to be negotiated based on other periodic activities&lt;br /&gt;
&lt;br /&gt;
[http://www.timeanddate.com/worldclock/meetingtime.html?year=2008&amp;amp;month=10&amp;amp;day=25&amp;amp;p1=57&amp;amp;p2=179&amp;amp;p3=37&amp;amp;p4=-1 Time comparison]&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Developers_Meeting&amp;diff=1058</id>
		<title>Developers Meeting</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Developers_Meeting&amp;diff=1058"/>
		<updated>2008-10-22T12:56:32Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Availability */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It would be good to get a meeting of the Code Monkeys going. Please fill in your available times below:&lt;br /&gt;
&lt;br /&gt;
=Timezones=&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Name !! Current Timezone !! Offset from GMT/UTC&lt;br /&gt;
|-&lt;br /&gt;
| [[Tom Parker]] || EDT || -4&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || AEDT || +11&lt;br /&gt;
|-&lt;br /&gt;
| [[nuance]] || GMT (currently BST) || +0 (currentlt +1)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Availability=&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Name !! Mon !! Tue !! Wed !! Thu !! Fri !! Sat !! Sun&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || 6pm-11pm AEDT || 6pm-11pm AEDT|| 6pm-11pm AEDT|| 6pm-11pm AEDT||6pm-11pm AEDT  || 7am-11pm AEDT|| 7am-4pm AEDT&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || 12am-5am UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC 8pm-12am UTC || 12am-12pm UTC 8pm-12am UTC&lt;br /&gt;
|-&lt;br /&gt;
| [[Tom Parker]] || 12am-3am UTC 10pm-12am UTC || 12am-3am UTC ''10pm-12am UTC'' || ''12am-3am UTC'' || none || 1am-3am UTC  10pm-12am UTC || 12am-1am UTC ''1am-3am UTC'' 11am-2pm UTC ''2pm-9pm UTC'' 9pm-12am UTC || 12am-3am UTC 11am-3pm UTC ''3pm-7pm UTC'' 7pm-12am UTC &lt;br /&gt;
|-&lt;br /&gt;
| [[nuance]] || none || ''8pm–1am'' || none || none || 7pm-12am UTC || 12am-3am UTC 9am-12am UTC || 12am-3am UTC 1pm-12am UTC &lt;br /&gt;
|-&lt;br /&gt;
| Common Time (James + Tom) || 12am-3am UTC || none || none || none || none || 11am-12pm UTC ''8pm-9pm UTC'' 9pm-12am UTC || 12am-3am UTC 11am-12pm UTC 8pm-12am UTC &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
PST is GMT -8&amp;lt;br&amp;gt;&lt;br /&gt;
MST is GMT -7&amp;lt;br&amp;gt;&lt;br /&gt;
EST is GMT -5&lt;br /&gt;
&lt;br /&gt;
''italicized items'' are limited availability: means availability needs to be negotiated based on other periodic activities&lt;br /&gt;
&lt;br /&gt;
[http://www.timeanddate.com/worldclock/meetingtime.html?year=2008&amp;amp;month=10&amp;amp;day=25&amp;amp;p1=57&amp;amp;p2=179&amp;amp;p3=37&amp;amp;p4=-1 Time comparison]&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Developers_Meeting&amp;diff=1057</id>
		<title>Developers Meeting</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Developers_Meeting&amp;diff=1057"/>
		<updated>2008-10-22T12:49:09Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Timezones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It would be good to get a meeting of the Code Monkeys going. Please fill in your available times below:&lt;br /&gt;
&lt;br /&gt;
=Timezones=&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Name !! Current Timezone !! Offset from GMT/UTC&lt;br /&gt;
|-&lt;br /&gt;
| [[Tom Parker]] || EDT || -4&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || AEDT || +11&lt;br /&gt;
|-&lt;br /&gt;
| [[nuance]] || GMT (currently BST) || +0 (currentlt +1)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Availability=&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Name !! Mon !! Tue !! Wed !! Thu !! Fri !! Sat !! Sun&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || 6pm-11pm AEDT || 6pm-11pm AEDT|| 6pm-11pm AEDT|| 6pm-11pm AEDT||6pm-11pm AEDT  || 7am-11pm AEDT|| 7am-4pm AEDT&lt;br /&gt;
|-&lt;br /&gt;
| [[James Dempsey]] || 12am-5am UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC || 7am-12pm UTC 8pm-12am UTC || 12am-12pm UTC 8pm-12am UTC&lt;br /&gt;
|-&lt;br /&gt;
| [[Tom Parker]] || 12am-3am UTC 10pm-12am UTC || 12am-3am UTC ''10pm-12am UTC'' || ''12am-3am UTC'' || none || 1am-3am UTC  10pm-12am UTC || 12am-1am UTC ''1am-3am UTC'' 11am-2pm UTC ''2pm-9pm UTC'' 9pm-12am UTC || 12am-3am UTC 11am-3pm UTC ''3pm-7pm UTC'' 7pm-12am UTC &lt;br /&gt;
|-&lt;br /&gt;
| Common Time (James + Tom) || 12am-3am UTC || none || none || none || none || 11am-12pm UTC ''8pm-9pm UTC'' 9pm-12am UTC || 12am-3am UTC 11am-12pm UTC 8pm-12am UTC &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
PST is GMT -8&amp;lt;br&amp;gt;&lt;br /&gt;
MST is GMT -7&amp;lt;br&amp;gt;&lt;br /&gt;
EST is GMT -5&lt;br /&gt;
&lt;br /&gt;
''italicized items'' are limited availability: means availability needs to be negotiated based on other periodic activities&lt;br /&gt;
&lt;br /&gt;
[http://www.timeanddate.com/worldclock/meetingtime.html?year=2008&amp;amp;month=10&amp;amp;day=25&amp;amp;p1=57&amp;amp;p2=179&amp;amp;p3=37&amp;amp;p4=-1 Time comparison]&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
	<entry>
		<id>http://159.203.101.162/w/index.php?title=Building_PCGen&amp;diff=377</id>
		<title>Building PCGen</title>
		<link rel="alternate" type="text/html" href="http://159.203.101.162/w/index.php?title=Building_PCGen&amp;diff=377"/>
		<updated>2008-08-10T01:33:18Z</updated>

		<summary type="html">&lt;p&gt;Nuance: /* Building PCGen from the command line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
=Building PCGen from the command line=&lt;br /&gt;
&lt;br /&gt;
This process uses the [[ANT]] tool, you need the following software packages:&lt;br /&gt;
&lt;br /&gt;
* Java Development Kit (aka Java SDK or JDK). You should use the latest version (update) of the JDK 5.0 available for download from [http://java.sun.com/javase/downloads/index_jdk5.jsp here]. At the time of writing this was JDK 5.0 Update 15. Java 1.6 will also work, but no 1.6 specific features should be used in the code. Other JDKs might work, but no one has tried.&lt;br /&gt;
* Ant 1.7.0 (or later) from [http://jakarta.apache.org/ant/ here]. Ant is an all-Java replacement for make, and is fully cross-platform. Note: You will also need to download the jakarta-ant optional.jar file if using certain versions of Ant. See [[ANT]] section for further details&lt;br /&gt;
* If you wish to run the test suite you will need JUnit 3.6 from [http://www.junit.org/ here].&lt;br /&gt;
* You will also need the latest version of the PCGen source code available from SVN. See [[Subversion Setup]] for details.&lt;br /&gt;
&lt;br /&gt;
Open a command window and change to the root directory/folder where you installed the PCGen source code. There should be a file called build.xml there.&lt;br /&gt;
&lt;br /&gt;
Type ant clean at the command prompt. This will make sure you have a clean start. Then run ant. This will build the pcgen.jar file. The jar file will be in ./bin. You can run pcgendev.bat or pcgendev.sh to run it or manually copy the jar file to the PCGen root directory.&lt;br /&gt;
&lt;br /&gt;
**NOTE**&lt;br /&gt;
* If you get a &amp;quot;Could not create task of type: javacc&amp;quot; you need to ensure you have the jakarta-ant optional.jar file in the $ANT_HOME/lib directory. (You only need this for older versions of Ant).&lt;br /&gt;
* If you get a &amp;quot;Could not create task of type: junit&amp;quot; you need to copy the junit.jar file from the pcgen/libs directory to the $ANT_HOME/lib directory. (You only need this for older versions of Ant).&lt;br /&gt;
&lt;br /&gt;
To generate the JavaDocs use ant docs, and for deployments you can use ant deploy, and finally ant all does all of the above (clean, build, docs, deploy), and ant complete does everything including a full testing cycle (which can take a while).&lt;br /&gt;
&lt;br /&gt;
Typing the command &amp;lt;pre&amp;gt;ant&amp;lt;/pre&amp;gt; will build the code and run a small selection of tests.&lt;br /&gt;
&lt;br /&gt;
Typing the command &amp;lt;pre&amp;gt;ant dotest&amp;lt;/pre&amp;gt; will build the code and run the full test suite.&lt;br /&gt;
&lt;br /&gt;
Typing the command &amp;lt;pre&amp;gt;ant reporttest&amp;lt;/pre&amp;gt; after running the tests will generate a test report.  The xml result files are generated while running the tests, they can be found in ./code/build/test-results/xml/ after making the reporttest target, a browsable set of html reports can be found in ./code/build/rpt/test-results/&lt;br /&gt;
&lt;br /&gt;
=Using Eclipse to build PCGen=&lt;br /&gt;
&lt;br /&gt;
You can build PCGen from within Eclipse. You will need to do a little bit of setup first though:&lt;br /&gt;
# Go to Window &amp;gt; Preferences, then Ant &amp;gt; Runtime then select Ant Home Entries under the Classpath tab.&lt;br /&gt;
# Click Add Jars. Select the junit.jar under pcgen/lib/test.&lt;br /&gt;
Now you should be able to select the build.xml, right click and hit Run &amp;gt; Ant Build and it should work.&lt;br /&gt;
&lt;br /&gt;
==Running and debugging==&lt;br /&gt;
&lt;br /&gt;
# Open the PCGen project.&lt;br /&gt;
# Open the Run dialog by right-clicking on the PCGen project and selecting Run &amp;gt; Run....&lt;br /&gt;
# Select the Java Application nide.&lt;br /&gt;
# Press the New button for a new configuration. Edit by field, thus:&lt;br /&gt;
Name -&amp;gt; PCGen&lt;br /&gt;
&lt;br /&gt;
Main class -&amp;gt; pcgen.gui.pcGenGUI&lt;br /&gt;
# Press Apply to save the configuration.&lt;br /&gt;
# Press Run to start PCGen.&lt;br /&gt;
&lt;br /&gt;
You can also run a single test by right clicking on the test and selecting Debug &amp;gt; JUnit Test. This is a great way to track through a bug too.&lt;br /&gt;
&lt;br /&gt;
=Using IDEA to build PCGen=&lt;br /&gt;
&lt;br /&gt;
You can build PCGen from within IDEA. You will need to do a little bit of setup first though:&lt;br /&gt;
# Go to the Window &amp;gt; Tool Windows &amp;gt; Ant Build. Press the [+] button to add a build file.&lt;br /&gt;
# Navigate to and select the build.xml Ant script in the root of the PCGen project tree. Press Ok.&lt;br /&gt;
&lt;br /&gt;
You can now select any Ant target you wish. Particularly helpful are the build and fetch-data targets.&lt;br /&gt;
&lt;br /&gt;
==Running and debugging==&lt;br /&gt;
&lt;br /&gt;
NB - IDEA will build the software sufficient for running and debugging within the IDE automatically just by following these step. This is not the same as the build from the Building section, above, which builds the software suitable for command-line use.&lt;br /&gt;
&lt;br /&gt;
# Open the PCGen.ipr project file.&lt;br /&gt;
# Get the Run/Debug Configurations dialog with Run &amp;gt; Edit Configurations from the menu bar.&lt;br /&gt;
# Select the Application tab.&lt;br /&gt;
# Press the [+] button for a new configuration. Edit by field, thus:&lt;br /&gt;
Name -&amp;gt; PCGen&lt;br /&gt;
&lt;br /&gt;
Main class -&amp;gt; pcgen.gui.pcGenGUI&lt;br /&gt;
# Uncheck Display settings before running/debugging.&lt;br /&gt;
# Press Ok.&lt;br /&gt;
&lt;br /&gt;
You can now run PCGen with the green right-pointing triangle on the toolbar and debug with the green right-facing beetle on a blue diamond. Or just use the Run menu.&lt;br /&gt;
&lt;br /&gt;
=Using Maven to build PCGen=&lt;br /&gt;
&lt;br /&gt;
See [[MAVEN]]&lt;/div&gt;</summary>
		<author><name>Nuance</name></author>
		
	</entry>
</feed>