Setting up the new Formula System
The basics
The new formula system is designed to do a few things relative to data:
- Validate formulas at LST load instead of runtime
- Dramatically increase flexibility
- It will replace many tokens, including all the BONUS tokens
Key concepts
To use the new system a few key things need to be remembered:
- It is possible to have local variables
- All variables must be defined prior to use
- Variables are not only numbers, but can be Strings, Dice, etc.
- We call this the variable FORMAT
Required Setup
Every format that needs to be used requires a default value. This value is shared throughout an entire system (it CANNOT be redefined). This is placed into a file referred to in a PCC file from the DATACONTROL: token.
The token used within that lst file is DEFAULTVARIABLEVALUE:
The format is DEFAULTVARIABLEVALUE:X|Y
- X is the format name
- Y is the default value
- Example: DEFAULTVARIABLEVALUE:NUMBER|0
How to define a variable
To define a variable, you need to add an LST file that is referred to in a PCC file from the VARIABLE: token.
There are 2 basic tokens for the VARIABLE file: GLOBAL and LOCAL.
- GLOBAL defines a global variable, usable from anywhere within the PlayerCharacter.
- LOCAL defines a local variable, usable only within the object on which the variable exists (or its children)
- 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.
Both of those tokens can take an 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)
The format of GLOBAL is GLOBAL:X=Y
- X is the format name
- Y is the variable name
- Example: GLOBAL:ORDEREDPAIR=Face
The format of LOCAL is LOCAL:W|X=Y
- W is the scope of the variable
- X is the format name
- Y is the variable name
- Example: LOCAL:STAT|NUMBER=Score
A few notes about the VARIABLE files: If you see an item without a leading token, e.g.:
- ORDEREDPAIR=Face
...then the system is using the default (GLOBAL). For now, the data standard is to avoid using this shortcut (as far as I know)
If you see an item without a leading format ("X" in both GLOBAL and LOCAL above), e.g.: LOCAL:STAT|Score ...then the format is a NUMBER. For now, the data standard is to avoid using this shortcut (as far as I know)
Setting a variable
The MODIFY token is used to set a variable.
The format of the token is: MODIFY:V|W|X|Y=Z|Y=Z
- V is the Variable name for which the value will be modified
- 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.
- W is the MODIFIER to be taken on the variable (e.g. SET)
- There can be multiple actions (more below), but SET will ALWAYS be available for any format.
- 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.
- Y is the name of an (optional) ASSOCIATION. For now, PRIORITY (more below) is the only available association.
- Z is the value of the association.
Available MODIFIERS
For NUMBER, the following modifiers are available:
- SET: This sets the variable to the value provided in the "X" parameter
- ADD: This adds the current value of the variable to the value provided in the "X" parameter
- MAX: This takes the maximum value of the current value of the variable and the value provided in the "X" parameter
- MIN: This takes the minimum value of the current value of the variable and the value provided in the "X" parameter
- MULTIPLY: This adds the current value of the variable and the value provided in the "X" parameter
- DIVIDE: This adds the current value of the variable by the value provided in the "X" parameter
Understanding PRIORITY and processing of MODIFY and MODIFYOTHER
When a PlayerCharacter has multiple items that attempt to modify a variable, they are sorted by two systems:
- First, they are sorted by their user priority. This is provided in the PRIORITY=Z association. Lower PRIORITY will be processed first.
- 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.
Example: Assume we had the following items:
- MODIFY:Hands|MULTIPLY|2|PRIORITY=100
- MODIFY:Hands|SET|2|PRIORITY=50
- MODIFY:Hands|ADD|1|PRIORITY=50
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 < 100). For the SET and ADD, we would need to know the inherent priority (For what it's worth, SET is 0, ADD is 1). 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.
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)