Trying to understand syntax

I am trying to document “Powers” for GURPS (the RPG system). A Power has a name (the tiddler title), some descriptive text, an initial cost (which is stored in the “initial_cost” field on the tiddler, and a list of modifiers (also tiddlers).

I was trying to set up the tiddler like this:

Description of Spell (just some text that I can edit later)<br>
<$set name="mods" value="
[[Costs Fatigue 1]] 
[[Limited Use: 1/day]]
">
<br>Modifiers:<br>
<$list variable="mod" filter="<<mods>>">
<$link>{{<<mod>>!!title}}</$link> {{<<mod>>!!cost}}<br>
</$list>
<$vars sum=[<<mods>>!!cost]sum[]]>
<<sum>>
</$vars>
</$set>

Where “Costs Fatigue 1” and “Limited Use: 1/day” were the names of other tiddlers (which have a “cost” field).

But of course, it is completely wrong. It seems that the “mods” variable is being treated as a single string. How can I make this a list, but one that is identified inside of this tiddler… and not from an external source.
I am afraid I am so lost, I don’t really know how to ask the question.
Any help would be greatly appreciated.

This is wrong because <<mods>> is in strings, inside filters you only use single braces, and because you need to parse your string with a filter operator. For a filter operator, either the subfilter or enlist operator would work.

So that changes the list widget to:

<$list variable="mod" filter="[enlist<mods>]">

Down below you have:

{{<<mod>>!!title}}

Unfortunately, this doesn’t work. You can’t “glue” a variable into a transclusion that way. Actually, since you just want to present the name, all you need is :

<<mod>>

For cost though, the preferred approach is to use the triple bracket evaluator.

{{{[<mod>get[cost]]}}}

Putting it altogether, with some other changes which you can study, we get:

<$set name="mods" value="
[[Costs Fatigue 1]] [[Limited Use: 1/day]]
">
<$list variable="mod" filter="[enlist<mods>]">
<$link to=<<mod>>><<mod>> </$link>
<$text text={{{[<mod>get[cost]]}}} /><br>
</$list>
{{{ [enlist<mods>get[cost]sum[]] }}}
</$set>

HTH. It’s a little different than other systems you may have encountered. But after awhile it will seem natural.

Fantastic! Thank you… the syntax (and concepts) are still a bit hard to follow (and I am a Java/JS dev ! :pensive:)

Now, given that I have a field named “initial-cost”, how can I evaluate this equation:

initial-cost * (( 100 + “sum of modifier costs” ) / 100) rounded down.

I can print the initial cost with: {{!!initial-cost}}
And your code calculates the “sum of the modifier costs”: {{{ [enlist<mods>get[cost]sum[]] }}}

I am afraid to try myself. When I tried working my example previously, I caused a Javascript error and had to trash the wiki.

Give this a try:
{{{ [enlist<mods>get[cost]sum[]add[100]divide[100]multiply{!!initial-cost}trunc[]] }}}

-e

1 Like

Wow, again I am amazed. Yes, that works! The only (slight) issue, is that the value is highlighted as if it were a URL. The same goes for {{{ [enlist<mods>get[cost]sum[]] }}}.

This:

Desc<br>
<$set name="mods" value="
[[Costs Fatigue 1]] [[Limited Use: 1/day]]
">
Initial cost: {{!!initial-cost}}<br>
Modifiers:<br>
<$list variable="mod" filter="[enlist<mods>]">
<$link to=<<mod>>><<mod>> </$link>
<$text text={{{[<mod>get[cost]]}}} /><br>
</$list>

[ {{{ [enlist<mods>get[cost]sum[]] }}}% ]

{{{ [enlist<mods>get[cost]sum[]add[100]divide[100]multiply{!!initial-cost}trunc[]] }}}
</$set>

Produces this:

Desc
Initial cost: 50
Modifiers:
Costs Fatigue 1 -10
Limited Use: 1/day -40
[ -50% ] 25

Use the <$text> widget to convert the filter result into plain text.

Thus:

[ <$text text={{{ [enlist<mods>get[cost]sum[]] }}}/>% ]

<$text text={{{ [enlist<mods>get[cost]sum[]add[100]divide[100]multiply{!!initial-cost}trunc[]] }}}/>

Perfect.

Ok, one last request, and then my life will be complete… is there a way to set a field on the current tiddler equal to the result of the evaluation? action-setfield doesn’t seem to be what I am looking for and setFieldCommand seems downright dangerous.

Given that the output looks like:
Desc

Initial cost: 50
Modifiers:
Costs Fatigue 1 -10%
Limited Use: 1/day -40%
[ -50% ] 25

I would like to set a field on that tiddler called “final-cost” to be 25.

$action-setfield IS what you want. However, you need to have a user interaction to trigger it. For example, using a $button widget, you would write:

<$button>
   save final-cost
   <$action-setfield final-cost={{{ [enlist<mods>get[cost]sum[]add[100]divide[100]multiply{!!initial-cost}trunc[]] }}}/>
</$button>

Darn… is there no way to make that happen automatically when the tiddler is saved? So far, the only thing I can figure out would be to implement my own “Edit Tiddler” button that includes an “inputActions” function to constantly set the field value.

I couldn’t find a “save tiddler” function… otherwise I would add an “Update & Save” button at the bottom of the spell template and the user can press that, instead of the “Checkmark” (Confirm changes to this tiddler).

Do you actually need the final value saved in the tiddler? You can have it calculated and displayed on the fly without having it saved in a tiddler field.

I want to be able to filter lists of powers based on their final-cost, so I assume I need it stored in a field.

It would be nice to be able to display list of powers that cost <=10, 11-20, 21-30, etc.

1 Like

@Chris_Normand

Put your JS head on… and a spreadsheet hat on top. Would you expect all the calcs in your spreadsheet to be stored? Where?

You’re storing the data – anywhere you want the same result, simply transclude the formula (or repeat it).

Or put it in a macro.

Another approach to store a calculated value in a tiddler is make use on a trigger already used in your work flow. Foe example you could use the close tiddler button as the trigger etc…

It all depends on your workflow, However if you are creating a new tiddler you can store the input values in temp fields and when creating the tiddler do the calculation and set the “result” field.

Calculating on the fly when you need it, is in many ways the best when the input values may change over time.

My issue is this… in another tiddler, I want to create a list of lists.

One of the lists would be Powers that have a final-cost between 0-10, 11-20, 21-30, etc. And I thought that would be much simplier if I could just reference the final-cost field of each tiddler.

I tried this:
{{{[!has[draft.of]tag[Spell]filter[field[final-cost]compare:integer:lteq[10]]sort[title]]}}}

But again, I don’t have the syntax correct (it is reporting “Missing [ in filter expression”).

@TW_Tones, I was thinking along those lines… somehow trap the “close” event and save the calculated value then… but of course, I have NO IDEA how to go about doing that. So I implemented the “Save” button… and I will manually click it when the field needs to be updated.

BTW, in case other new users follow this thread (and hopefully learn something from it), here is the Wiki that I am working on: Spells Tiddlywiki — "Magic as Powers"

Yes this filter is the wrong syntax

eg what is filter[field[ or change lteq[10]] to lteq[10]

I think you may need to try and restate what you are wanting to do, not how, or with what you already have.

I have a hunch you need to make use of the map: filter prefix to calculate the value for each tiddlers where needed rather than trying to make use of other existing lists.

The high level design is that I want to create a bunch of Spells (Powers), whose final cost is calculated from a starting cost, and a set of modifiers. Different variations on the Spell will exist, using the same starting cost, but have a different set of modifiers.

From the wonderful help given today, I have have been able to create an example spell that I can clone and edit to create the different Spells.

For example:
Fireball v1: 3d6 burn damage, initial cost: 15, final-cost: 15
Fireball v2: 3d6 burn damage, initial cost: 15, modifiers: Cost Fatigue 1 (-10%), final-cost: 13
Fireball v3: 3d6 burn damage, initial cost: 15, modifiers: Cost Fatigue 1 (-10%) & Limited Use: 1/day (-140%), final-cost: 7

So I have 3 variations on a Spell, each with slightly different limitations (as defined by their modifiers), and each with a different final-cost.

I would then like to be able to list spells in various ways. Some examples:

All spells, sorted alphbetically
All spells, sorted by final-cost, then sorted alphabetically
Any spell whose final-cost is between 0-10, then sorted alphabetically
Any spell whose final-cost is between 11-20, then sorted alphabetically
Any spell whose final-cost is between 21-30, then sorted alphabetically

When you use the filter operator you can’t insert the filter expression directly inside, you need use it from macro or use the filter prefix, as @TW_Tones said. See https://tiddlywiki.com/#filter%20Operator where there is a example similar to your case, and a better explanation how the filter operator works.

Thank you, yes, I saw the examples, and didn’t know the filter MUST use a macro. Once I duplicated that, I have been able to create two lists following that format:

Spells (0-10):

<$vars lt10="[{!!final-cost}compare:integer:lteq[10]]">
<$list filter="[!has[draft.of]tag[Spell]filter<lt10>sort[title]]">
<$link to=<<currentTiddler>>><<currentTiddler>> </$link> [{{!!final-cost}}] <br>
</$list>
</$vars>

Which displays:
Fireball V3 [8]

Spells (11-20)

<$vars lt20="[{!!final-cost}compare:integer:lteq[20]]" gt10="[{!!final-cost}compare:integer:gt[10]]">
<$list filter="[!has[draft.of]tag[Spell]filter<lt20>filter<gt10>sort[title]]">
<$link to=<<currentTiddler>>><<currentTiddler>> </$link> [{{!!final-cost}}]<br>
</$list>
</$vars>

Which displays:
Fireball V1 [15]
Fireball V2 [14]

So again, thank you all for your help. I am STILL a bit shaky on the syntax, but I have enough examples that I can start building the data.

Just a detail, but good to know:
These things…

…can be simplified into…

(yes, that last one is correct because it by default refers to current tid)