• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Hero Lab Scripting 401: Bootstrap Conditions

Mathias

Moderator
Staff member
This article is part of a collection of editor and scripting articles: http://forums.wolflair.com/showthread.php?t=21688

Bootstrap conditions are used when you want to add a certain thing to the hero, but not all the time - you want to add it only while certain circumstances apply.

When making a bootstrap conditional, first, test this ability without the condition - make sure you've got everything working, and make sure it's adding the bootstrap all the time, and that the bootstrapped thing or things are all showing up correctly.

In the editor, press the "Bootstraps" button at the top right - find the bootstrap you want to make conditional, and press the "Condition..." button.

Like scripts, bootstrap conditions have a phase and priority. So your first step is to look at the conditions that you want to have satisfied - what phase and priority will they be satisfied by? You need your bootstrap condition to come AFTER that. Next, you need to look at the thing you are bootstrapping, that you want to make conditional. Make sure you have "Enable Data File Debugging" turned on in the Develop menu, and then right-click the thing you're bootstrapping. Choose the "Show Debug Tasks for XXXXX" option from the right-click menu, and look at the list of scripts on that thing. Your bootstrap condition must come BEFORE all of those.

If you're not sure what phase & priority to choose, the default I use in Pathfinder & d20 is First/500, and in Shadowrun & Cortex, I default to Initialize/1000. Looking through the Savage Worlds files, a default hasn't really been established yet, so I'd recommend Initialize/1000.

Next, writing the "Tag Expression" for the bootstrap. First, be aware that this is not normal Hero Lab scripting - you're NOT using field[something].value or tagis[XXXX.YYYY], or the other tests you're used to. The place you're probably familiar with tag expressions from is foreaches - the 'where "something"' that's at the end of foreaches - the "something" part is a tag expression.

About the context of these tag expressions - a bootstrap condition is testing the tags and fields on the pick that is doing the bootstrapping. There's a way to test the tags on the hero (I'll get to that later), but those are the only things you can test using bootstrap conditions - the tags on the thing doing the bootstrapping, the fields on the thing doing the bootstrapping, or the tags on the hero.

Here's the wiki page about tag expressions, if you want to read about them in detail: http://hlkitwiki.wolflair.com/index....ag_Expressions

Here are some common examples - hopefully this will cover 85% of the cases:

Is a tag present?
Code:
[I]Group[/I].[I]Tag[/I]
or
Code:
[I]Group[/I].[I]Tag[/I] <> 0
(If you just use the simpler version, the <> 0 is implied).

Do we have a certain number of a tag:
Code:
count:[I]Group[/I].[I]Tag[/I] >= #
In Pathfinder and d20, this is common - "When we reach level 3, we get this feat" - here's the example for a level 3 Ranger's bonus Endurance feat:
Code:
count:Classes.Ranger >= 3
Is a field's value at least a certain amount (you can also use <, <=, =, >=, >, or <>):
Code:
fieldval:[I]Field[/I] >= #
This one is very common, since a lot of bootstrap conditions will be testing whether or not this ability has been turned on on the In-Play tab. Here's that specific example:
Code:
fieldval:abilActive <> 0
Is a certain tag present on the hero?
Code:
hero#[I]Tag[/I].[I]Group[/I]
or
Code:
hero#[I]Tag[/I].[I]Group[/I] <> 0
This one's also common - for example, for a d20/Pathfinder barbarian, "While we're raging" - here's that example:
Code:
hero#Hero.Raging
These can be combined - here's "This can only be used during a rage, and the user turns this particular ability on using the in-play tab":
Code:
hero#Hero.Raging & (fieldval:abilActive <> 0)
(If you only tested fieldval:abilActive <> 0, what could happen is that the user goes into a rage, and then turns on this ability - then, they turn off their rage, forgetting to also turn off this ability. If you were only testing fieldval:abilActive <> 0, then the conditional bootstrap would continue to be added, even though the character isn't raging anymore).
 
Debugging bootstrap conditions:

Timing - this is the most common error in bootstrap conditions. Think about the information you're looking up in your bootstrap condition - look again at how that information is being generated - make certain that your bootstrap condition is being tested AFTER that information is available.

Next, try switching tabs, and then switching back, or, if it's not showing up on one of the summary panels, print preview, and then immediately cancel. By default, tables in Hero Lab don't always update the list of things that should be in that table - it saves time to not update every single table everytime the user changes something. If you find that this is the case - that by switching tabs so that you can't see the table your bootstrap condition should be showing up on, and then switching back, and you haven't changed anything else about your character, please report that to us as a bug - we can find the table and force it to always update.

Specific to Pathfinder, if you are testing the gIsEquip field: Make certain that you are NOT testing this field's value before First/495. If you do, you will get an odd bug - the bootstrap condition will be the opposite of what it should be until you change something else about your character - what happens is that it will be one calculation pass behind. There's actually some special handling happening behind the scenes for the gIsEquip field because equipping weapons works differently on the desktop and tablet versions of Hero Lab.
 
Last edited:
Mathias,

I love the information you provide in these mini-lectures, they're very helpful. Is there any chance things like this could be part of the hlkitwiki? I really think it would make the authoring kit wiki more useful to have information like these in there for when we're building datafiles from scratch.
 
Something you may wish to mention or talk about is how 99% of the time tags are checked on the "hero". Not the Pick you are on.

So in example:
Code:
hero#Hero.Raging
hero# is redundant as you can leave it off and it works:
Code:
Hero.Raging
as we are always checking the hero. :(
 
The default tag check is the container, which is the hero most of the time. But for things which are inside of a different container (like an item power inside a custom magic item entity), then hero# can be useful to transfer to the hero context.
 
It looks like you may have reversed the order of Group and Tag in the hero# descriptions... the example(hero@Hero.Raging) looks like 'Hero' is a Group while 'Raging' is a tag, but in the initial description you show it as hero#Tag.Group

Or, is Hero a tag and Raging is a group?
 
Mathias,

I love the information you provide in these mini-lectures, they're very helpful. Is there any chance things like this could be part of the hlkitwiki? I really think it would make the authoring kit wiki more useful to have information like these in there for when we're building datafiles from scratch.

Second this, as some one who recently learned the editor by trial and error due to the lack of info, I cannot stress enough how awesome this information is to have, and how much better it would be also posted in a wiki or some location where all this info can be combined into a manual or tutorial.
 
It looks like you may have reversed the order of Group and Tag in the hero# descriptions... the example(hero@Hero.Raging) looks like 'Hero' is a Group while 'Raging' is a tag, but in the initial description you show it as hero#Tag.Group

Or, is Hero a tag and Raging is a group?
In this case "hero" is the container (ie character) and "Hero" is the group and "Rage" is the tag. These "Hero" group was made with the idea that they would always go on the "hero" container. :)

From a new persons perspective I am sure that can be a little confusing.
 
Actually Shadow there is a section where he says it goes hero#Tag.Group and has it backwards, and it's the part where he's talking about hero#Hero.Raging.
 
That is what I get for reading too fast. Yea looks like Mathias was dyslexic for a moment. :) So sorry my bad...

So this part here
Is a certain tag present on the hero?
Code:
hero#[I]Tag[/I].[I]Group[/I]
or
Code:
hero#[I]Tag[/I].[I]Group[/I] <> 0

Should be:
Is a certain tag present on the hero?
Code:
hero#[I]Group[/I].[I]Tag[/I]
or
Code:
hero#[I]Group[/I].[I]Tag[/I] <> 0
 
In this case "hero" is the container (ie character) and "Hero" is the group and "Rage" is the tag. These "Hero" group was made with the idea that they would always go on the "hero" container. :)

From a new persons perspective I am sure that can be a little confusing.

Right - so, I am correct that you mixed up 'Group' and 'Tag' in the descriptions, but got the order correct in the example... ;)
 
Right - so, I am correct that you mixed up 'Group' and 'Tag' in the descriptions, but got the order correct in the example... ;)
Yep you where correct. :D Here is your super special cookie! I have emailed it to you. Oh and don't worry that your antivirus software says its a Trojan virus. You can trust me *really*. :p
 
Heh - my bad for not reading who it was that was writing the response! But thanks for the cookie! It w#s veri tas&%@*$()_... ;-)
 
I must be missing something. You said to find a field:

fieldval:Field >= #

However, that seems to look at fields on the object. If I want to look at a field on the hero, how would I do that? Everything I've guessed at didn't work.
 
I must be missing something. You said to find a field:

fieldval:Field >= #

However, that seems to look at fields on the object. If I want to look at a field on the hero, how would I do that? Everything I've guessed at didn't work.
Simply put you can't. The bootstrap conditions can only access the specific Pick's fields not the hero or any other Pick. You can check for "Tags" on the hero in the bootstrap condition. What you would end up doing is adding logic in the eval-script to test the hero field and push a tag that can be checked. Or set another field value to test.

Honestly though not allot of hero fields are going to be set at the timing that a bootstrap condition needs to run. You are much better off here asking questions about "what" you want to accomplish. Then someone could give advice on the best method.

Also HL does not have objects it has Picks and Things. Just saying its best to pick up the terminology so you have an easier time in the editor. :)
 
Thanks ShadowChemosh for all of your tips and information. You are always helpful. I appreciate the link which helped clear up the difference between Pick and Thing (which I was confused about).
 
Is there any secret to putting a condition on bootstrapping an archetype?

I'm trying to set up an "automatic Gifted Blade" rule option for the Soulknife without directly editing the Soulknife class (so it can be kept in a separate file). Just bootstrapping the Gifted Blade archetype from a Mechanic is simple, but it seems impossible to make a condition that does anything useful (like, say, check if you actually have any Soulknife levels). In that context there's a "Condition phase/priority (...) for bootstrap thing '...' occurs after earliest rule/script (GlobalTest/10500)" error, and I know the Classes.? tags only get added up somewhere early in the First phase.
 
Is there any secret to putting a condition on bootstrapping an archetype?

I'm trying to set up an "automatic Gifted Blade" rule option for the Soulknife without directly editing the Soulknife class (so it can be kept in a separate file). Just bootstrapping the Gifted Blade archetype from a Mechanic is simple, but it seems impossible to make a condition that does anything useful (like, say, check if you actually have any Soulknife levels). In that context there's a "Condition phase/priority (...) for bootstrap thing '...' occurs after earliest rule/script (GlobalTest/10500)" error, and I know the Classes.? tags only get added up somewhere early in the First phase.
You are correct in that this is not an easy one to pull off. I have an archetype that is automatically applied to Unchained Rogue in my personal data set. This applies my groups houserules (Shadowd20) to the unchained rogue.

HERE is a link to the code on GitHub for you too look at.

For all my mechanics I create a "Simple" Thing in the editor which is bootstrapped to my Mechanic. Makes it easier to keep stuff in pieces.

Basically the Simple Thing bootstrap condition is looking for a specific tag (Shadowd20.arS2URog01) to be present on the hero at phase="GlobalTest" priority="10050". Then the Simple Thing has an eval script that runs at phase="GlobalTest" priority="10000". It uses a findchild to attempt to see if the unchained rogue class help Pick is live on the hero. If it is I assign the tag Shadowd20.arS2URog01 to the hero.

In this case you won't be able to use Shadowd20.? tag group as that is a custom group I created for my houserules. I would recommend using a new "Custom.?" tag that you create on the Simple or Mechanic Thing that you will push to the hero and then test that in the bootstrap condition.
 
Back
Top