Formula Parser Conversion - Data
Contents
Proposed Changes
Based off of examples and discussion ideas from Formula_Parser_Equip_Vars_Proposal and Formula_Parser_Equip_Vars_Demo
- NOTE: All syntax here is in planning stages, nothing is FINALIZED!
- NOTATION:
- X = Numerical Value appropriate for variable
- N = Name as appropriate
New formula system MUST support PRExxx, the alternative is additional Ability objects with PRExxx tags to trigger the Formula. Performance would definitely take a hit.
Thought for attacks:
- ATTACKS controls how many attacks are available.
- We have a local 'ATTACKS' for equipment
- We have a Global 'ATTACKS.Total'
- MODIFYOTHER:ATTACKS|SOLVE|ATTACKS.Total
- In our global file we have: MODIFY:ATTACKS.Total|SOLVE|1+min((BASEAB-1)/5,3)
- This grants first attack, and then the pattern +1 at 6, +2 at 11, +3 at 16
- Next, since we need fine control over attack bonuses, we set this up:
- TOHIT.Base, TOHIT.2, TOHIT.3, TOHIT.4, TOHIT.5, etc. (Assume all base PCs should have 5 values - this accounts for 4 attacks from high BAB, and +1 for a speed/haste effect
- MODIFYOTHER:TOHIT.Base|SOLVE|value()+TOHIT.Total
- MODIFYOTHER:TOHIT.2|SOLVE|value()+TOHIT.Base|PREVARGTEQ:ATTACKS,2
- MODIFYOTHER:TOHIT.3|SOLVE|value()+TOHIT.Base|PREVARGTEQ:ATTACKS,3
- MODIFYOTHER:TOHIT.4|SOLVE|value()+TOHIT.Base|PREVARGTEQ:ATTACKS,4
- MODIFYOTHER:TOHIT.2|SUBTRACT|5|PREVARGTEQ:ATTACKS,2
- MODIFYOTHER:TOHIT.3|SUBTRACT|10|PREVARGTEQ:ATTACKS,3
- MODIFYOTHER:TOHIT.4|SUBTRACT|15|PREVARGTEQ:ATTACKS,4
Now, that handles standard attacks.
For Flurry of Blows:
- MODIFY:ATTACKS|SOLVE|MonkBAB-1/3 -> This sets us to have more attacks for the Flurry
Next we want to set up the Flurry Attack Values
- MODIFY:FlurryAttackTotal|SOLVE|value()+TOHIT.Total-2
- MODIFY:TOHIT.1|SOLVE|value()+FlurryAttackTotal
- MODIFY:TOHIT.2|SOLVE|value()+TOHIT.1|PREVARGTEQ:ATTACKS,2
- MODIFY:TOHIT.3|SOLVE|value()+TOHIT.1|PREVARGTEQ:ATTACKS,3
- MODIFY:TOHIT.4|SOLVE|value()+TOHIT.1|PREVARGTEQ:ATTACKS,4
- MODIFY:TOHIT.5|SOLVE|value()+TOHIT.1|PREVARGTEQ:ATTACKS,5
- MODIFY:TOHIT.6|SOLVE|value()+TOHIT.1|PREVARGTEQ:ATTACKS,6
- MODIFY:TOHIT.7|SOLVE|value()+TOHIT.1|PREVARGTEQ:ATTACKS,7
That gives us up to seven attacks, all set at the initial to hit value of attack #1. We can then designate each attack to have a decreased value from the initial value.
- MODIFY:TOHIT.3|SUBTRACT|2
Attack value assumed 20, Number of attacks set to 5, display would be +20/+20/+18/+20/+20
With this thought process, we need to devise a method that can do such things as Haste or Speed
- Items which typically add an additional attack at the highest value
Standard Tokens
HANDS:x
- Defined as "HANDS"
- Set by MODIFY:HANDS|SET|x
LEGS:x
- Defined as "LEGS"
- Set by MODIFY:LEGS|SET|x
FACE:x
- Defined as "FACE"
- Set by MODIFY:FACE|SET|x,x
- NOTE: This is an AREA not a VAR, hence the syntax expression allowed is "x,x"; oddly enough, I am curious how this value will be altered. NOTE FOR TOM!
MOVE:x,y,x,y (x = being valid movement modes such as Walk, Fly, Burrow, Climb, Swim; y = value)
- Defined as the movement mode name "WALK", "FLY", etc.
- Set by MODIFY:MOVE.n|SET|x
CR:x
- Defined as "CR"
- Set by MODIFY:CR|SET|x
- Special Consideration as CR has other system mechanic implications handled in the gamemode.
CL:x (CLASS ONLY Token)
- Defined as "CL"
- Set by MODIFY:CL|SOLVE|thisclass()
SR:x (Since this typically comes in two race flavors 5+Level, or 11+Level, we can set this up via ability)
- Defined as "SR"
- Set by MODIFY:SR|SOLVE|x
CT: (CASTINGTHRESHOLD)
- Defined as "CT"
- Set by MODIFY:CT|ADD|x
Special Considerations
FOLLOWERS:x|y - has BONUS:FOLLOWERS|x|y - conversion will require the "y" be a variable
- Set as "FOLLOWER.n"
ABILITYCATEGORY - has POOL. This should be set "POOL.n"
HD:x - probably be altered to "HD.n" to allow the bonus replacement
HITDIE:x (Three variations - CLASS alters the HD it's located on - use "HD.n", Race/Template alters all granted HD)
MOVEBASE - this should be used exclusively on race or attached if the base.
- Set "MOVEBASE.n" with n being a valid movement value
BONUS:KNOWN
mastervar() - this needs to be ported over as this function is crucial; we should also get one back 'companionvar()' if possible.
MAXLEVEL:x -
XTRAFEATS:x - DEPRECATE (Can be replicated by BONUS:ABILITYPOOL|FEAT|x, and MODIFY:POOL.FEAT|ADD|x)
MOVECLONE:x,x,y - DEPRECATE (Can be replicated better by MODIFY:MOVE.n2|SOLVE|max(MOVE.n1*2,30)
NONPP:x
- Set with "NONPP" - Replace Gamemode tag for that.
STARTSKILLPTS:x - replace with local var?
TEMPBONUS??? - Very special consideration!!!
WT:x (Ties into a JIRA for robot armor)
- Set with "WT"
WIELD:x - need to evaluate due to this going away:
- EQSIZEPENALTY:35 Size Penalty
- BONUS:WEAPON|TOHIT|(PC.SIZE.INT-EQUIP.SIZE.INT)*-2|PREVARGT:PC.SIZE.INT,EQUIP.SIZE.INT|!PRETYPE:2,Melee,Natural|!PRETYPE:1,NoAttackPenalty|TYPE=DifferentEQSizePenalty
- BONUS:WEAPON|TOHIT|(EQUIP.SIZE.INT-PC.SIZE.INT)*-2|PREVARGT:EQUIP.SIZE.INT,PC.SIZE.INT|!PRETYPE:2,Melee,Natural|!PRETYPE:1,NoAttackPenalty|TYPE=DifferentEQSizePenalty * BONUS:WEAPON|TOHIT|SizeIncrease*2|PREVARGT:PC.SIZE.INT,EQUIP.SIZE.INT|!PRETYPE:2,Melee,Natural|PREVARGTEQ:SizeIncrease,1 * BONUS:WEAPON|TOHIT|SizeDecrease*2|PREVARGT:EQUIP.SIZE.INT,PC.SIZE.INT|!PRETYPE:2,Melee,Natural|PREVARGTEQ:SizeDecrease,1 * BONUS:WEAPON|TOHIT|2|PREVARGT:EQUIP.SIZE.INT,PC.SIZE.INT|!PRETYPE:2,Melee,Natural|PREABILITY:1,CATEGORY=Special Ability,Oversized Weapon
- BONUS:WEAPON|TOHIT|min(OversizeWeaponToHitBonus,((EQUIP.SIZE.INT-PC.SIZE.INT)*2))|PREVARGT:EQUIP.SIZE.INT,PC.SIZE.INT|!PRETYPE:2,Melee,Natural
And this:
WIELDCATEGORY:Light HANDS:1 FINESSABLE:Yes SIZEDIFF:-1 DAMAGEMULT:1=1,2=1 WIELDCATEGORY:OneHanded HANDS:1 SIZEDIFF:0 DAMAGEMULT:1=1,2=1.5 WIELDCATEGORY:TwoHanded HANDS:2 SIZEDIFF:1 DAMAGEMULT:2=1.5 WIELDCATEGORY:TooSmall HANDS:999 WIELDCATEGORY:TooLarge HANDS:999 WIELDCATEGORY:Unusable HANDS:999 WIELDCATEGORY:None HANDS:0
- Light weapon vs PC size changes
WIELDCATEGORY:Light PREVARLTEQ:EQUIP.SIZE.INT,PC.SIZE.INT-1 SWITCH:TooSmall WIELDCATEGORY:Light PREVAREQ:EQUIP.SIZE.INT,PC.SIZE.INT+1 SWITCH:OneHanded WIELDCATEGORY:Light PREVAREQ:EQUIP.SIZE.INT,PC.SIZE.INT+2 SWITCH:TwoHanded WIELDCATEGORY:Light PREVARGTEQ:EQUIP.SIZE.INT,PC.SIZE.INT+3 SWITCH:TooLarge
- OneHanded weapon vs PC size changes
WIELDCATEGORY:OneHanded PREVARLTEQ:EQUIP.SIZE.INT,PC.SIZE.INT-2 SWITCH:TooSmall WIELDCATEGORY:OneHanded PREVAREQ:EQUIP.SIZE.INT,PC.SIZE.INT-1 SWITCH:Light WIELDCATEGORY:OneHanded PREVAREQ:EQUIP.SIZE.INT,PC.SIZE.INT+1 SWITCH:TwoHanded WIELDCATEGORY:OneHanded PREVARGTEQ:EQUIP.SIZE.INT,PC.SIZE.INT+2 SWITCH:TooLarge
- TwoHanded weapon vs PC size changes
WIELDCATEGORY:TwoHanded PREVARLTEQ:EQUIP.SIZE.INT,PC.SIZE.INT-3 SWITCH:TooSmall WIELDCATEGORY:TwoHanded PREVAREQ:EQUIP.SIZE.INT,PC.SIZE.INT-2 SWITCH:Light WIELDCATEGORY:TwoHanded PREVAREQ:EQUIP.SIZE.INT,PC.SIZE.INT-1 SWITCH:OneHanded WIELDCATEGORY:TwoHanded PREVARGTEQ:EQUIP.SIZE.INT,PC.SIZE.INT+1 SWITCH:TooLarge
- Wield Category Steps
- This is used when figuring bonuses that allow you to wield Larger or Smaller size weapons
WCSTEPSFORMULA:EQUIP.SIZE.INT-PC.SIZE.INT
WIELDCATEGORY:TooSmall UP:Light|OneHanded|TwoHanded ZERO:Light WIELDCATEGORY:Light UP:OneHanded|TwoHanded WIELDCATEGORY:OneHanded UP:TwoHanded DOWN:Light WIELDCATEGORY:TwoHanded DOWN:OneHanded|Light WIELDCATEGORY:TooLarge DOWN:TwoHanded|OneHanded|Light ZERO:TwoHanded </nowiki>
Variables
These have special value that needs to be handled
- STR & STRSCORE
- DEX & DEXSCORE
- CON & CONSCORE
- INT & INTSCORE
- WIS & WISSCORE
- CHA & CHASCORE
=> All should be rather simple to whip up
- TL => Global 'MODIFY:TL|SOLVE|???' - need a method to grab all levels.
- CL => Local 'MODIFY:CL|SOLVE|thisclass()'
- BASECR => Was set by CR on the race, 'MODIFY:BASECR|SET|x' on race
- CR => MODIFY:CR|SOLVE|value()+BASECR
CASTERLEVEL - gonna need some thought
BASEHD -
- MODIFY:BASEHD|SOLVE|CLASS.Monster
- NOTE: All classes designated as "Monster" need "MODIFY:BASEHD|SOLVE|thisclass()"
RACIALHDSIZE
- MODIFY:RACIALHDSIZE|SET|x - placed in all Class TYPE "Monster"
WEIGHT.CARRIED
WEIGHT.EQUIPPED
WEIGHT.PC
WEIGHT.TOTAL
SKILLTOTAL=name
- "MODIFY:SKILLTOTAL.n|SOLVE|SKILLRANK.n+SKILL.n+SKILLSTAT.n
- Debating how we handle bonuses to skills with types "BONUS:SKILL|n|x|TYPE=Competence"
- MODIFY:SKILL.n|SOLVE|Competence+Profane+Holy+Morale+Misc
TYPEs
We will set up each "TYPE" assigned as a local variable. We will need to establish "Non-Stacking" rules
Common TYPE's
- Deflection (AC)
- Dodge (AC, Stacks)
- Profane (AC)
- Holy (AC)
- NaturalArmor (AC)
- Enhancement (Armor/Weapon/tool)
- Morale (Attack/Save)
- Competence (Skill)
AC Types: (Most systems)
- Base
- Touch
- TouchMisc
- Flatfooted
- Ability
- Size
- Armor
- ArmorEnhancement
- Shield
- ShieldEnhancement
- NaturalArmor
- NaturalArmorEnhancement
- Dodge
- Deflection
- Misc
- Circumstance
- Insight
- Morale
- Profane
- Sacred/Holy
- CMD
- ClassDefense
Stats & Checks
- FORMULATERM:STR
- FORMULATERM:DEX
- FORMULATERM:CON
- FORMULATERM:INT
- FORMULATERM:WIS
- FORMULATERM:CHA
SAVE will be a special case involving FORMULATERM:x
BONUS:SAVE becomes
- Defined as "SAVE.n"
- MODIFY:SAVE.n|SOLVE|value()+STATVAR
Equipment Tokens - using Local Formula System
ACCHECK
- Becomes three Defined values 'ACCHECK' is the total value; 'ACCHECK.Armor' will be used for Armor; 'ACCHECK.Shield' will be used for Shields
- Conversion will need to realize if ACCHECK is TYPE "Armor" or "Shield" to convert to proper variable.
- Set by MODIFY:ACCHECK.n|SET|x
- Example: MODIFY:ACCHECK.Armor|SET|-6
ALTCRITMULT (See also CRITMULT)
- Defined as "CritMult"
- Set by 'PART:2|MODIFY:CritMult|SET|x' with x being the value
ALTCRITRANGE (See also CRITRANGE)
- Defined as "CritRange"
- Set by 'PART:2|MODIFY:CritRange|SET|x' with x being the value
ALTDAMAGE (Conversion ?)
COST
- Needs to be considered. We have a lot of issues factoring costs, so using the new system may be beneficial.
CRITMULT (See also ALTCRITMULT)
- Defined as "CritMult"
- Set by 'PART:1|MODIFY:CritMult|SET|x'
CRITRANGE
- Define as "CritRange"
- Set by 'PART:1|MODIFY:CritRange|SET|x'
DAMAGE (Conversion ?) Would make sense in some aspects, but make things harder in another. Need to contemplate and deliberate with Code and Arch.
EDR
- Defined as "EDR"
- Set by 'MODIFY:EDR|SET|x"
FUMBLERANGE
- Defined as "FUMBLERANGE"
- Set by 'MODIFY:FUMBLERANGE|SET|x'
- May use PART:x|MODIFY:FUMBLERANGE|SET|x if double weapon
MAXDEX
- Defined as "MAXDEX"
- Set by 'MODIFY:MAXDEX|SET|x'
- NOTE: This will be presented to "MODIFY:MAXDEX.TOTAL|SOLVE|thisvalue()+MAXDEX" which will set the global Max Dex to work with the d20 systems.
NUMPAGES (?)
PAGEUSAGE (?)
RANGE
- Defined as "RANGE"
- Set by 'MODIFY:RANGE|SET|x'
RATEOFFIRE
- Defined as "RATEOFFIRE"
- Set by 'MODIFY:RATEOFFIRE|SET|x'
REACH
- Defined as "REACH"
- Set by 'MODIFY:REACH|SET|x'
REACHMULT
- Defined as "REACH" - REACHMULT becomes part of the Formula system.
- Set by 'MODIFYOTHER:EQUIPMENT.PART|ALL|REACH|SOLVE|value()*x'
SLOTS (EQMHANDS interfaces with this value)
- Defined as "SLOTS"
- Set by 'MODIFY:SLOTS|SET|x'
SPELLFAILURE
- Defined as "SPELLFAILURE"
- Set by 'MODIFY:SPELLFAILURE|SET|x'
- NOTE: This will be presented to "MODIFY:SPELLFAILURE.TOTAL|SOLVE|thisvalue()+SPELLFAILURE" which will set the global SPELLFAILURE to work with the d20 systems and OS.
- NOTE TO TOM: Need to make sure we can grab multiple values to get correct values - such as SPELLFAILURE from equipped Shield and Armor.
WT
- Defined as "WT"
- Set by 'MODIFY:WT|SET|x'
BONUS TAGS PROPOSED
ABILITYPOOL => Simple conversion, we implement the POOL:n tag in all the ABILITYCATEGORIES, then use MODIFY for the POOLNAME. Example: MODIFY:POOL.n|ADD|x then ABILITYCATEGORY:Pool <> POOL:POOL.x
BONUS:ACVALUE - Gamemode tag, skipping for now.
BONUS:CASTERLEVEL - This would become MODIFY:CASTERLEVEL.n|SOLVE|thisclass()+CasterLevelBonus.n
- x = Class Name, we will continue to use 'CASTERLEVEL' as the first portion in all CAPS.
BONUS:CONCENTRATION - Becomes "MODIFY:CONCENTRATION.n|SOLVE|ConcentrationBase+ConcentrationClassBonus.n
- x = Class Name, we will use CONCENTRATIONBASE to set the base line level across all classes. (Pathfinder only)
BONUS:DC - becomes MODIFY:DC.n|SOLVE|STATBONUS.x
Master Bonus Tag List
- BONUS:COMBAT (Global BONUS - this applied to all things)
- Encompasses:
- "AC",
- Set as 'AC.n' - due to multiple types, needs extra consideration
- "ATTACKS", Global is defined as "COMBAT.ATTACKS", local for weapons is "ATTACKS"
- Set as 'MODIFY:COMBAT.ATTACKS|ADD|x'
- "ATTACKS", Global is defined as "COMBAT.ATTACKS", local for weapons is "ATTACKS"
- "BASEAB",
- Set as 'MODIFY:BASEAB|SOLVE|thisclass("APPLIEDAS=NONEPIC")'
- "BASEAB",
- "DAMAGE.Weapon or TYPE",
- "DAMAGEMULT - special values",
- "DAMAGESIZE",
- "DAMAGE-SHORTRANGE",
- "EPICAB",
- Set as 'MODIFY:BASEAB|SOLVE|thisclass("APPLIEDAS=EPIC")'
- "EPICAB",
- "INITIATIVE",
- Set as 'MODIFY:INITIATIVE|ADD|x'
- "INITIATIVE",
- "REACH",
- Global is "REACH.Race", Local is REACH for individual weapons
- Set as 'MODIFY:REACH.Race|ADD|x'
- "REACH",
- "RANGEPENALTY",
- "SECONDARYATTACKS",
- "SECONDARYDAMAGE",
- "TOHIT",
- Set as 'MODIFY:COMBAT.TOHIT|ADD|x'
- "TOHIT.Weapon Type",
- "TOHIT-PRIMARY",
- "TOHIT-SECONDARY",
- "TOHIT-SHORTRANGE"
- BONUS:DR (Global BONUS) - Special Consideration, may need to keep DR unless Tom has something in mind for the "DR:cold iron/5"
- BONUS:DOMAIN|NUMBER (Special Consideration - UI ramifications, along with class ramifications)
- Defined as
- Modified by 'MODIFYOTHER:||x'
BONUS:EQM|HANDS (Equipment Modifier)
- Defined as "SLOTS"
- 'MODIFYOTHER:SLOTS|Z|x'
These following are all handled with the same tag:
- BONUS:EQM|WEIGHTADD
- BONUS:EQM|WEIGHTDIV
- BONUS:EQM|WEIGHTMULT
- Defined as "WT"
- Modified by MODIFYOTHER:WT|Z|X
- Z = ADD, DIVIDE, or MULTIPLY
- X = Number
BONUS:EQMARMOR|ACCHECK (Equipment Modifier)
- Defined as 'ACCHECK.Armor'
- Modified by 'MODIFYOTHER:ACCHECK.Armor|ADD|x'
BONUS:EQMARMOR|EDR (Equipment Modifier)
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:EQMARMOR|MAXDEX (Equipment Modifier)
- Defined as 'MAXDEX'
- Modified by 'MODIFYOTHER:MAXDEX|ADD|x'
- BONUS:EQMARMOR|SPELLFAILURE (Equipment Modifier)
- Defined as 'SPELLFAILURE'
- Modified by 'MODIFYOTHER:SPELLFAILURE|SUBTRACT|x'
- BONUS:EQMWEAPON|CRITRANGEADD (Equipment Modifier)
- Defined as 'CRITRANGE'
- Modified by 'MODIFYOTHER:CRITRANGE|ADD|x'
- BONUS:EQMWEAPON|CRITRANGEDOUBLE (Equipment Modifier)
- Defined as 'CRITRANGE'
- Modified by 'MODIFYOTHER:CRITRANGE|MULTIPLY|2'
- BONUS:EQMWEAPON|DAMAGESIZE (Equipment Modifier) ???
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:EQMWEAPON|RANGEADD (Equipment Modifier)
- Defined as 'RANGE'
- Modified by 'MODIFYOTHER:RANGE|ADD|x'
- BONUS:EQMWEAPON|RANGEMULT (Equipment Modifier)
- Defined as 'RANGE'
- Modified by 'MODIFYOTHER:RANGE|MULT|x'
- BONUS:FEAT|POOL (Global BONUS)
- Defined as 'POOL.Feat'
- Modified by 'MODIFY:POOL.Feat|ADD|x'
- BONUS:FOLLOWERS (Global BONUS) - Exception tag, needs consideration?
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:HD (CLASS ONLY TAG - increases HD size)
- Defined as 'HD.N'
- Modified by 'MODIFYOTHER:HD.N|ADD|x'
- BONUS:HP
- Defined as 'HP.CURRENTMAX' or 'HP.ALTHP'
- Modified by 'MODIFY:n|ADD|x'
- BONUS:ITEMCAPACITY (Size Adjustment) - Special tag using TYPE - needs evaluation
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:ITEMCOST - Special tag using TYPE - needs evaluation
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:ITEMCOST|TYPE (Global BONUS) - Special tag using TYPE - needs evaluation
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:ITEMCOST (Size Adjustment) - Special tag using TYPE - needs evaluation
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:ITEMWEIGHT (Size Adjustment) - Special tag using TYPE - needs evaluation
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:LANG (Stats & Checks) (In STATNAME Line)
- Defined as 'LANGUAGE.INTBASED'
- Modified by 'OTHER:LANGUAGE.INTBASED|ADD|INT'
- BONUS:LOADMULT (Size Adjustment) - Gamemode - needs consideration
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:LANGUAGES|NUMBER (Global BONUS)
- Defined as 'LANGUAGE.TOTAL'
- Modified by 'MODIFY:LANGUAGE.TOTAL|ADD|x'
- BONUS:LOCKEDSTAT (Global BONUS) - Special tag / review
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:MISC (Global BONUS)
- Covers these:
- ACCHECK,
- CR,
- MAXDEX,
- SPELLFAILURE,
- SR
- Defined as 'ACCHECK', 'CR', 'MAXDEX', 'SPELLFAILURE', 'SR'
- Modified by 'MODIFY:n|ADD|x'
- BONUS:MODSKILLPOINTS (Stats & Checks)
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:MONSKILLPTS|LOCKNUMBER (Template)
- Defined as
- Modified by 'MODIFYOTHER:||x'
BONUS:MOVEADD|TYPE & BONUS:MOVEMULT|TYPE
- Valid normal values are any defined movement - Walk, Fly, Swim, Climb, Burrow
- Defined as 'MOVE.n'
- Modified by 'MODIFY:MOVE|ADD|x'
- Modified by 'MODIFY:MOVE|MULTIPLY|x'
- BONUS:PCLEVEL (Global BONUS)
- Defined as 'PCLEVEL.n'
- Modified by 'MODIFYOTHER:PCLEVEL.n|ADD|x'
- BONUS:POSTMOVEADD|TYPE (Global BONUS)
- Valid normal values are any defined movement - Walk, Fly, Swim, Climb, Burrow
- Defined as 'MOVE.n'
- Modified by 'MODIFY:MOVE|ADD|x|PRIORITY=1000'
- BONUS:POSTRANGEADD (Global BONUS)
- Defined as 'RANGE'
- Modified by 'MODIFYOTHER:RANGE|ADD|x|PRIORITY=1000'
- BONUS:PPCOST (Spell)
- Defined as 'PPCOST'
- Modified by 'MODIFYOTHER:PPCOST|ADD|x'
- BONUS:RANGEADD (Global BONUS)
- Defined as 'RANGE'
- Modified by 'MODIFYOTHER:RANGE|ADD|x'
- BONUS:RANGEMULT (Global BONUS)
- Defined as 'RANGE'
- Modified by 'MODIFYOTHER:RANGE|MULTIPLY|x'
- BONUS:SAVE (Global BONUS) - will this convert?
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:SITUATION (Global BONUS)
- Defined as 'SITUATION.n'
- Modified by 'MODIFYOTHER:SITUATION.n|ADD|x'
- BONUS:SIZEMOD|NUMBER (Global BONUS)
- Defined as 'SIZEMOD'
- Modified by 'MODIFY:SIZEMOD|ADD/SUBTRACT|x'
- BONUS:SKILL (Global BONUS)
- Defined as 'SKILL.n'
- Modified by 'MODIFYOTHER:SKILL.n|ADD/SUBTRACT|x'
- BONUS:SKILLRANK (Global BONUS)
- Defined as 'SKILLRANK.n'
- Modified by 'MODIFYOTHER:SKILLRANK.n|ADD|x'
- BONUS:SKILLPOINTS (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:SKILLPOOL - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:SLOTS (Global BONUS)
- Defined as 'SLOT.n'
- Modified by 'MODIFY:SLOT.n|ADD/SUBTRACT|x'
- BONUS:SPECIALTYSPELLKNOWN (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:SPELLCAST (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:SPELLCASTMULT (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:SPELLKNOWN (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:SPELLKNOWNMULT (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:STAT (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:STAT|BASESPELLKNOWNSTAT (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:STAT|BASESPELLKNOWNSTAT:CLASS (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:STAT|BASESPELLSTAT (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:STAT|BASESPELLSTAT;CLASS (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:UDAM (Global BONUS) - Special considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:VAR (Global BONUS) - DEPRECATED!
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:VISION (Global BONUS)
- Defined as 'VISION.n'
- Modified by 'MODIFY:VISION.n|ADD|x'
- BONUS:WEAPON (Global BONUS) - REVIEW
- Values
- 'ATTACKS',
- 'ATTACKSPROGRESS',
- 'DAMAGE',
- 'DAMAGEMULT',
- 'DAMAGE-SHORTRANGE',
- 'TOHIT',
- 'TOHIT-SHORTRANGE',
- 'WEAPONBAB',
- 'WIELDCATEGORY'.
- Defined as 'ATTACKS', 'ATTACKSPROGRESS', 'DAMAGE', 'DAMAGEMULT', 'DAMAGE-SHORTRANGE', 'TOHIT', 'TOHIT-SHORTRANGE', 'WEAPONBAB', 'WIELDCATEGORY'
- Modified by 'MODIFYOTHER:||x'
- BONUS:WEAPONPROF (Global BONUS) - Special Considerations
- Defined as
- Modified by 'MODIFYOTHER:||x'
- BONUS:WIELDCATEGORY (Global BONUS) - this needs to consider single item and all items.
- Defined as 'WIELDCATEGORY'
- Modified by 'MODIFYOTHER:WIELDCATEGORY|ADD/SUBTRACT|x'
NEW DEFINES
Any Class/Object name with a SPACE in it's name will use an UNDERSCORE '_' to replace the space, as I don't believe that the System can handle SPACES. (Check with Tom)
- POOL.n > Used for ABILITYCATEGORY on the POOL: token "POOL:POOL.n" to easily designate Pools we can alter.
- CASTERLEVEL.n = Used for all classes that CAST spells. n = Class Name. Example CASTERLEVEL.Wizard, CASTERLEVEL.Mage_Blade
- AC.n = Used for designating the AC Type. Example, AC.NATURAL.
DEPRECATION
- JEP Formula Parser which includes:
- DEFINE:x
- BONUS:VAR
- All Bonus Tags are planned on being replaced by the Formula Parser system in the future and any base tag that they affect is a potential candidate for Formula Parser replacement, such as:
- HANDS
- LEGS
- CR
- SLOTS
- CRITMULT
- ACCHECK,
- MAXDEX,
- SPELLFAILURE,
- SR
- DR (BONUS:DR is an odd duck)
Homebrew Conversion Start
Here is a basic list of conversion - should be universal.
NOTE: This is still in the planning phase, this is not official yet.
Tag Name | Converted to | Reviewable? | Comments |
---|---|---|---|
CRITMULT:x | PART:1|MODIFY:CritMult|SET|x | No | No concerns |
CRITRANGE:x | PART:1|MODIFY:CritRange|SET|x | No | No concerns |
ALTCRITMULT:x | PART:2|MODIFY:CritMult|SET|x | No | No concerns |
ALTCRITRANGE:x | PART:2|MODIFY:CritRange|SET|x | No | No concerns |
PLACEHOLDER |
Conversion Process Ideas
Keeping homebrews caught up with changes in pcgen is a daunting task. We strive to make it easier for those who maintain their own data to keep up with production cycle changes. This Formula Parser is going to be a tough conversion process, since this will not be an apples to apples process. Many issues hinder a one-to-one or apples-to-apples conversion approach:
- TERMS are not allowed
- Some magical back up parser would kick in if JEP failed
- JEP and FORMULA parser will not interact at all
- The vars and replacement tokens are Data Scope and Driven by Data Decisions
- TYPE=x is not supported in the new system, making BONUS:VAR|MyVar|5|TYPE=Competence much harder to convert.
A suggestion I made was a PER gamemode system migration file to help with conversions. This would house all the OLDTAGS and give them the "NEWTAG". However, this does not address the TYPE=x issue.
Tom has some ideas, but needs to discuss the ramifications with the development team.
Log Discussion for Non-Stacking modifiers interaction with SKILL / SKILLSIT
- Tom[Arch_SB]: Making up something new for the moment
- DEFAULTVARIABLEVALUE:NONSTACKING|0
- VARTYPEDEF:NONSTACKING|NONSTACKINGBONUS
- LOCAL:ALL|NONSTACKINGBONUS|Trait
- (and this is on the fly, so don't try to remember or quote me on this later as being set or coherent in any way)
- @Andrew[Chair]: concepts and brainstorm sessions are like that... Nothing is set in stone.
- Tom[Arch_SB]:
- MyTrait <> MODIFYOTHER:SKILL|Foo|Trait|APPLY|1
- MyTrait.MOD <> MODIFYOTHER:SKILLSIT|Foo (Bar)|Trait|APPLY|2
- MODIFYOTHER:SKILLSIT|ALL|Trait|APPLY|parent()
- the last in the global file
- APPLY as a modifier knows Trait is a NONSTACKINGBONUS
- APPLY then performing the stacking rules
- in the case of NONSTACKINGBONUS that is the equivalent of MAX
- in the semiequivalent case of STACKINGBONUS it's ADD
- @Andrew[Chair]: Okay, you lost me...
- Tom[Arch_SB]: so "Trait" starts its life with value zero
- @Andrew[Chair]: A bunch of new concepts packed in tightly...
- Okay Trait = 0
- Tom[Arch_SB]: since the default value for any NONSTACKING is zero as per the default variable value line
- @Andrew[Chair]: Correct
- Tom[Arch_SB]: Trait is local to all objects that was caused by the
- LOCAL:ALL|NONSTACKINGBONUS|Trait
- so Foo as a skill has a local variable Trait then in MyTrait, we modified Trait on the skill to be 1
- MODIFYOTHER:SKILL|Foo|Trait|APPLY|1
- we also modified via the .MOD, the Trait on the Situation to be 2
- MODIFYOTHER:SKILLSIT|Foo (Bar)|Trait|APPLY|2
- globally we modified Trait on the situation to be equivalent to the parent
- MODIFYOTHER:SKILLSIT|ALL|Trait|APPLY|parent()
- thus if we didn't have the APPLY|2 it would be 1
- since the parent (the skill foo)has Trait of 1
- follow?
- @Andrew[Chair]: Is APPLY a new Function? And is parent() a new function?
- Tom[Arch_SB]: yes
- things I'm creating on the fly
- parent() is referring to the var on the skill (when used for a situation)
- @Andrew[Chair]: Okay, then yes. Now I'm following. Takes a bit, I've been learning pseudo-code algorithms in class
- Tom[Arch_SB]: APPLY is equivalent to MAX if the underlying object is non-stacking
- would be equivalent to ADD if the underlying object is stacking
- just trying to give you guys ONE way to spell it out, with the ability elsewhere to declare stacking vs non stacking
- that way you don't have to be concerned about which one it is when you are writing the modify
- like you don't have to worry about it today with BONUS
- @Andrew[Chair]: Cool. But not set in stone ;) - Mark is available. You able to chat on GTalk?
- Tom[Arch_SB]: that would take a bit
- @Andrew[Chair]: okay.
- Tom[Arch_SB]:
- MODIFYOTHER:SKILL|ALL|Rank|Add|asnumber(Trait)
- MODIFYOTHER:SKILLSIT|ALL|Rank|ADD|asnumber(Trait)
- @Andrew[Chair]: Eh?
- Tom[Arch_SB]: Trait is a NONSTACKINGBONUS
- not a VAR
- Rank is a (local) VAR
- presumably
- need to convert Trait to a VAR
- which is actually a NUMBER
- hence asnumber(Trait)
- basically strips off the fact that it's non-stacking in this case
- and just returns the value
- @Andrew[Chair]: Gotcha.
- Tom[Arch_SB]: ok, this authentication thing isn't going to happen tonight
- haven't had to authenticate an app before and too much reading
- @Andrew[Chair]: no worries, Mark hasn't popped online for me the big issues left for the conversion:
- 1) Apply Luck bonus boost to ALL existing Luck bonuses
- Tom[Arch_SB]: have you seen my latest note to _Exp?
- @Andrew[Chair]: something you mentioned in your last email
- Tom[Arch_SB]: ok, I THINK that answers it
- What I'd like to know is how you guys are doing the bauble thing today
- @Andrew[Chair]: And the AC discussion... Periods were mentioned as legal in the wiki, is that no longer the case?
- Tom[Arch_SB]: if you can't get a bonus from a type of object more than once
- @Andrew[Chair]: Bauble thing caught me off-guard. Today, if you put on three, you'd have a +3 bonus.
- that's a tricky sneaky rule I wasn't aware of till today.
- Tom[Arch_SB]: you are correct, period is legal as per the wiki
- my bad
- @Andrew[Chair]: Oh, Mark just popped on
- Distant_Scholar: Typically, you can't get more than one of the same ability/feat/object anyway. How many objects would this apply to?
- @Andrew[Chair]: Items
- Tom[Arch_SB]: two identical rings for example would cause the issue
- @Andrew[Chair]: Say an equipment without slots or two rings, yes
- Tom[Arch_SB]: So today you'd probably just create a TYPE = localto that object?
- TYPE=FooRingStuff
- on the BONUS?
- Distant_Scholar: Ah. To my eyes, the simplest "fix" would be to make up a new type. (Tom beat me to it.)
- @Andrew[Chair]: pretty much
- if I was made aware of it, I would have done something like that, yes
- sounds like items will need those "types" to manage...
- mjmeans: ok
- hi
- Tom[Arch_SB]: Hi Mark
- @Andrew[Chair]: Yay!
- Hi Mark
- mjmeans: Dont worry about the fate's favored ability. It isn't possible with the current system either.
- Tom[Arch_SB]: do you think my example work work though?
- mjmeans: for fate's favores? no
- Tom[Arch_SB]: why not?
- mjmeans: consider a pc with one ability that gives a luck bonus to intimidate, one equipment that gives a luck bonus to AC and a eqmod that gives a luck bonus to shield.
- There is no way a single modify would identify and add 1 luck to each and every one of those luck bonuses
- Tom[Arch_SB]: oh, I get the question now
- so it's actually based on the TYPE=
- mjmeans: it's an array formuls that is required for that solution
- Tom[Arch_SB]: that you are triggering off of
- mjmeans: yeah. that's why the current JEP can't do it either
- Tom[Arch_SB]: so one question
- if you have a luck bonus to intimidate from item a and a luck bonus to intimidate from item b, each are 1. is the result 3 or 4?
- mjmeans: i think there are more pressing concens than this one trait, so lets work on the regular issues with stacking.
- Tom[Arch_SB]: well, I have a solution that may do both
- so let's spend a few more moments on this
- mjmeans: ok.. so i'll restate the issue with luck then
- with expected results
- PC has Ability_1 that gives a +2 luck bonus to intimidate.
- PC has 1 equipment item that gives a +1 luck bonus to AC.
- PC has a spell that grants +1 luck bonus to AC, Attacks and saves. Got it so far?
- Tom[Arch_SB]: y
- mjmeans: So at this point (without the fate's favored trait) the PC has a total +2 luck bonus to intimidate, +1 luck bonus to AC, attacks and damage. The equipment and the spell both provide a +1 luck bonus to AC but they don't stack. Okay so far?
- Tom[Arch_SB]: y
- mjmeans: So now fate's favor is applied. each of the various luck bonuses go up by 1, but the net effect is the PC has +3 luck bonus to intimidate, and +2 to AC, attacks and damage.
- Tom[Arch_SB]: k
- mjmeans: Now consider that a luck bonus could apply to any skill or conditional skill, of which there are are least 100.
- Tom[Arch_SB]: understand
- my question was an order of ops issue
- but because it doesn't stack it's moot
- because max (1,1)+1 is the same as max (1+1,1+1)
- mjmeans: To make fate's favored work, one method is to .MOD each existing item or ability or spell that is known to have a luck bonus, to add an additional 1 if the PC has fate's favoreed.
- Tom[Arch_SB]: I think that' s a mess
- mjmeans: But that is prone to error.
- Tom[Arch_SB]: we need better
- so let's leave that aside for a moment
- mjmeans: Another method might be is there is a way to query the AC total to "know" if a luck bonus was applied and then apply 1 more if fate's favored. A smaller list to be sure, but still hundreds. And each SKILLSIT would still have to be .MODed since they are never added into any total.
- Tom[Arch_SB]: still bad
- I have better
- mjmeans: right
- Tom[Arch_SB]: So let's talk about the variable system as it's proposed
- right now, there are some default types built into the system
- One of those is NUMBER
- In the variable proposal
- every game mode will have to provide a default value:
- DEFAULTVARIABLEVALUE:NUMBER|0
- We can then define different types of numbers
- think of these as local scopes in a way
- VARTYPEDEF:NUMBER|VAR
- mjmeans: ok
- Tom[Arch_SB]: so any time we create a new VAR, it takes on the characteristics of NUMBER, including the default value of zero
- GLOBAL:VAR|GlobalVariable
- so GlobalVariable has a default value of zero
- mjmeans: ok
- next?
- Tom[Arch_SB]: So NUMBER has the quirk, as you've pointed out, that with the operations we have, such as MAX and ADD, that if we use NUMBER for BONUSES (either as a VAR or as another type of NUMBER)
- ...then we end up with a problem of locality of knowledge
- meaning the BONUS type of Luck was defined in a book on page 2 for example
- and was said to be non-stacking
- mjmeans: right
- Tom[Arch_SB]: then it was used on pages 25-30 in variables thingies
- whatever they were
- so as a thought exercise, let's define a new type, let's call it NONSTACKING
- DEVAULTVARIABLEVALUE:NONSTACKING|0
- VARTYPEDEF:NONSTACKING|NSBONUS
- LOCAL:ALL|NSBONUS|Luck
- every object is given a local variable (type is NSBONUS/NONSTACKING) called Luck'
- mjmeans: So all items get a Local Luck variable?
- Tom[Arch_SB]: yes
- defaulting of course to zero
- mjmeans: so we have armor and shield. each one has a local Luck variable. Got it.
- @Andrew[Chair]: and skills and spells, etc.
- mjmeans: Now let's consider a +1 luck bonus to armor and a +1 luck bonus to shield and the PC has fate's favored.
- Tom[Arch_SB]: hold on
- mjmeans: ok
- Tom[Arch_SB]: wait
- let's not go there yet
- By the way
- This is a bit of brainstorming
- so it may end up more verbose than necessary
- and I may backtrack here and there
- mjmeans: just remember that if the the luck bonus is 0 it gets no benefit from fate's favored.
- "Whenever you are under the effect of a luck bonus of any kind, that bonus increases by 1."
- Tom[Arch_SB]: that's the easy part :D
- mjmeans: do go on
- @Andrew[Chair]: All, I have to head off... be back in 30...
- mjmeans: BCNU
- Tom[Arch_SB]: (thinking)
- this is likely to be too verbose, but it should function
- GLOBAL:NSBONUS|LuckBonus
- mjmeans: or LOCAL:ALL?
- Tom[Arch_SB]: global
- mjmeans: ok
- Tom[Arch_SB]: I need to summarize the local Lucks somewhere
- mjmeans: Too bad there isn't a LOCAL:MODIFY|ALL|GLOBAL.Luck|ADD|Luck
- a pseudo array forumula
- Tom[Arch_SB]: There is: MODIFYOTHER:ALL|ALL|LuckBonus|ADD|Luck
- mjmeans: Where the scope of the left argument is a global and the right argument is a local?
- Tom[Arch_SB]: used once in the global file
- local variables can't match the name of a global var
- the data load would fail
- mjmeans: that's bad
- Tom[Arch_SB]: so the scope is directly known from the name
- why is it bad
- it's enormously confusing to have "Luck" in two places
- these aren't programmers we're talking about that do the data
- mjmeans: So then from a data standpoint, all global variables should follow an obvious naming scheme that will help keep them separate
- Tom[Arch_SB]: That's a data team thing
- I don't think that's necessary
- mjmeans: Are variable type sensitive?
- Tom[Arch_SB]: meaning what?
- mjmeans: i.e. gFoo is a different variable than GFOO
- like java or c++... case sensitive
- Tom[Arch_SB]: not case sensitive
- mjmeans: ick
- Tom[Arch_SB]: it's a side effect of LST load
- the files were always loaded in as all CAPS as part of the load process
- that's the history we have
- mjmeans: ok
- Tom[Arch_SB]: actually my MODIFYOTHER was wrong
- because ADD would make them stack as it wer
- *were
- should be: MODIFYOTHER:ALL|ALL|LuckBonus|APPLY|Luck
- APPLY is new for NONSTACKING and effectively acts as MAX
- mjmeans: So let's get back to the LOCAL:ALL|NSBONUS|Luck... Luck to what? Some items will give Luck to AC, others will give Luck to a skill, others will give differing Luck to multiple skills or saves.
- Tom[Arch_SB]: argh you're right
- mjmeans: Consider AC only. So we use LOCAL:ALL|NSBONUS|LuckBonusToAC. Then on any item, ability or spell that gives a luck bonus to AC, it will SET it's local variable. SOmewhere else that is totaled back to a TotalACLuckBonus variable which is then totaled into the TotalAC variable reported on the OS.
- So now we have NxN bonuses added to every item, spell or ability
- Tom[Arch_SB]: except they are lazily instantiated, so they aren't really there if they aren't used
- mjmeans: Well, N1 x N2... where N1 is the number of types, and N2 is the number of object because each object cannot stack with itself.
- N2 is HUGE
- Tom[Arch_SB]: let's ignore the bauble thing for the moment
- mjmeans: ok
- For the simple case of types, there are about 20 types in Pathfinder.
- Tom[Arch_SB]: one clarification
- you woudlnt' SET the LuckBonusToAC
- you'd APPLY it
- that way if there was a later .MOD that was a different value it would take the max
- in the case of nonstacking
- mjmeans: So at the very least we have LOCAL:ALL|NSBONUS|XBonusToY where X is the type of bonus and Y is AC, or STR, or a skill, etc.
- As an exercise, let's start with a simpler case, but complex enough. The spell Divine Favor "you gain a +1 luck bonus on attack and weapon damage rolls for every three caster levels you have (at least +1, maximum +3)."
- Tom[Arch_SB]: let's step back for a moment
- mjmeans: ok
- Tom[Arch_SB]: I don't like X*Y even as you show it
- If we were doing this in Java or C# or whatever
- mjmeans: I dont like it either, but is there another way?
- Tom[Arch_SB]: how would we accumulate it
- we have some object that has a type and a value
- call that class Bonus
- mjmeans: If this was C# or Java, each spell, item or ability would be an Class in and of itself with shared and local variables
- Tom[Arch_SB]: Luck:1, Luck:2 whatever
- put on the constraint that each spell has no local or global variables
- and design it that way :)
- mjmeans: We'd use a singleton to handle the "not stacking with itself" behaviour
- Tom[Arch_SB]: or assume you are using a visitor pattern to extract data from the list of objects
- that's probably the better description of the scenario
- mjmeans: I've never herd of a "visitor" pattern.
- Tom[Arch_SB]: ok
- let's do this then
- mjmeans: but, ,yes, accessing data from a list of object, which each contain a list of bonuses
- that;s back to an array formula
- Tom[Arch_SB]: so we have a spell an an ability and a ring
- to keep it simple
- mjmeans: ok
- Tom[Arch_SB]: each has a few bonuses
- since we can .MOD items from different LST files
- we have to assume the spell could have Luck for AC:1 and Luck for AC:2
- so the order of ops has to be:
- grab the list for object n
- do a local consolidation (non stacking in this case)
- then add that list to the global list
- then do a global consolidation
- right?
- is the local one necessary?
- mjmeans: yes
- for luck's favor yes, but otherwise, maybe not
- Tom[Arch_SB]: each bonus has 3 pieces of info
- type, whereto apply and a value
- mjmeans: if global consolidation is "per total", and you have the ability ti query "was there a non-0 luck bonus, then add 1" then global consolidation would work for fate's favored.
- Tom[Arch_SB]: k
- mjmeans: but back to the single spell, item and ability
- assuming the bastard fate's favored is not the ability
- Tom[Arch_SB]: MODIFY:ACBonus|APPLY|Luck: 1
- mjmeans: So the item, spell and ability would simply APPLY to a GLOBAL variable that it should apply to.
- Tom[Arch_SB]: ACBonus is a global NSBONUS
- (I've changed NSBONUS a bit from what we were doing before)
- mjmeans: I don't see "Luck:1" as a legal syntax in the current examples on the wiki
- Tom[Arch_SB]: hehe
- It's not
- but the formula system can do some neat stuff :)
- here's the key thing
- when you have something like MODIFY:ACBonus|APPLY|Luck: 1'
- ACBonus is specific
- mjmeans: AC is going to be totaled with each type of bonus separately because it gets reported on the OS as separate totals
- Tom[Arch_SB]: it knows that is an NSBONUS
- let's come back to that
- and that NSBONUS is a NONSTACKINGBONUS
- APPLY is made legal for the type of NONSTACKINGBONUS
- and APPLY is taught to parse it's argument as expecting "TYPE:numeric VALUE"
- mjmeans: once you finish your current train of through, let me know. I have a different question...
- Tom[Arch_SB]: that way the type and value travel together
- mjmeans: okay... good
- Tom[Arch_SB]: and that way we can apply stacking
- mjmeans: a vector number (or complex number)
- Tom[Arch_SB]: effectively
- mjmeans: That's one of my suggestions to Andrew
- Tom[Arch_SB]: the framework for that is already in place
- the system is actually fairly flexible
- I can do (and have sample code that supports):
- VARTYPEDEF:LIST|MyList
- @Andrew[Chair]: Back
- Tom[Arch_SB]:
- MODIFY:MyList|ADD|4
- MODIFY:MyList|ADD|5
- and MyList is now [4, 5]
- that isn't exposed right now
- and I probably won't support that in the first release
- but the power is there if we need it
- (and there are places it will be useful)
- so anyway, we create the type:value
- and put it into AC
- I think I've finished my thought, so what was your question
- mjmeans: So MODIFY:MyList|ADD|Luck:4 MODIFY:MyList|ADD|Shield:5 becomes { [4,Luck], [5,Shield] } ?
- Tom[Arch_SB]: give or take some complexities I've left out
- MyList would need to have the underlying type predefined
- so you can't mix and match a VAR with a NONSTACKING
- for example
- mjmeans: My different question is... why in the world did you decide to use key words for ADD MULTIPLY, whatever rather than just using arythmatic operators... "variable = {equation}"
- Tom[Arch_SB]: speed
- mjmeans: x+=1 for ADD
- Tom[Arch_SB]: launching a formula system to interpret value()+4 is about 10,000 times more expensive than knowing I need to add 1
- mjmeans: y = m*x+b normal formula
- precompiling +=1 to static is simple and only needs to be done once
- Tom[Arch_SB]: it is conceptually simple
- it takes a lot of code to do that though
- mjmeans: In fact the assembly language INC and DEC ops exist because they are in fact much faster than ADD x,1
- But compilers will always identify statics and optimize them for you.
- Tom[Arch_SB]: but these aren't in code
- they are in files we load
- mjmeans: So you can code ADD x,1 and the compiler will automatically replace that with INC x.
- Tom[Arch_SB]: and we aren't doing a compile of them in the java sense
- walk through the process
- we have an LST file
- mjmeans: So it's beyond the scope of the formula parser to PCode the formulas, then?
- Tom[Arch_SB]: it has MODIFY:Foo|SOLVE|value()+1
- When this project was started, I submitted code to the project that took a formula and *literally* compiled it into bytecode
- that would have made this pretty moot as then the JIT compiler could do whatever it needed to do
- that was deemed too complex and the decision was made to leave the formula in a tree format and solve from there for easier debugging and understanding by new developers
- mjmeans: ok
- well each formula is currently stored in a string somewhere. right?
- Tom[Arch_SB]: no
- when you have something like value()+1 it's turned into a parse tree
- there is a + object with 2 children
- value() and 1
- value is actually a formula object with 2 children
- sorry value() is a formula object with 2 children
- value (a formula name) and an argument child that has zero children
- Distant_Scholar: Sorry to interrupt, but I have to go for today. I'll want to get a transcript later; this is interesting stuff. G'night.
- Tom[Arch_SB]: night
- I have to quit in about 10 anyway
- that make sense Mark?
- @Andrew[Chair]: I will log it, minus the chit chat part.... ;)
- mjmeans: what are the two children of value() nothing is specified in the aparens?
- Tom[Arch_SB]: yes, the function is split into the function name and a node representing the parens that has the arguments (that would be in the parens in some cases) as children
- that allows us to just look at the function name node to look up the code that runs that function
- and hand it the array of children
- in the case of if(a>4,5,b)
- mjmeans: so parent node is "function" and two children are "function" and "parameterlist"?
- Tom[Arch_SB]: the two children would be "if" and "()" and the children of "()" would be ">", "5", and "b", and the children of ">" would be "a" and "4"
- mjmeans: sorry, lag.. .didn't mean you if example, your previous example where you said function() had two children
- So function() becomes parent "Formula" with children "function" and "parameterlist" ?
- Tom[Arch_SB]: so there is a node that represents the total "value()" [I forget what this node is actually called - function perhaps?]... it has children of "value" [the type is a string, but is interpreted as a function name since it's the child of the node type above that I can't remember] and "()" [an otherwise empty node that is interpreted as arguments since it's part of a function].
- so yes, basically you are correct in your last statement
- have you ever used lex or yacc?
- mjmeans: So let me try to describe how I'm seeing this, if this is right... MODIFY:Foo|SOLVE|if(a>4,5,b) -> {Foo, SOLVE, {function {if, {a, >, b}, 5, b}}}
- Tom[Arch_SB]: not quite
- When modify is struck by the LST parser, it is decomposed
- It knows Foo is to be modified, and it validates that Foo is legal in that context (if Foo is local to equipment and in a spell, expect an error)
- it then looks at the second arg for the modification type in this case SOLVE
- that is looked up against the type of Foo, in this case NUMBER
- the SOLVE code in Java is then passed "if(a>4,5,b)" as a String
- then the String passed into SOLVE is broken up into the tree as described
- if you hit ADD instead of SOLVE, it knows the argument must only be a decimal number (can't be a formula) so it can just call Double.valueOf(inputString)
- and store the double for direct addition later on
- rather than needing a tree
- that help?
- mjmeans: So you would never MODIFY:Foo|ADD|if(a>b,4,5)
- Tom[Arch_SB]: that would cause an LST load error
- mjmeans: because rith righ operand is a formula
- Tom[Arch_SB]: correct
- and ADD requires something that is effectively interpret-able as a Double
- mjmeans: And in the case MODIFY:Foo|SOLVE|Foo+5
- Tom[Arch_SB]: "Foo+5" is passed to the parser, which generates a tree
- mjmeans: the LST load does not see that as equivalent to ADD 5?
- Tom[Arch_SB]: and the tree is interpreted at runtime to calculate
- they are mathematically equivalent
- but the SOLVE always triggers a tree
- optimizing that call to detect equivalents is more code to write, maintain, test
- mjmeans: Okay, so LST load hass areas where loading optimization can be applied behind the scenes, but that's not relevant at this early stage.
- Tom[Arch_SB]: it could be improved, certainly, at the cost of time
- I have not tried to do that optimization since I want to get the basics running to get out of the other issues we have
- mjmeans: So back to nonstacking types... Do we have a xolution that is not X*Y variable names?
- Tom[Arch_SB]: yes, remember the type:value setup
- mjmeans: Using the concept Luck:1 (or whatever?
- Tom[Arch_SB]: but I actually need to run
- mjmeans: okay. greate chat
- Tom[Arch_SB]: so we can pick this up later
- mjmeans: yes
- @Andrew[Chair]: Later Tom.
- Tom[Arch_SB]: yes, thanks, I appreciate someone poking at this to make it better
- mjmeans: BCNU
- @Andrew[Chair]: Did you get all your major questions answered? I briefly skimmed the stuff I missed
- mjmeans: it's still alittle foggy because the concept has talked about where we can use Luck:1 as a vector (or complex) number is not desribed in the docs yet.
- @Andrew[Chair]: Yes, since he's brainstorming a lot of it.
- mjmeans: It still doesn't address the issue of an item not stacking with other instances of itself. One question he has was, does the existing DATA support that. And I dont know. Should be easy ehough to test though
- @Andrew[Chair]: No, Bauble +1 and Bauble +1 would give +2
- mjmeans: That's a problem
- @Andrew[Chair]: untyped bonuses stack, and the data/system doesn't equate the non-stack of same source.
- mjmeans: But the current DATA *could* support it by always adding |TYPE:itemname
- @Andrew[Chair]: The work around is to place a unique type on those items. yes