Board index

PCGen


IT IS ALIVE!!!

Tom's Formula Parser (JEP replacement) - Roadmap 6.6

Discussions between the code and data teams for new features and implementing long term projects

Tom's Formula Parser (JEP replacement) - Roadmap 6.6

Postby LegacyKing » Thu Sep 11, 2014 5:21 am

Another change coming to us in 6.6, a JEP (Java Expression Parser) replacement. http://wiki.pcgen.org/Formula_Parser-JEP_removal, http://wiki.pcgen.org/Formula_Parser_Equip_Vars_Proposal & http://wiki.pcgen.org/Formula_Parser_Equip_Vars_Demo.

This powerful replacement will have two aspects - the JEP replacement is the GLOBAL aspect. The new feature is what we call the LOCAL. Local allows us to do things that were not possible before.

You can have multiple intelligent items and each one with have its own values. Ego, Mental Stats, etc. The same for To Hit bonuses, you can have EnhancementBonus of 1 for Longsword 1, and +4 for Longsword 2 and they will have those values. Local breaks down even further into parts - since a weapon can have two heads, and each head can hold different values, it makes sense to be able to determine the values of each head.

This aspect of the Formula parser will allow us to act upon outstanding bugs calling for Ego's, Hardness rating, Item Hit points.

This tool has a lot of potential to replace a lot of Bonus tags.


Andrew Maitland
PCGen Content SB
- Data Chimp
- Quicksilver Tracker Monkey
User avatar
LegacyKing
Site Admin
 
Posts: 684
Joined: Fri Oct 11, 2013 12:35 pm
Location: California, US

Re: Tom's Formula Parser (JEP replacement) - Roadmap 6.6

Postby LegacyKing » Thu Dec 11, 2014 9:47 am

Hi Tom,

I'm trying to work around some issues that I noticed during review and
patching.

We have BONUS:SKILL|%LIST|x or BONUS:SKILL|SomeSkill|%LIST.

Will the CHOOSER interact with MODIFY, if not then that is something
which needs to included.

Additionally, for a full migration, we will need PRExxx support directly
on the MODIFY tag. Otherwise, the alternative is placing the MODIFY on
some triggered abilities, and we both know that is bound to give us some
performance hit.

Another more interesting question, if we can't reuse the same name, why
are we setting up these:

VARTYPEDEF:NUMBER|VAR

Defines an internal "variable type" of "VAR" that holds numbers.

This is done because we may want something like:

VARTYPEDEF:NUMBER|MOVEMENT

This allows us to have multiple, non-conflicting types of numbers in the
data.

Once the second argument is used in a TYPE entry, then it can be used in
other data, including LOCAL and GLOBAL in the variable file and MODIFY
in other LST files. Items are referred to by the second argument, NOT
the underlying type. So the following would be reasonable data:

VARTYPEDEF:POINT|AREA
AREA|Face (note that since GLOBAL is implied, this is equal to
GLOBAL:AREA|Face)
MODIFY:AREA=Face|SET|10,10

Note that we are asking the data team to put the TYPE into the var file,
but we are currently implying the Face in the code. This is so that we
can "hide" the use of GLOBAL in the test (since that would cause a few
confusing issues)

Note also that MODIFY CANNOT be used with the "=" in the first argument,
so please don't try it! I am echoing long term intent, not immediate
syntax.


So, hypothetically, let's set this up:
I have NUMBER for VAR and MOVEMENT
I have MOVEMENT of "Walk", "Fly", "Climb", "Burrow" and "Swim" all
default to 0.

But that means I can't have a VAR of "Walk", "Fly", "Climb", "Burrow" or
"Swim", or am I missing something, and re-using names is not allowed
between the GLOBAL & LOCAL within the same type, but may be used in
different TYPEs? Much like CATEGORY is a "TYPE" and allows us to re-use
a name.

Which means
MODIFY:MOVEMENT=Walk|SET|30
and
MODIFY:VAR=Walk|SET|30
are actually two different items, and won't interact.

Which if true, leads me to my next question, will the two values be able
to interact?

MODIFY:MOVEMENT=Walk|SOLVE|value()+var(WALK)?

Next something I noticed about the Legal types listed:
ADD
MULTIPLY
SET
SOLVE

MAX and MIN are listed, but the wording makes their usage appear
pointless, only a SOLVE allows calculations, which means MIN or MAX
can't be used as a type.


- During discussion you made a new type
APPLY - which is a Non-Stacking Bonus.

Missing from the list though:
SUBTRACT
DIVIDE

Anyways, just some food for thought. I look forward to your replies.

Cheers,
Andrew


Andrew Maitland
PCGen Content SB
- Data Chimp
- Quicksilver Tracker Monkey
User avatar
LegacyKing
Site Admin
 
Posts: 684
Joined: Fri Oct 11, 2013 12:35 pm
Location: California, US

Re: Tom's Formula Parser (JEP replacement) - Roadmap 6.6

Postby LegacyKing » Thu Dec 11, 2014 9:48 am

1) On %LIST and CHOOSE/MODIFY interaction:


Something is certainly necessary. It may vary in precisely how it works. This is not finalized, since some of it is outside the immediate scope of the formula system and is rather part of the token itself.... And those formats are not final.


For example, showing below that the location may impact the syntax. We will NOT do "%LIST" (as in the literal string) substitution in the actual formula because it can be misinterpreted and I will not let that ambiguity be created in a new system. It also limits the ability to cache and share certain items in memory.

Anyway,

BONUS:SKILL|%LIST|1

has the list owned by the token, so we would use %LIST, and it might be something like:

MODIFYOTHER:SKILL|%LIST|Rank|ADD|1

(
The reason for this is that the code thinks of this much like APPLYTOCHOICE:MODIFY:Rank|ADD|1
... The modify is deterministic but the target is not known...
)

...while...

BONUS:SKILL|SomeSkill|%LIST

has the list owned by the formula, so we would not use %LIST, and it might be something like:

MODIFYOTHER:SKILL|SomeSkill|Rank|SOLVE|value()+choice()

(This is because the application is not conditional, the target is known and it always occurs, but the value of the modify is not known, but with a function to draw from the choice can be entirely solved by the formula system without unique replacement infrastructure.)

2) As far as PRExxx on Modify:

2a) There are many ways to address this type of problem. You are describing the request based on how you currently design data. That may not be the best way to do it going forward, and we should have that discussion.

For example, the PREVAR examples on (at least an earlier draft of) the web page could easily have been done as something like:

MODIFY:Foo|SOLVE|if(var<2,value(),5+bar)

2b) *Literally* using PRExxx is a non-starter. That will pull the new formula system into the current BONUS-PRE-VAR loop, and I *adamantly* refuse to do that.


We should specify WHY we need something - what is the structure / rule we need to implement and address that directly, rather than asking for a specific implementation and thus forcing a certain design. Show me why you need a conditional that can't be done with an IF in a formula (or why it's completely ugly to do it that way)

3) I seem to recall they allow reuse, but I'm not 100% on whether vars get reused and the reuse scope. (It may be that you can have an Area called Foo and a Var called Foo but not a Movement called Foo because Var and Movement are both NUMBER.) That swapped back and forth a few times, and I'd have to check where it currently stands... and that needs to be clear and consistent across the documentation.

4) "Note that we are asking the data team to put the TYPE into the var file, but we are currently implying the Face in the code. This is so that we can "hide" the use of GLOBAL in the test (since that would cause a few confusing issues)"

I don't understand this statement... But not sure if I need to?


5) "Note also that MODIFY CANNOT be used with the "=" in the first argument"


A Variable will prohibit = in the name, otherwise it can't be used in a formula. Given that, the syntax of the first arg is:
<vartype>=<varname>

<vartype>= is optional if the user wants it to be defaulted to "VAR=".

It will use = to separate the vartype from the varname.

If that isn't what you're saying, I may need help on this statement too...

6)
Which means
MODIFY:MOVEMENT=Walk|SET|30
and
MODIFY:VAR=Walk|SET|30
are actually two different items, and won't interact.


6a) If they can be reused (to be validated), then correct. If they can't be reused, that would produce an LST load error. So either way, you will know at load if it works or not.

6b) "Which if true, leads me to my next question, will the two values be able to interact?"


"MODIFY:MOVEMENT=Walk|SOLVE|value()+var(WALK)?"


If they can be reused (to be validated), then give or take, yes.

It's unlikely to be var() for (anti-)compatibility reasons, but there will be some need to do that type of conversion. This is especially true if you have something like:

MODIFY:MyArea|SET|10,15
MODIFY:MyVar|SOLVE|value()+area_x(MyArea)


...not that area_x is necessarily the best formula name for that, but hopefully it gives the general idea...

7) On modifiers (such as ADD, SET)

7a) We should not call them types, as that word is ambiguous

7b) Recognize that a modifier is legal for a given variable type. So a NUMBER will allow MULTIPLY but a POINT will not. So that will have to be correctly documented as a dependency (and lists for each variable type built).

7c) MAX and MIN are VERY useful... and all of the modifiers are doing a calculation "under the covers".... The difference is NOT calculation and we should try to be precise to help avoid confusion of those following along at home. The difference is whether the item following the modifier must be an integer (ADD, MIN, MAX) or whether it can be a formula (SOLVE).

Consider a rule: A First level character starts with a Foo of 1. For a bard, Foo is Bar+3. Foo can never exceed 4.
Global file:
MODIFY:Foo|SET|1
MODIFY:Foo|MAX|4|PRIORITY=2000

On bard:
MODIFY:Foo|SOLVE|Bar+3|PRIORITY=1000


If Bar is 0, what is Foo? (3, based on 0+3)

If Bar is 3, what is Foo? (4, based on the MAX)


8) On Missing SUBTRACT and DIVIDE: There are likely to be a bunch of modifiers added, though I question the need for Subtract since you can just ADD -3 instead of SUBTRACT 3... but YMMV and it's really no skin off my back to do a SUBTRACT. However, if a SUBTRACT is done, ADD and SUBTRACT should require only positive integers so you can't ADD -3, which is not the clearer way to write it... After all, if you introduce SUBTRACT it is not for completeness of function, it is for *clarity*, so allowing an ADD of -3 if a SUBTRACT function is available seems a bit hypocritical from that perspective of clarity... Thus it would not be supported.

TP.
--
Tom Parker


Andrew Maitland
PCGen Content SB
- Data Chimp
- Quicksilver Tracker Monkey
User avatar
LegacyKing
Site Admin
 
Posts: 684
Joined: Fri Oct 11, 2013 12:35 pm
Location: California, US
Top

Re: Tom's Formula Parser (JEP replacement) - Roadmap 6.6

Postby LegacyKing » Thu Dec 11, 2014 9:48 am

Replies in-line, and please, any other data member with questions, feel free to join in.

On 12/10/2014 8:21 PM, Tom Parker thpr@yahoo.com [pcgen_experimental] wrote:
> 1) On %LIST and CHOOSE/MODIFY interaction:
>
>
> Something is certainly necessary. It may vary in precisely how it works. This is not finalized, since some of it is outside the immediate scope of the formula system and is rather part of the token itself.... And those formats are not final.
>
>
> For example, showing below that the location may impact the syntax. We will NOT do "%LIST" (as in the literal string) substitution in the actual formula because it can be misinterpreted and I will not let that ambiguity be created in a new system. It also limits the ability to cache and share certain items in memory.
>
> Anyway,
>
> BONUS:SKILL|%LIST|1
>
> has the list owned by the token, so we would use %LIST, and it might be something like:
>
> MODIFYOTHER:SKILL|%LIST|Rank|ADD|1
>
> (
> The reason for this is that the code thinks of this much like APPLYTOCHOICE:MODIFY:Rank|ADD|1
> ... The modify is deterministic but the target is not known...
> )
>
> ...while...
>
> BONUS:SKILL|SomeSkill|%LIST
>
> has the list owned by the formula, so we would not use %LIST, and it might be something like:
>
> MODIFYOTHER:SKILL|SomeSkill|Rank|SOLVE|value()+choice()
>
> (This is because the application is not conditional, the target is known and it always occurs, but the value of the modify is not known, but with a function to draw from the choice can be entirely solved by the formula system without unique replacement infrastructure.)

As long as we have a clear method to grant the choice in the system, then great. No loss of function then. (Yes, my brain has already come up with several ideas if this wasn't the case, but why make things more convoluted?)

>
> 2) As far as PRExxx on Modify:
>
> 2a) There are many ways to address this type of problem. You are describing the request based on how you currently design data. That may not be the best way to do it going forward, and we should have that discussion.

Definitely need the discussion, which is why I'm bringing it up. :)

>
> For example, the PREVAR examples on (at least an earlier draft of) the web page could easily have been done as something like:
>
> MODIFY:Foo|SOLVE|if(var<2,value(),5+bar)

Okay, that's great for things based upon PREVAR, what about conditional on Ability/Feat/Template/Spell? We have a lot of PRExxx tags, admittedly several will likely be removed as obsolete.

Now, if I understand your position the appending a PRExxx is the cycle you mention, but placing it in an IF statement prevents that problem. If that is the case, then I'd like to move the discussion for PRExxx into how to get the PRExxx tags used inside an IF statement so we have the versatility possible today.


Let's try a few examples - these are the methods we would use today:

A) MODIFY:Foo|ADD|5|xxx with xxx being #1, #2, or #3 (Direct PRExxx on the token, just for example)

#1: PREABILITY:3,CATEGORY=Special Ability,TYPE.SpiffyMonkey

#2: PREALIGN:LG,LN,LE

#3: PREMULT:1,[PREABILITY:3,CATEGORY=Special Ability,TYPE.SpiffyMonkey],[PREALIGN:LG,LN,LE]

B) Using a PRExxx triggered ability to grant the modify:
ABILITY:Modify|AUTOMATIC|Modify Foo +5|PRExxx #1, #2, or #3

Modify Foo +5 <> CATEGORY:Modify <> MODIFY:Foo|ADD|5

C) Using your IF statement means we will be using SOLVE more often, but here is potential examples, (mind I'm gonna use the PRExxx syntax for clarification, just removing the 'PRE', I'm certain we'll clean it up):

MODIFY:Foo|SOLVE|if(ABILITY:3,CATEGORY=Special Ability,TYPE.SpiffyMonkey=>True,5)
MODIFY:Foo|SOLVE|if(ALIGN:LG,LN,LE=>True,5)
MODIFY:Foo|SOLVE|if(MULT:1,[ABILITY:3,CATEGORY=Special Ability,TYPE.SpiffyMonkey],[PREALIGN:LG,LN,LE]=>True,5)

I don't know all the particulars, but if we can reuse the PRExxx inside a conditional statement, or even a boolean statement, then let's do it. I'm curious, will that actually avoid an endless cycle or defer it though? Let's do a common cyclic example:

MODIFY:Foo|SOLVE|if(Foo<1,1)

This gives us a classic cycle issue: Foo is 0, since it's 0, the IF triggers and says less than 1, grant 1. Well, now the value is 1, but the conditional if statement is no longer valid with 1, thus it removes the conditional 1. and we drop to 0 again, repeat indefinitely till system crashes. Or is the system able to catch that sort of cycle and deal with rationally? I'm not certain how moving from the PRExxx attached to an If statement solves the problem.

One of our current bonus cycle issues:
I take ability x, it grants class skill y; however, if I already have class skill y, I get skill bonus z. If I later get class skill y from another source, then I automatically gain skill bonus z.

Today we can't do that cleanly. We don't track CSKILL granting objects, nor count how many times it's granted. One solution I had, but involves a lot of busy work, and I'm not sure if the payback is worth it:

ABILITY:SKILL|AUTOMATIC|Skill|Skill2|Skill3 on each class, and make it MULT:YES, give them a TYPE and now you can track if a CSKILL is from a class, or granted by an outside force. Or simplify it, BONUS:VAR|Skill1,Skill2,Skill3,Skill4|1 - still busy work, but same concept, if I have var x > 1, then it's class granted.


>
> 2b) *Literally* using PRExxx is a non-starter. That will pull the new formula system into the current BONUS-PRE-VAR loop, and I *adamantly* refuse to do that.

I'm open to what solutions you have to offer as an alternative.

>
>
> We should specify WHY we need something - what is the structure / rule we need to implement and address that directly, rather than asking for a specific implementation and thus forcing a certain design. Show me why you need a conditional that can't be done with an IF in a formula (or why it's completely ugly to do it that way)

If x, then y - simple conditional statements are what form the PRExxx. However, this dives into the Required versus must have constantly debate inherent in the d20 system. However, Feats are rife with practically every usage of the PRExxx system. Class features are also littered with PRExxx.

Going through each and every feat/ability/template to peg the rule mechanic seems a bit daunting, but I'm available till January if that's what you want to spend the time discerning.

Suffice it to say at the heart of the matter, we have a Rules based system with exceptions to those same rules.

Here are the three main rule structures: Note this really is PREreq and REQuired.
#1 Required to have - You must meet x standard to gain or acquire the item
#2 Must have to use - You must meet and maintain x standard to gain/benefit from the object
#3 Incremental growth - You gain x when you meet y, you gain b when you meet a, you gain j when you have k.

I think those three encompass the vast system of d20 rules.
#1 - Pretty much Feats fall under both #1 and #2, it's a fine line, but you have to meet the requirement to get the feat, and then you need to maintain to use the feat. PRE & REQ
#2 - Gnome Innate spell, every gnome can cast an innate spell, but they must have a stat of > x, otherwise it's not granted at all - REQ.
#3 - Examples of this are "Sneak Attack", "Monk's Unarmed Damage", "Wild Shape", "Smite", "Lay on Hands", Bardic Music, etc.
Monk's Unarmed Strike and Bardic Music are the best example, since I have items trigger to alter based upon the level of the ability and skill level. REQ

Now, that's general, let's dive into real mechanics:

Holy Avenger - in the hands of a PALADIN, this becomes a +5 Holy weapon, in the hands of anyone else, it is merely a +2 Longsword.

How we handle that today:
BONUS:WEAPON|TOHIT,DAMAGE|2|TYPE=Enhancement
BONUS:WEAPON|TOHIT,DAMAGE|5|TYPE=Enhancement|PRECLASS:1,Paladin=1
The "Holy" can't be evoked from the EQMOD today, so instead we cheat and directly apply the SPROP with an attached PRECLASS:1,Paladin as well. (NOTE: I have a NEWTAG that would allow that EQUIPMOD if implemented)

Here we clearly have a defined mechanic, that simply boils down to "If x, then y, otherwise z"

Now, since we've set this up we have three methods to actually get this result:
classlevel("Paladin") system var pulling the classlevel for paladin
PaladinLVL < var
PRECLASS:1,Paladin=1

MODIFY:WeaponToHit|SOLVE|if(x>0,5,2)
x can take many forms - CLASS.Paladin (Likely since the team is not going to abandon the ClassNameLVL.)

However, let's complicate this, what if the requirement is either a "Paladin", or has Deity "Thor", or has Feat "Avenger"?

Not an uncommon thing in splat books, how would that translate? Would that be in one or more if statements? Or do I need to evaluate them separately and then have yet another var to trigger the +5 vs. +2?

Today, the triple combo of needs only 1 would be handled by:

PREMULT:1,[PRECLASS:1,Paladin=1],[PREDEITY:1,Thor],[PREFEAT:1,Avenger]

Though as pointed out the PRECLASS can be handled as PREVARGTEQ:PaladinLVL,1 or classlevel("Paladin"), or var("CL=Paladin")

What is your idea to handle the problem?

>
> 3) I seem to recall they allow reuse, but I'm not 100% on whether vars get reused and the reuse scope. (It may be that you can have an Area called Foo and a Var called Foo but not a Movement called Foo because Var and Movement are both NUMBER.) That swapped back and forth a few times, and I'd have to check where it currently stands... and that needs to be clear and consistent across the documentation.

Yes, it doesn't make sense to have NUMBER|VAR and NUMBER|MOVEMENT if they can't share a name, might as well just stick with var then. At least I am not seeing any advantage to that prospect and see only confusion if true. If we can re-use the names, then MOVEMENT and VAR make better sense, and having different "groupings" would allow for some very creative coding.

>
> 4) "Note that we are asking the data team to put the TYPE into the var file, but we are currently implying the Face in the code. This is so that we can "hide" the use of GLOBAL in the test (since that would cause a few confusing issues)"
>
> I don't understand this statement... But not sure if I need to?

It's your statement verbatim from the wiki. I just cut and paste the bottom portion for context.

>
>
> 5) "Note also that MODIFY CANNOT be used with the "=" in the first argument"
>
>
> A Variable will prohibit = in the name, otherwise it can't be used in a formula. Given that, the syntax of the first arg is:
> <vartype>=<varname>
>
> <vartype>= is optional if the user wants it to be defaulted to "VAR=".
>
> It will use = to separate the vartype from the varname.
>
> If that isn't what you're saying, I may need help on this statement too...

Again, taken directly from the wiki in your own words. You implied that MODIFY:VAR=Foo|ADD|5 was not valid, but reflected future syntax. Your example was MODIFY:Area=Face|x|y. Which is what sparked my interest in the separate namespace - and re-usability. Sounds like the wiki was incorrect and the vartype=var is a valid use. We can't do VAR=x, which means CL=x is going to need to be dealt with, correct?



>
> 6)
> Which means
> MODIFY:MOVEMENT=Walk|SET|30
> and
> MODIFY:VAR=Walk|SET|30
> are actually two different items, and won't interact.
>
>
> 6a) If they can be reused (to be validated), then correct. If they can't be reused, that would produce an LST load error. So either way, you will know at load if it works or not.

I'm hoping the plan is "they can be reused". As the system designer, I was hoping you would know that up-front, so I can confer with the team and what "TYPEs" we would want. Like "MOVEMENT" "AC" "CLASS", "SKILL", etc. would be nice, but if the VARTYPEs can't re-use names then keeping everything as a var makes the most sense. Which would require that we get very strict on naming standards - i.e. VAR "SKILL.Name".

>
> 6b) "Which if true, leads me to my next question, will the two values be able to interact?"
>
>
> "MODIFY:MOVEMENT=Walk|SOLVE|value()+var(WALK)?"
>
>
> If they can be reused (to be validated), then give or take, yes.
>
> It's unlikely to be var() for (anti-)compatibility reasons, but there will be some need to do that type of conversion. This is especially true if you have something like:
>
> MODIFY:MyArea|SET|10,15
> MODIFY:MyVar|SOLVE|value()+area_x(MyArea)
>
>
> ...not that area_x is necessarily the best formula name for that, but hopefully it gives the general idea...

If they can interact in some fashion, then it's great. If they can't interact, then the system becomes less likely to have divergent types, as you practically have everything interacting with everything.

+1 for re-use, +1 for interactive.

>
> 7) On modifiers (such as ADD, SET)
>
> 7a) We should not call them types, as that word is ambiguous

Uh, I actually didn't, you did, I'm just parroting the terminology you yourself used on the wiki. I'll use "Modifiers" from now on.


>
> 7b) Recognize that a modifier is legal for a given variable type. So a NUMBER will allow MULTIPLY but a POINT will not. So that will have to be correctly documented as a dependency (and lists for each variable type built).

Interesting and a good thing to know. What/who determines what modifiers will be legal?

>
> 7c) MAX and MIN are VERY useful... and all of the modifiers are doing a calculation "under the covers".... The difference is NOT calculation and we should try to be precise to help avoid confusion of those following along at home. The difference is whether the item following the modifier must be an integer (ADD, MIN, MAX) or whether it can be a formula (SOLVE).
>
> Consider a rule: A First level character starts with a Foo of 1. For a bard, Foo is Bar+3. Foo can never exceed 4.
> Global file:
> MODIFY:Foo|SET|1
> MODIFY:Foo|MAX|4|PRIORITY=2000
>
> On bard:
> MODIFY:Foo|SOLVE|Bar+3|PRIORITY=1000
>
>
> If Bar is 0, what is Foo? (3, based on 0+3)
>
> If Bar is 3, what is Foo? (4, based on the MAX)

That makes more sense. I figured the SOLVE was the only thing doing the calculations. Hence the confusion.

>
>
> 8) On Missing SUBTRACT and DIVIDE: There are likely to be a bunch of modifiers added, though I question the need for Subtract since you can just ADD -3 instead of SUBTRACT 3... but YMMV and it's really no skin off my back to do a SUBTRACT. However, if a SUBTRACT is done, ADD and SUBTRACT should require only positive integers so you can't ADD -3, which is not the clearer way to write it... After all, if you introduce SUBTRACT it is not for completeness of function, it is for *clarity*, so allowing an ADD of -3 if a SUBTRACT function is available seems a bit hypocritical from that perspective of clarity... Thus it would not be supported.

I pointed out the missing modifiers strictly on a basis of what was present in a modifier section, if ADD can handle a negative integer, then subtract is redundant and can be omitted. Basically, if something doesn't appear correct, I'm asking to get clarification, and aid those following along at home.

Something which I haven't brought up, and may be a bit advanced, but you hinted to this in the wiki,

We can do ALL, and we can isolate to ONE, but how would we select a "group" of related objects? Examples are Melee Weapons, Martial Weapons, Knowledge skills, etc.

For instance, BONUS:SKILL|TYPE.Knowledge|5
Any skill designated as TYPE:Knowledge would be granted a +5 bonus.

Another example: BONUS:COMBAT|TOHIT.Martial|5

All group 'Martial' is granted a +5 bonus to hit.

The reason I ask, I did see Group=x when discussing weapon capabilities.

Cheers,
Andrew


Andrew Maitland
PCGen Content SB
- Data Chimp
- Quicksilver Tracker Monkey
User avatar
LegacyKing
Site Admin
 
Posts: 684
Joined: Fri Oct 11, 2013 12:35 pm
Location: California, US
Top

Re: Tom's Formula Parser (JEP replacement) - Roadmap 6.6

Postby LegacyKing » Thu Dec 11, 2014 9:49 am

Another example of where we use PRExxx to get desired results and the rules mechanic:

These are both from Pathfinder. Ability Focus and Skill Focus.

Ability Focus - feat

Mechanic - If the creature takes this feat, they choose one ability they posses and add +2 to the DC.

Creature has 'Fear' or 'Poison', 'Whatever This Is', we have it set up like so:

Whatever This Is
<snip>
DESC:DC %1 for this affect.|WhateverThisIsDC
DEFINE:WhateverThisIsDC|0
BONUS:VAR|WhateverThisIsDC|10+CHA+TL|TYPE=Base
BONUS:VAR|WhateverThisIsDC|2|PREFEAT:1,Ability Focus (Whatever This Is)
ABILITY:Ability Focus|AUTOMATIC|Whatever This Is

This model works well, cause we keep our ABILITY FOCUS choices limited to only valid choices - and the bonus to the var is on the granted ability. Clean and simple. As far as I'm concerned, best bang for the buck in terms of performance.

Are we allowed any SPACES in the var name? What about Parenthesis? If spaces are allowed, and even parenthesis, then modifying vars just got much easier.

In the new system we would go with this:

Whatever This Is
<snip>
DESC:DC %1 for this affect|DC.WhateverThisIs
<DEFINE is not used, as this is set up in a central file>
MODIFY:VAR=DC.WhateverThisIs|SOLVE|10+CHA+TL+if(FEAT:Ability Focus (Whatever This Is)>0,2,0)

Now, to be honest, I plan on actually making the 10+CHA+TL or whatever it really is and making that a DC.DefaultCHA so we can save time, and do this:

MODIFY:VAR=DC.WhateverThisIs|SOLVE|DC.DefaultCHA+if(FEAT:Ability Focus (Whatever This Is)>0,2,0)

Now, is that how you expect the IF statement to work?


If spaces are allowed then life gets better:
We don't even need the if statement in ability focus, we can alter to this:

MODIFY:DC.%LIST|ADD|2

'DC.WhateverThisIs' becomes 'DC.Whatever This Is'

Another example where you formula system will be nice:

Skill Focus
Mechanic: Grants a +3 bonus to the selected skill, if the skill has 10 or more ranks, the bonus increases to +6

Would something like this be possible?

Assume instead of VAR, all Skills are using NUMBER|SKILL, and the syntax for the SKILL is

SKILLxBonus.Name of Skill = x=bonus type
SKILLRANK.Name of Skill = Rank
SKILLSTAT.Name of Skill = Key Stat bonus
SKILL.Name = Total

Example:

SKILL.Disable Device
SKILL.Knowledge (Arcana)

MODIFYOTHER:SKILL=SKILLxBonus.%LIST|SOLVE|if(SKILLRANK.%LIST>9,6,3)

Cheers,
Andrew


Andrew Maitland
PCGen Content SB
- Data Chimp
- Quicksilver Tracker Monkey
User avatar
LegacyKing
Site Admin
 
Posts: 684
Joined: Fri Oct 11, 2013 12:35 pm
Location: California, US
Top


Return to Experimental

Who is online

Users browsing this forum: No registered users and 1 guest